From 54d6d06144872bb0f322539deb8fa668bf421cf4 Mon Sep 17 00:00:00 2001 From: Nayan <33187059+GShadow5@users.noreply.github.com> Date: Wed, 7 May 2025 23:15:54 -0400 Subject: [PATCH] add body extraction and clean up and fix http stuff, in particular add auto_fill content metadata from headers --- http_stuff.c | 36 +++++++++++++++++++++--------------- http_stuff.h | 24 ++++++++++++++++++++++++ request_handler.c | 15 +++++++++------ 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/http_stuff.c b/http_stuff.c index 884dda5..9b514b7 100644 --- a/http_stuff.c +++ b/http_stuff.c @@ -26,20 +26,17 @@ http_response* create_http_response() { void free_http_request(http_request* req) { if (req == NULL) { printf("Attempting to free NULL request\n"); - return NULL; + return; } if (req->method != NULL) { - printf("Freeing request method\n"); free(req->method); req->method = NULL; } if (req->url != NULL) { - printf("Freeing request url\n"); free(req->url); req->url = NULL; } if (req->headers != NULL) { - printf("Freeing request headers\n"); for (int i = 0; i < req->num_headers; i++) { free(req->headers[i].key); req->headers[i].key = NULL; @@ -50,16 +47,13 @@ void free_http_request(http_request* req) { req->headers = NULL; } if (req->content_type != NULL) { - printf("Freeing request content type\n"); free(req->content_type); req->content_type = NULL; } if (req->body != NULL) { - printf("Freeing request body\n"); free(req->body); req->body = NULL; } - printf("Freeing request\n"); free(req); req = NULL; } @@ -67,7 +61,7 @@ void free_http_request(http_request* req) { void free_http_response(http_response* res) { if (res == NULL) { printf("Attempting to free NULL response\n"); - return NULL; + return; } if (res->status_line != NULL) { free(res->status_line); @@ -185,14 +179,26 @@ void request_add_header(http_request* req, char* key, char* value) { } void request_info_print(http_request* req) { - printf("Method: %d\n", (int)req->method); - printf("URL: %d\n", (int)req->url); + printf("Method: %p\n", (int*)req->method); + printf("URL: %p\n", (int*)req->url); printf("Headers:\n"); for (int i = 0; i < req->num_headers; i++) { - printf("%d: %d\n", (int)req->headers[i].key, - (int)req->headers[i].value); + printf("%p: %p\n", (int*)req->headers[i].key, + (int*)req->headers[i].value); + } + printf("Content-Type: %p\n", (int*)req->content_type); + printf("Content-Length: %d\n", (int)req->content_length); + printf("Body:\n%p\n", (int*)req->body); +} + +void autofill_content_meta(http_request* req) { + char* cptr = get_header_value_request(req, "Content-Type"); + if (cptr != NULL) { + req->content_type = malloc(strlen(cptr) + 1); + strcpy(req->content_type, cptr); + } + cptr = get_header_value_request(req, "Content-Length"); + if (cptr != NULL) { + req->content_length = atoi(cptr); } - printf("Content-Type: %d\n", (int)req->content_type); - printf("Content-Length: %zu\n", req->content_length); - printf("Body:\n%d\n", (int)req->body); } \ No newline at end of file diff --git a/http_stuff.h b/http_stuff.h index d2c2688..32295c0 100644 --- a/http_stuff.h +++ b/http_stuff.h @@ -173,6 +173,30 @@ void request_add_header_n(http_request* req, char* key, size_t key_length, */ void request_add_header(http_request* req, char* key, char* value); +/** + * Prints out information about an HTTP request, in a way that is not + * particularly human-readable. This function is used for debugging + * purposes. + * + * @param req The request to print information about + */ void request_info_print(http_request* req); +/** + * Automatically fills in the Content-Type and Content-Length fields of the + * given http_request if they are not already set. This function is meant to be + * used when the content type and length are not known when the request is + * created, but are known when the request is processed. + * + * @param req The request whose Content-Type and Content-Length fields are to + * be filled in + * + * @details + * This function will search for the Content-Type and Content-Length headers in + * the request. If it finds either of them, it will copy the value of the header + * into the appropriate field in the request. If it does not find either of + * them, it does nothing. + */ +void autofill_content_meta(http_request* req); + #endif \ No newline at end of file diff --git a/request_handler.c b/request_handler.c index edc21fd..9fda5f3 100644 --- a/request_handler.c +++ b/request_handler.c @@ -19,6 +19,7 @@ void handle_request(char* request, int length, char* response, parse_http_request(request, length, req); print_http_request(req); printf("---------\n"); + request_info_print(req); free_http_request(req); // Create reponse string @@ -93,12 +94,14 @@ void parse_http_request(char* request, int length, struct http_request* req) { header_start = header_end + 2; } - // Fill in content type and length. In order to avoid a double free we copy - // the content type instead of just pointing to the request header - req->content_type = - malloc(strlen(get_header_value_request(req, "Content-Type")) + 1); - strcpy(req->content_type, get_header_value_request(req, "Content-Type")); - req->content_length = atoi(get_header_value_request(req, "Content-Length")); + // Autofill content metadata based on headers + autofill_content_meta(req); + + // Extract body + char* body_start = headers_end + 4; + req->body = (char*)malloc(length - (body_start - request) + 1); + strncpy(req->body, body_start, length - (body_start - request)); + req->body[length - (body_start - request)] = '\0'; return; };