#include #include #include #include #include #include #include #define STD_HEADERS "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Headers: *\r\nAccess-Control-Allow-Methods: *\r\n" #define HEADERS_FMT STD_HEADERS "Content-Type: %s" // -2 for "%s" -1 for \0 #define HEADERS_FMT_LEN (sizeof(HEADERS_FMT) - 3) void handler_connection(struct mg_connection *nc, int ev, void *p) { if (ev == MG_EV_HTTP_REQUEST) { struct http_message *hm = (struct http_message *) p; LOG_DEBUG("new http %.*s request for %.*s\n", hm->method.len, hm->method.p, hm->uri.len, hm->uri.p); endpoint_t *endpoint = router_find_endpoint(hm->uri.p, hm->uri.len, &hm->method); if(endpoint) { if(endpoint->func) { endpoint_response_t response; static const char content[] = "the server did not create a response"; endpoint_response_text(&response, 500, content, STRLEN(content)); endpoint->func(nc, hm, endpoint->args, &response); char *response_headers = malloc(sizeof(char) * (HEADERS_FMT_LEN + strlen(response.content_type) + 1)); sprintf(response_headers, HEADERS_FMT, response.content_type); mg_send_head(nc, response.status_code, response.content_length, response_headers); mg_printf(nc, "%s", response.content); free(response_headers); if(response.alloced_content) { free((char*)response.content); } for(int i = 0; i < endpoint->args_count; ++i) { if(endpoint->args[i].type == ENDPOINT_ARG_TYPE_STR) { free((char*)endpoint->args[i].value.v_str); } } } else { if(endpoint->method == HTTP_METHOD_OPTIONS) { char options_header[256]; // TODO make more generic sprintf(options_header, STD_HEADERS "Allow: OPTIONS%s%s%s%s", endpoint->options & HTTP_METHOD_GET ? ", GET" : "", endpoint->options & HTTP_METHOD_POST ? ", POST" : "", endpoint->options & HTTP_METHOD_PUT ? ", PUT" : "", endpoint->options & HTTP_METHOD_DELETE ? ", DELETE" : "" ); mg_send_head(nc, 204, 0, options_header); } else { mg_send_head(nc, 501, 0, "Content-Type: text/plain"); } } } else { mg_send_head(nc, 500, 0, "Content-Type: text/plain"); } //mg_printf(c, "%.*s", (int)hm->message.len, hm->message.p); //mg_printf(c, "%.*s", (int)hm->body.len, hm->body.p); } }