This commit is contained in:
SuperNovaa41 2025-01-29 09:22:56 -05:00
parent 9e1a9c7c23
commit 9fbe993f1c
5 changed files with 149 additions and 7 deletions

View File

@ -1,7 +1,7 @@
TARGET=http TARGET=http
CC=gcc CC=gcc
OBJ = main.o tcp.o OBJ = main.o tcp.o http.o
$(TARGET): $(OBJ) $(TARGET): $(OBJ)
mkdir -p ../build mkdir -p ../build
@ -9,7 +9,8 @@ $(TARGET): $(OBJ)
mv $(TARGET) ../build/ mv $(TARGET) ../build/
main.o: include/tcp.h 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 .PHONY: clean
clean: clean:

112
src/http.c Normal file
View File

@ -0,0 +1,112 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#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");
}
*/
}

25
src/include/http.h Normal file
View File

@ -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

View File

@ -14,9 +14,6 @@ int main(void)
setup_socket(&server); setup_socket(&server);
puts("Server setup succesfully!"); puts("Server setup succesfully!");
// start accepting connections here
puts("Accepting new connections..."); puts("Accepting new connections...");
while (true) { while (true) {
client_sock = accept(server.socket, (struct sockaddr*) &(server.server_info), client_sock = accept(server.socket, (struct sockaddr*) &(server.server_info),

View File

@ -6,6 +6,7 @@
#include <poll.h> #include <poll.h>
#include "include/tcp.h" #include "include/tcp.h"
#include "include/http.h"
void setup_socket(server_conn_t* conn) void setup_socket(server_conn_t* conn)
{ {
@ -78,7 +79,7 @@ void recv_message(char** buffer, int socket)
} }
bytes_recv += status; 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'; (*buffer)[bytes_recv] = '\0';
} }
@ -86,12 +87,17 @@ void recv_message(char** buffer, int socket)
void* connection_handler(void* arg) void* connection_handler(void* arg)
{ {
int client_socket = *(int*) arg; int client_socket = *(int*) arg;
http_request request;
char* buffer = NULL; char* buffer = NULL;
recv_message(&buffer, client_socket); recv_message(&buffer, client_socket);
puts(buffer); 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 :) * Handle HTTP request here :)
*/ */
@ -103,7 +109,8 @@ void* connection_handler(void* arg)
// create payload // create payload
// //
// send payload // send payload
free(buffer);
close(client_socket); close(client_socket);
return NULL; return NULL;