From 9fbe993f1cfe36c8ca0ce14f22055e942e825526 Mon Sep 17 00:00:00 2001 From: SuperNovaa41 Date: Wed, 29 Jan 2025 09:22:56 -0500 Subject: [PATCH] progress --- src/Makefile | 5 +- src/http.c | 112 +++++++++++++++++++++++++++++++++++++++++++++ src/include/http.h | 25 ++++++++++ src/main.c | 3 -- src/tcp.c | 11 ++++- 5 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 src/http.c create mode 100644 src/include/http.h diff --git a/src/Makefile b/src/Makefile index bff176b..266d5f3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ TARGET=http CC=gcc -OBJ = main.o tcp.o +OBJ = main.o tcp.o http.o $(TARGET): $(OBJ) mkdir -p ../build @@ -9,7 +9,8 @@ $(TARGET): $(OBJ) mv $(TARGET) ../build/ main.o: include/tcp.h -tcp.o: include/tcp.h +tcp.o: include/tcp.h include/http.h +http.o: include/http.h .PHONY: clean clean: diff --git a/src/http.c b/src/http.c new file mode 100644 index 0000000..2d11750 --- /dev/null +++ b/src/http.c @@ -0,0 +1,112 @@ +#include +#include +#include + +#include "include/http.h" + +// what we want to do here is start parsing the http message + +// GET / HTTP/1.1 +// Host: localhost:8080 +// User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0 +// Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +// Accept-Language: en-US,en;q=0.5 +// Accept-Encoding: gzip, deflate, br, zstd +// Connection: keep-alive +// Upgrade-Insecure-Requests: 1 +// Sec-Fetch-Dest: document +// Sec-Fetch-Mode: navigate +// Sec-Fetch-Site: none +// Sec-Fetch-User: ?1 +// Priority: u=0, i + +http_method_t str_to_http_method(char* input) +{ + if (strncmp(input, "GET", 3) == 0) { + return GET; + } else if (strncmp(input, "HEAD", 4) == 0) { + return HEAD; + } + + return UNKNOWN; +} + +const char* http_method_to_str(http_method_t input) +{ + switch (input) { + case GET: + return "GET"; + case HEAD: + return "HEAD"; + case UNKNOWN: + default: + return "UNKNOWN"; + } +} + +void parse_request_line(char** line, http_request* request) +{ + char *tok, *ver; + + + tok = strtok(*line, " "); // this is the method + if (tok == NULL) { + perror("strtok"); + exit(EXIT_FAILURE); + } + request->method = str_to_http_method(tok); + + tok = strtok(NULL, " "); // this is the request URI + if (tok == NULL) { + perror("strtok"); + exit(EXIT_FAILURE); + } + request->request_uri = (char*) malloc(strlen(tok) + 1); + strncpy(request->request_uri, tok, strlen(tok) + 1); + + tok = strtok(NULL, " "); // this is the version + if (tok == NULL) { + perror("strtok"); + exit(EXIT_FAILURE); + } + + ver = strtok(tok, "/"); + if (tok == NULL) { + perror("strtok"); + exit(EXIT_FAILURE); + } + ver = strtok(NULL, "/"); + if (tok == NULL) { + perror("strtok"); + exit(EXIT_FAILURE); + } + + request->version = atof(ver); +} + +void parse_http_request(char** buffer, http_request* request) +{ + // going to be using strtok here to split up the request + + // first lets split each line + char* line; + + // parse the first line + line = strtok(*buffer, "\n"); + if (line == NULL) { + perror("strtok"); + exit(EXIT_FAILURE); + } + + parse_request_line(&line, request); + + + /** + // parse the remaining lines + while (line != NULL) { + // get the rest of them + line = strtok(NULL, "\n"); + + } + */ +} diff --git a/src/include/http.h b/src/include/http.h new file mode 100644 index 0000000..832bbc8 --- /dev/null +++ b/src/include/http.h @@ -0,0 +1,25 @@ +#ifndef HTTP_H +#define HTTP_H + +typedef enum { + GET, + HEAD, + UNKNOWN, +} http_method_t; + +typedef struct { + http_method_t method; + char* request_uri; + double version; + +} http_request; + + +http_method_t str_to_http_method(char* input); +const char* http_method_to_str(http_method_t input); + +void parse_request_line(char** line, http_request* request); + +void parse_http_request(char** buffer, http_request* request); + +#endif diff --git a/src/main.c b/src/main.c index 2a9c6cf..72762d9 100644 --- a/src/main.c +++ b/src/main.c @@ -14,9 +14,6 @@ int main(void) setup_socket(&server); puts("Server setup succesfully!"); - // start accepting connections here - - puts("Accepting new connections..."); while (true) { client_sock = accept(server.socket, (struct sockaddr*) &(server.server_info), diff --git a/src/tcp.c b/src/tcp.c index 693b79d..28b09ec 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -6,6 +6,7 @@ #include #include "include/tcp.h" +#include "include/http.h" void setup_socket(server_conn_t* conn) { @@ -78,7 +79,7 @@ void recv_message(char** buffer, int socket) } bytes_recv += status; - } while (status == BUFFER_INC_LEN); // break when we stop receiving, status == 0 means no more data + } while (status == BUFFER_INC_LEN); // break when we stop receiving, status < BUFFER_INC_LEN means no more data after this last call (*buffer)[bytes_recv] = '\0'; } @@ -86,12 +87,17 @@ void recv_message(char** buffer, int socket) void* connection_handler(void* arg) { int client_socket = *(int*) arg; + http_request request; char* buffer = NULL; recv_message(&buffer, client_socket); puts(buffer); + parse_http_request(&buffer, &request); + + printf("%s %s %1.1f\n", http_method_to_str(request.method), request.request_uri, request.version); + /** * Handle HTTP request here :) */ @@ -103,7 +109,8 @@ void* connection_handler(void* arg) // create payload // // send payload - + + free(buffer); close(client_socket); return NULL;