add: file handling with 404

This commit is contained in:
Tobias Reisinger 2020-06-03 00:47:49 +02:00
parent 865caa627e
commit 20d38730c9
8 changed files with 157 additions and 83 deletions
handlers

View file

@ -7,12 +7,31 @@
#include <router.h>
#include <handlers.h>
#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"
#define HEADERS_FMT "Content-Type: %s"
// -2 for "%s" -1 for \0
#define HEADERS_FMT_LEN (sizeof(HEADERS_FMT) - 3)
static void
send_response(struct mg_connection *nc, endpoint_response_t *response)
{
if(response->status_code)
{
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);
}
}
}
void
handler_connection(struct mg_connection *nc, int ev, void *p)
{
@ -23,63 +42,70 @@ handler_connection(struct mg_connection *nc, int ev, void *p)
endpoint_t *endpoint = router_find_endpoint(hm->uri.p, hm->uri.len, &hm->method);
if(endpoint)
endpoint_response_t response;
static const char content[] = "the server did not create a response";
endpoint_response_text(&response, 500, content, STRLEN(content));
if(!endpoint)
{
if(endpoint->func)
/* Normalize path - resolve "." and ".." (in-place). */
if (!mg_normalize_uri_path(&hm->uri, &hm->uri)) {
mg_http_send_error(nc, 400, NULL);
return;
}
char *request_file_org = malloc(sizeof(char) * hm->uri.len);
strncpy(request_file_org, hm->uri.p + 1, hm->uri.len);
request_file_org[hm->uri.len - 1] = '\0';
char *request_file = request_file_org;
while(request_file[0] == '/')
{
endpoint_response_t response;
++request_file;
}
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);
}
}
LOG_DEBUG("%s\n", request_file);
int access_result = access(request_file, R_OK);
free(request_file_org);
if(access_result != -1)
{
response.status_code = 0;
mg_serve_http(nc, hm, global_config.http_server_opts);
return;
}
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");
}
endpoint = router_get_not_found_endpoint();
}
}
else
if(!endpoint->func)
{
mg_send_head(nc, 500, 0, "Content-Type: text/plain");
if(endpoint->method == HTTP_METHOD_OPTIONS)
{
char options_header[256]; // TODO make more generic
sprintf(options_header, "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");
}
}
//mg_printf(c, "%.*s", (int)hm->message.len, hm->message.p);
//mg_printf(c, "%.*s", (int)hm->body.len, hm->body.p);
endpoint->func(nc, hm, endpoint->args, &response);
send_response(nc, &response);
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);
}
}
}
}