/* Feel free to use this example code in any way you see fit (Public Domain) */ #include //#ifndef _WIN32 #include #include //#else //#include //#endif #include #include #include #include "web.h" #include "pebblisp.h" #ifdef _MHD_FLAGS_ENUM typedef enum MHD_Result HttpResult; #else typedef int HttpResult; #endif int requestDefinition = -1; int routeCount = 0; struct Route routes[10]; int addRoute(struct Route route) { routes[routeCount] = route; routeCount += 1; return 0; } int methodMatches(const char* method, struct Route* route) { switch (route->type) { case GET: return method[0] == 'G' || method[0] == 'g'; case POST: return method[0] == 'P' || method[0] == 'p'; default: return 0; } } static HttpResult print_out_key(void* queryParamsV, enum MHD_ValueKind kind, const char* key, const char* value) { (void) kind; /* Unused. Silent compiler warning. */ Object* queryParams = queryParamsV; Object pair = startList(stringFromSlice(key, strlen(key))); nf_addToList(&pair, parseEval(value, NULL)); nf_addToList(queryParams, pair); return MHD_YES; } static HttpResult answer_to_connection(void* cls, struct MHD_Connection* connection, const char* url, const char* method, const char* version, const char* upload_data, size_t* upload_data_size, void** con_cls) { char* page = NULL; printf("%s URL: '%s' :: ", method, url); printf("version: %s\n", version); printf("upload_data: %s\n", upload_data); for (int i = 0; i < routeCount; i++) { if (methodMatches(method, &routes[i]) && strcmp(url, routes[i].path) == 0) { Object queryParams = listObject(); MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, print_out_key, &queryParams); Object res = structObject(requestDefinition); res.structObject->fields[0] = queryParams; Object route = cloneObject(routes[i].routeAction); Object result = listEvalLambda(&route, &res, routes[i].env); cleanObject(&res); page = result.string; break; } } if (!page) { printf("no route found!\n"); page = "

404, Dumbass.

"; } (void) cls; /* Unused. Silent compiler warning. */ (void) url; /* Unused. Silent compiler warning. */ (void) method; /* Unused. Silent compiler warning. */ (void) version; /* Unused. Silent compiler warning. */ (void) upload_data; /* Unused. Silent compiler warning. */ (void) upload_data_size; /* Unused. Silent compiler warning. */ (void) con_cls; /* Unused. Silent compiler warning. */ struct MHD_Response* response = MHD_create_response_from_buffer( strlen(page), (void*) page, MHD_RESPMEM_PERSISTENT); HttpResult ret = MHD_queue_response(connection, MHD_HTTP_OK, response); MHD_destroy_response(response); // if (needsFree) { // free(page); // } return ret; } int initialized = 0; void initialize() { if (!initialized) { Object o = parseEval("(struct Request (queryParams))", global()); cleanObject(&o); requestDefinition = getStructIndex(global(), "Request"); } initialized = 1; } int start(int port) { initialize(); struct MHD_Daemon* daemon = MHD_start_daemon( MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD, port, NULL, NULL, &answer_to_connection, NULL, MHD_OPTION_END); if (NULL == daemon) { return 1; } // (void) getchar(); // MHD_stop_daemon(daemon); return 0; }