#include "http.h" #include "tcp.h" #include #include #include #include #include #include TcpServer* server = NULL; void interrupt_handler(int a) { (void)a; printf("\nShutting down gracefully...\n"); if (server != NULL) tcp_server_destroy(server); exit(1); } void handle_client_connection(TcpConnection* connection) { uint8_t buffer[8192] = { 0 }; ssize_t recieved = tcp_recieve(connection, buffer, 8192); if (recieved < 0) { printf("error: could not recieve\n"); return; } else if (recieved == 0) { printf("client disconnected\n"); return; } HttpRequestHeader header = parse_http_request_header((char*)buffer, strlen((char*)buffer)); char* path = calloc(header.path_length + 1, sizeof(char)); strncpy(path, (char*)&buffer[header.path_index], header.path_length); if (strncmp(path, "/api", 4) == 0) { // something something api } else { if (strstr(path, "..") != NULL) { uint8_t send_buffer[] = "HTTP/1.1 400 BAD\r\n" "Content-Type: text/html\r\n" "\r\n" "Bad " "request

Fuck you!

\r\n"; ssize_t written = tcp_send(connection, send_buffer, sizeof(send_buffer)); if (written < 0) { printf("error: could not write\n"); return; } } else if (header.path_length == 0 || strncmp(path, "/", header.path_length) == 0) { FILE* file = fopen("../frontend/index.html", "r"); if (file == NULL) { printf("error: could not open file\n"); return; } uint8_t send_buffer[] = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "\r\n"; ssize_t written = tcp_send(connection, send_buffer, sizeof(send_buffer)); if (written < 0) { printf("error: could not write\n"); return; } char char_read; while ((char_read = (char)fgetc(file)) != EOF) { tcp_send(connection, (uint8_t*)&char_read, sizeof(char)); } } else { char rootpath[] = "../frontend"; size_t filepath_size = sizeof(rootpath) + header.path_length + 1; char* filepath = calloc(filepath_size, sizeof(char)); snprintf(filepath, filepath_size, "%s%s", rootpath, path); char* dot = strrchr(path, '.'); char mime_type[20] = { 0 }; char file_flag[3] = { 'r', 0 }; if (dot != NULL && strncmp(dot, ".html", 5) == 0) { snprintf(mime_type, 20, "text/html"); } else if (dot != NULL && strncmp(dot, ".css", 4) == 0) { snprintf(mime_type, 20, "text/css"); } else if (dot != NULL && strncmp(dot, ".js", 3) == 0) { snprintf(mime_type, 20, "text/javascript"); } else if (dot != NULL && strncmp(dot, ".map", 4) == 0) { snprintf(mime_type, 20, "application/json"); } else if (dot != NULL && strncmp(dot, ".ico", 4) == 0) { snprintf(mime_type, 20, "image/x-icon"); } else if (dot != NULL && strncmp(dot, ".jpg", 4) == 0) { snprintf(mime_type, 20, "image/jpeg"); file_flag[1] = 'b'; } else if (dot != NULL && strncmp(dot, ".png", 4) == 0) { snprintf(mime_type, 20, "image/png"); file_flag[1] = 'b'; } else if (dot != NULL && strncmp(dot, ".woff2", 6) == 0) { snprintf(mime_type, 20, "font/woff2"); file_flag[1] = 'b'; } else { printf("error: unknown file type\n"); return; } FILE* file = fopen(filepath, file_flag); if (file == NULL) { printf("error: could not open file\n"); return; } char send_buffer_1[] = "HTTP/1.1 200 OK\r\n" "Content-Type: "; char send_buffer_2[] = "\r\n" "\r\n"; ssize_t written = tcp_send(connection, (uint8_t*)send_buffer_1, strlen(send_buffer_1)); if (written < 0) { printf("error: could not write\n"); return; } written = tcp_send(connection, (uint8_t*)mime_type, strlen(mime_type)); if (written < 0) { printf("error: could not write\n"); return; } written = tcp_send(connection, (uint8_t*)send_buffer_2, strlen(send_buffer_2)); if (written < 0) { printf("error: could not write\n"); return; } int char_read; while ((char_read = fgetc(file)) != EOF) { tcp_send(connection, (uint8_t*)&char_read, sizeof(char)); } free(filepath); fclose(file); } } free(path); } int main(void) { tcp_global_initialize_sockets(); signal(SIGINT, &interrupt_handler); const uint16_t port = 8000; printf("starting server...\n"); server = tcp_server_create("127.0.0.1", port); if (server == NULL) return 1; printf("listening on port %d\n", port); while (true) { printf("waiting for client...\n"); TcpConnection* connection = tcp_server_accept(server); if (connection == NULL) { printf("error: could not accept client\n"); continue; } printf("client connected\n"); handle_client_connection(connection); printf("disconnecting client\n"); tcp_connection_destroy(connection); } tcp_server_destroy(server); return 0; }