/* 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" #include "tokens.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') && (method[1] == 'O' || method[1] == 'o'); default: return 0; } } static HttpResult add_query_param(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))); Object parsed; if (isDigit(value[0])) { parsed = parseEval(value, NULL); } else { parsed = stringFromSlice(value, strlen(value)); } nf_addToList(&pair, parsed); 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, add_query_param, &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); 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; }