mirror of
https://github.com/opus-tango/http-server-in-c.git
synced 2026-03-20 03:55:25 +00:00
switched over to logging
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@@ -2,6 +2,8 @@
|
||||
"files.associations": {
|
||||
"string.h": "c",
|
||||
"types.h": "c",
|
||||
"random": "c"
|
||||
"random": "c",
|
||||
"request_handler.h": "c",
|
||||
"response_builder.h": "c"
|
||||
}
|
||||
}
|
||||
30
http_stuff.c
30
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);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -133,28 +112,3 @@ void parse_http_request(char* request, int length, struct http_request* req) {
|
||||
|
||||
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");
|
||||
}
|
||||
@@ -6,8 +6,39 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#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
|
||||
@@ -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) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "http_stuff.h"
|
||||
#include "logging.h"
|
||||
|
||||
typedef enum {
|
||||
HTML,
|
||||
|
||||
Reference in New Issue
Block a user