diff --git a/.vscode/settings.json b/.vscode/settings.json index c11fca3..52dfd2f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,8 @@ "files.associations": { "string.h": "c", "types.h": "c", - "random": "c" + "random": "c", + "request_handler.h": "c", + "response_builder.h": "c" } } \ No newline at end of file diff --git a/http_stuff.c b/http_stuff.c index 81b8181..279f1c0 100644 --- a/http_stuff.c +++ b/http_stuff.c @@ -25,7 +25,7 @@ http_response* create_http_response() { void free_http_request(http_request* req) { if (req == NULL) { - printf("Attempting to free NULL request\n"); + log_message(LOG_INFO, "Attempting to free NULL request"); return; } if (req->method_str != NULL) { @@ -60,7 +60,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"); + log_message(LOG_INFO, "Attempting to free NULL response"); return; } if (res->status_line != NULL) { @@ -84,10 +84,12 @@ void free_http_response(http_response* res) { } void print_http_request(http_request* req) { + log_message(LOG_WARN, "Deprecated function 'print_http_request' called"); if (req == NULL) { - printf("Attempting to print NULL request\n"); + log_message(LOG_INFO, "Attempting to print NULL request"); return; } + printf("Method: %s\n", (req->method_str == NULL) ? "" : req->method_str); printf("URL: %s\n", (req->url == NULL) ? "" : req->url); printf("Headers:\n"); @@ -103,6 +105,7 @@ void print_http_request(http_request* req) { } void print_http_response(http_response* res) { + log_message(LOG_WARN, "Deprecated function 'print_http_response' called"); printf("Status Line: %s\n", (res->status_line == NULL) ? "" : res->status_line); printf("Headers:\n"); @@ -116,6 +119,7 @@ void print_http_response(http_response* res) { } char* response_to_string(http_response* res) { + log_message(LOG_DEBUG, "Converting entire response to string"); // Define lengths int total_length = 0; int len_newline = strlen("\r\n"); @@ -162,6 +166,7 @@ char* response_to_string(http_response* res) { } char* response_headers_to_string(http_response* res) { + log_message(LOG_DEBUG, "Generating response headers string"); // Define lengths int total_length = 0; int len_newline = strlen("\r\n"); @@ -204,18 +209,19 @@ char* response_headers_to_string(http_response* res) { } char* get_header_value_request(http_request* req, char* key) { - // printf("Getting header value for key: %s\n", key); + log_message(LOG_DEBUG, "Getting header value for %s", key); for (int i = 0; i < req->num_headers; i++) { if (strcmp(req->headers[i].key, key) == 0) { return req->headers[i].value; } } - // printf("Header not found\n"); + log_message(LOG_WARN, "Header %s not found\n", key); return NULL; } void request_add_header_n(http_request* req, char* key, size_t key_length, char* value, size_t value_length) { + log_message(LOG_DEBUG, "Adding header %s: %s", key, value); req->num_headers++; req->headers = realloc(req->headers, req->num_headers * sizeof(header_kv)); req->headers[req->num_headers - 1].key = malloc(key_length + 1); @@ -230,20 +236,8 @@ void request_add_header(http_request* req, char* key, char* value) { request_add_header_n(req, key, strlen(key), value, strlen(value)); } -void request_info_print(http_request* req) { - 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("%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) { + log_message(LOG_DEBUG, "Autofilling content metadata"); char* cptr = get_header_value_request(req, "Content-Type"); if (cptr != NULL) { req->content_type = malloc(strlen(cptr) + 1); diff --git a/http_stuff.h b/http_stuff.h index 5a81a73..9956314 100644 --- a/http_stuff.h +++ b/http_stuff.h @@ -6,6 +6,8 @@ #include #include +#include "logging.h" + typedef enum { GET, POST, @@ -111,6 +113,7 @@ void free_http_request(http_request* req); void free_http_response(http_response* res); /** + * DEPRECATED * Prints a formatted version of an http_request struct to stdout. This function * is meant to be used for debugging purposes. * @@ -119,6 +122,7 @@ void free_http_response(http_response* res); void print_http_request(http_request* req); /** + * DEPRECATED * Prints a formatted version of an http_response struct to stdout. This * function is meant to be used for debugging purposes. * diff --git a/request_handler.c b/request_handler.c index 0f84171..b6cc944 100644 --- a/request_handler.c +++ b/request_handler.c @@ -1,12 +1,6 @@ #include "request_handler.h" -void parse_http_request(char* request, int length, struct http_request* req); -void debug_print_request(char* request); - void handle_request(char* request, int length, http_response* response) { - // Terminate request with EOF so strtok stops at end of string - request[length] = EOF; - // Parse request into struct http_request* req = create_http_request(); parse_http_request(request, length, req); @@ -14,7 +8,6 @@ void handle_request(char* request, int length, http_response* response) { // Switch statement to handle different request types switch (req->method) { case GET: - // Build response response_handle_get(req, response); break; @@ -31,20 +24,6 @@ void handle_request(char* request, int length, http_response* response) { break; } - // Create response - - // Create response string - // char* ptr_temp = response; - // char* temp = - // "HTTP/1.1 200 OK\r\nContent-Type: text/html \r\nContent-Length: " - // "0\r\n\r\n\0"; - // strcpy(ptr_temp, temp); - - // printf("Response --------\n"); - // printf("%s\n--------\n", response); - - // *response_length = strlen(response); - free_http_request(req); } @@ -52,7 +31,7 @@ void parse_http_request(char* request, int length, struct http_request* req) { // Get the end of the first line char* request_line_end = strstr(request, "\r\n"); if (request_line_end == NULL) { - printf("Invalid packet (end first line)\n"); + log_message(LOG_ERROR, "Invalid packet (request line), cannot parse"); return; } @@ -60,7 +39,7 @@ void parse_http_request(char* request, int length, struct http_request* req) { char* type_start = request; char* type_end = strstr(type_start, " "); if (type_end == NULL) { - printf("Invalid packet (method)\n"); + log_message(LOG_ERROR, "Invalid packet (method), cannot parse"); return; } char* type = (char*)malloc(type_end - type_start + 1); @@ -75,7 +54,7 @@ void parse_http_request(char* request, int length, struct http_request* req) { } else if (strcmp(type, "DELETE") == 0) { req->method = DELETE; } else { - printf("Invalid packet (method)\n"); + log_message(LOG_ERROR, "Invalid packet (method), cannot parse"); return; } req->method_str = (char*)malloc(type_end - type_start + 1); @@ -86,7 +65,7 @@ void parse_http_request(char* request, int length, struct http_request* req) { char* url_start = type_end + 1; char* url_end = strstr(url_start, " "); if (url_end == NULL) { - printf("Invalid packet (url)\n"); + log_message(LOG_ERROR, "Invalid packet (url), cannot parse"); return; } req->url = (char*)malloc(url_end - url_start + 1); @@ -96,12 +75,12 @@ void parse_http_request(char* request, int length, struct http_request* req) { // Extract headers char* headers_end = strstr(request_line_end + 2, "\r\n\r\n"); if (headers_end == NULL) { - printf("Invalid packet (headers)\n"); + log_message(LOG_ERROR, "Invalid packet (headers), cannot parse"); return; } char* headers_start = request_line_end + 2; if (headers_start == NULL) { - printf("Invalid packet (headers)\n"); + log_message(LOG_ERROR, "Invalid packet (headers), cannot parse"); return; } req->num_headers = 0; @@ -113,7 +92,7 @@ void parse_http_request(char* request, int length, struct http_request* req) { } char* delim = strstr(header_start, ": "); if (delim == NULL) { - printf("Invalid packet (headers)\n"); + log_message(LOG_ERROR, "Invalid packet (headers), cannot parse"); return; } @@ -132,29 +111,4 @@ void parse_http_request(char* request, int length, struct http_request* req) { req->body[length - (body_start - request)] = '\0'; return; -}; - -void debug_print_request(char* request) { - // Copy request - char* request_copy = (char*)malloc(strlen(request) + 1); - strcpy(request_copy, request); - - // Iterate through request and print "\\r\\n" before each \r\n - // and "\\r\\n\\r\\n" before each \r\n\r\n - char* ptr = request_copy; - while (*ptr != '\0') { - if (*ptr == '\r' && *(ptr + 1) == '\n') { - if (*(ptr + 2) == '\r' && *(ptr + 3) == '\n') { - printf("\\r\\n\\r\\n\n"); - ptr += 4; - } else { - printf("\\r\\n\n"); - ptr += 2; - } - } else { - printf("%c", *ptr); - ptr++; - } - } - printf("\n"); -} \ No newline at end of file +}; \ No newline at end of file diff --git a/request_handler.h b/request_handler.h index d667602..1982b2b 100644 --- a/request_handler.h +++ b/request_handler.h @@ -6,8 +6,39 @@ #include #include "http_stuff.h" +#include "logging.h" #include "response_builder.h" +/** + * Handles a given HTTP request and writes the appropriate response into the + * given http_response struct. + * + * @param request The request to handle + * @param length The length of the request + * @param response The response to write to + * + * @details + * This function will parse the given request into an http_request struct using + * parse_http_request, handle the request using one of the response_handle_* + * functions, and then write the response back into the given http_response + * struct. Finally, it will free the http_request struct. + */ void handle_request(char* request, int length, http_response* response); +/** + * Parse a given HTTP request into a struct http_request. + * + * @param request The HTTP request to parse + * @param length The length of the request + * @param req The struct to populate with the parsed request + * + * @return void + * + * @details + * This function will parse the given HTTP request into the req struct. This + * includes extracting the request type, URL, headers, and body. It will also + * autofill the content metadata based on the headers. + */ +void parse_http_request(char* request, int length, struct http_request* req); + #endif \ No newline at end of file diff --git a/response_builder.c b/response_builder.c index fa7c9cd..d7399d7 100644 --- a/response_builder.c +++ b/response_builder.c @@ -1,12 +1,13 @@ #include "response_builder.h" void response_handle_get(http_request* req, http_response* res) { + log_message(LOG_INFO, "GET request %s", req->url); // Extract the path from the request URL char* basepath = "./public"; char* file_path = (char*)malloc(strlen(req->url) + strlen(basepath) + 1); strcpy(file_path, basepath); strcat(file_path, req->url); - printf("%s\n", file_path); + log_message(LOG_INFO, "Path: %s", file_path); // Determine the file type char* ptr = file_path + strlen(file_path) - 1; @@ -31,22 +32,19 @@ void response_handle_get(http_request* req, http_response* res) { void response_handle_post(http_request* req, http_response* res) { // TODO - printf("POST request\n"); - printf("%s\n", req->url); + log_message(LOG_INFO, "POST request %s", req->url); serve_501(res); } void response_handle_delete(http_request* req, http_response* res) { // TODO - printf("DELETE request\n"); - printf("%s\n", req->url); + log_message(LOG_INFO, "DELETE request %s", req->url); serve_501(res); } void response_handle_put(http_request* req, http_response* res) { // TODO - printf("PUT request\n"); - printf("%s\n", req->url); + log_message(LOG_INFO, "PUT request %s", req->url); serve_501(res); } @@ -55,7 +53,7 @@ void response_build_static_file(char* file_path, content_type content_type, // Open the file and verify that the file exists FILE* file = fopen(file_path, "rb"); if (file == NULL) { - printf("fopen failed to find file %s\n", file_path); + log_message(LOG_WARN, "404:fopen failed to find file %s\n", file_path); serve_404(res); return; } @@ -68,13 +66,13 @@ void response_build_static_file(char* file_path, content_type content_type, // Read file into buffer char* file_buffer = (char*)malloc(file_size); if (file_buffer == NULL) { - printf("malloc failed\n"); + log_message(LOG_WARN, "500: malloc for file failed"); serve_500(res); return; } size_t bytes_read = fread(file_buffer, file_size, 1, file); if (bytes_read != 1) { - printf("fread failed\n"); + log_message(LOG_WARN, "500: fread for file failed"); serve_500(res); return; } @@ -154,14 +152,7 @@ void response_build_static_file(char* file_path, content_type content_type, // Set content type string res->content_type = content_type_str; - // Add header for close connection - header_kv* close_connection = (header_kv*)malloc(sizeof(header_kv)); - close_connection->key = (char*)malloc(strlen("Connection") + 1); - close_connection->value = (char*)malloc(strlen("close") + 1); - strcpy(close_connection->key, "Connection"); - strcpy(close_connection->value, "close"); - res->headers = close_connection; - res->num_headers = 1; + log_message(LOG_INFO, "Serving %s\n", file_path); } void serve_404(http_response* res) { diff --git a/response_builder.h b/response_builder.h index c4c33a3..02d42f8 100644 --- a/response_builder.h +++ b/response_builder.h @@ -6,6 +6,7 @@ #include #include "http_stuff.h" +#include "logging.h" typedef enum { HTML,