# HG changeset patch # User June Park # Date 1759769734 25200 # Node ID 875bb6e10db777b82a2a55457f13dbeff6dadafd # Parent fa2b8af609d9740e90bd50767e2ed54f3bc30d37 [Seobeo] Chaning Function naming to be easily readable. diff -r fa2b8af609d9 -r 875bb6e10db7 cutelient/main.c --- a/cutelient/main.c Mon Oct 06 08:21:34 2025 -0700 +++ b/cutelient/main.c Mon Oct 06 09:55:34 2025 -0700 @@ -8,6 +8,6 @@ { err(EXIT_FAILURE, "Usage: %s URL, PORT, PATH\n", argv[0]); } - Seobeo_Web_ClientGet(argv[1], argv[2], argv[3]); + Seobeo_Web_Client_Get(argv[1], argv[2], argv[3]); return 0; } diff -r fa2b8af609d9 -r 875bb6e10db7 mrjunejune/main.c --- a/mrjunejune/main.c Mon Oct 06 08:21:34 2025 -0700 +++ b/mrjunejune/main.c Mon Oct 06 09:55:34 2025 -0700 @@ -14,5 +14,5 @@ int main(void) { - Seobeo_Web_StartBasicHTTPServer("mrjunejune/pages", "6969", SEOBEO_MODE_EDGE, 2); + Seobeo_Web_Server_Start("mrjunejune/pages", "6969", SEOBEO_MODE_EDGE, 2); } diff -r fa2b8af609d9 -r 875bb6e10db7 seobeo/os/s_linux_edge.c --- a/seobeo/os/s_linux_edge.c Mon Oct 06 08:21:34 2025 -0700 +++ b/seobeo/os/s_linux_edge.c Mon Oct 06 09:55:34 2025 -0700 @@ -14,7 +14,7 @@ if (h == args->srv) { // new connection Seobeo_PHandle cli = - Seobeo_Stream_Handle_Accept(args->srv); + Seobeo_Stream_Handle_Server_Accept(args->srv); if (!cli) continue; struct epoll_event ev = { .events = EPOLLIN, diff -r fa2b8af609d9 -r 875bb6e10db7 seobeo/os/s_macos_edge.c --- a/seobeo/os/s_macos_edge.c Mon Oct 06 08:21:34 2025 -0700 +++ b/seobeo/os/s_macos_edge.c Mon Oct 06 09:55:34 2025 -0700 @@ -13,7 +13,7 @@ Seobeo_PHandle h = evlist[i].udata; if (h == args->srv) { Seobeo_PHandle cli = - Seobeo_Stream_Handle_Accept(args->srv); + Seobeo_Stream_Handle_Server_Accept(args->srv); if (!cli) continue; struct kevent kev = { .ident = cli->socket, diff -r fa2b8af609d9 -r 875bb6e10db7 seobeo/s_linux_network.c --- a/seobeo/s_linux_network.c Mon Oct 06 08:21:34 2025 -0700 +++ b/seobeo/s_linux_network.c Mon Oct 06 09:55:34 2025 -0700 @@ -76,8 +76,8 @@ Seobeo_PHandle p_handle; p_handle = malloc(sizeof(*p_handle)); - struct addrinfo hints, *server_infos, *free_server_info; - int32 socket_fd, yes = 1; // Need this for setsockopt + struct addrinfo hints, *server_infos; + int32 socket_fd; // Need this for setsockopt memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; @@ -100,7 +100,7 @@ if (use_tls) { printf("USE SSL\n\n"); - init_openssl(); + Seobeo_Web_SSL_Init(); p_handle->ssl_ctx = SSL_CTX_new(TLS_client_method()); SSL_CTX_set_default_verify_paths(p_handle->ssl_ctx); @@ -143,7 +143,7 @@ return p_handle; } -Seobeo_PHandle Seobeo_Stream_Handle_Accept(Seobeo_PHandle p_server_handle) +Seobeo_PHandle Seobeo_Stream_Handle_Server_Accept(Seobeo_PHandle p_server_handle) { struct sockaddr_storage addr; socklen_t addrlen = sizeof addr; @@ -153,7 +153,7 @@ &addrlen); inet_ntop( addr.ss_family, - Seobeo_GetIP4OrIP6((struct sockaddr *)&addr), + Seobeo_Get_IP4_Or_IP6((struct sockaddr *)&addr), client_inet_addr, sizeof client_inet_addr); if (client_fd == -1) @@ -200,9 +200,25 @@ if (p_handle->host) free(p_handle->host); if (p_handle->port) free(p_handle->port); + + if (p_handle->ssl) + { + SSL_shutdown(p_handle->ssl); + SSL_free(p_handle->ssl); + p_handle->ssl = NULL; + } + + if (p_handle->ssl_ctx) + { + SSL_CTX_free(p_handle->ssl_ctx); + p_handle->ssl_ctx = NULL; + } + if (p_handle->socket) close(p_handle->socket); + if (p_handle->read_buffer) free(p_handle->read_buffer); if (p_handle->write_buffer) free(p_handle->write_buffer); + if (p_handle->text_copy) free(p_handle->text_copy); if (p_handle->file_name) free(p_handle->file_name); @@ -368,7 +384,7 @@ p_handle->read_buffer_len -= consumed; } -void *Seobeo_GetIP4OrIP6(struct sockaddr *sa) +void *Seobeo_Get_IP4_Or_IP6(struct sockaddr *sa) { if (sa->sa_family == AF_INET) { diff -r fa2b8af609d9 -r 875bb6e10db7 seobeo/s_web.c --- a/seobeo/s_web.c Mon Oct 06 08:21:34 2025 -0700 +++ b/seobeo/s_web.c Mon Oct 06 09:55:34 2025 -0700 @@ -26,7 +26,7 @@ ); } -void Seobeo_Web_GenerateResponseHeader(void *buffer, int status, +void Seobeo_Web_Header_Generate(void *buffer, int status, const char *content_type, const int content_length) { const char *status_text; @@ -71,10 +71,10 @@ if (!p_response_header) { perror("Dowa_Arena_Allocate"); goto clean_up; } p_req_map = Dowa_HashMap_Create(32); - if (Seobeo_Web_ParseClientHeader(p_cli_handle, p_req_map) != 0) + if (Seobeo_Web_Header_Parse(p_cli_handle, p_req_map) != 0) { // malformed request or closed — respond 400 - Seobeo_Web_GenerateResponseHeader(p_response_header, + Seobeo_Web_Header_Generate(p_response_header, HTTP_BAD_REQUEST, "text/plain", 0); Seobeo_Handle_Queue(p_cli_handle, @@ -126,7 +126,7 @@ if (!p_current) { fprintf(stderr, "No value in hashmap key: %s\n\n", dir); - Seobeo_Web_GenerateResponseHeader(p_response_header, + Seobeo_Web_Header_Generate(p_response_header, HTTP_NOT_FOUND, "text/html", 0); Seobeo_Handle_Queue(p_cli_handle, @@ -143,7 +143,7 @@ // Missing so 404 if (!entry) { - Seobeo_Web_GenerateResponseHeader(p_response_header, + Seobeo_Web_Header_Generate(p_response_header, HTTP_NOT_FOUND, "text/html", 0); Seobeo_Handle_Queue(p_cli_handle, @@ -168,7 +168,7 @@ size_t body_size = entry->capacity; printf("key: %s\n\n", entry->key); printf("Body Size: %zu\n\n", body_size); - Seobeo_Web_GenerateResponseHeader(p_response_header, + Seobeo_Web_Header_Generate(p_response_header, HTTP_OK, mime, body_size); @@ -193,7 +193,7 @@ Dowa_HashMap_Free(p_req_map); // TODO: Maybe initilized hashmap within the Arena? } -int Seobeo_Web_ParseClientHeader(Seobeo_PHandle p_handle, Dowa_PHashMap map) +int Seobeo_Web_Header_Parse(Seobeo_PHandle p_handle, Dowa_PHashMap map) { // 1) Fill read_buffer until we see "\r\n\r\n" while (1) @@ -302,7 +302,7 @@ errno = saved_errno; } -int Seobeo_Web_StartBasicHTTPServer( +int Seobeo_Web_Server_Start( const char *folder_path, const char *port, Seobeo_ServerMode mode, @@ -334,7 +334,7 @@ while (1) { Seobeo_PHandle cli = - Seobeo_Stream_Handle_Accept(p_server_handle); + Seobeo_Stream_Handle_Server_Accept(p_server_handle); if (!cli) continue; if (fork() == 0) @@ -356,10 +356,9 @@ return -1; } - -int Seobeo_Web_ClientGet(const char *host, - const char *port, - const char *path) +int Seobeo_Web_Client_Get(const char *host, + const char *port, + const char *path) { Seobeo_PHandle h = Seobeo_Stream_Handle_Client_Create(host, port, TRUE); if (!h || h->socket < 0) @@ -424,3 +423,14 @@ Seobeo_Handle_Destroy(h); return 0; } + +void Seobeo_Web_SSL_Init() +{ + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); +} + +void Seobeo_Web_SSL_Cleanup(void) +{ + EVP_cleanup(); // I don't think these are needed... +} diff -r fa2b8af609d9 -r 875bb6e10db7 seobeo/seobeo.h --- a/seobeo/seobeo.h Mon Oct 06 08:21:34 2025 -0700 +++ b/seobeo/seobeo.h Mon Oct 06 09:55:34 2025 -0700 @@ -1,9 +1,12 @@ #ifndef SEOBEO_SERVER_H #define SEOBEO_SERVER_H -// --- Seobeo --- // -// Library for creating sockets, binding sockets, and listening to a sockets. -// Sending and unpacking bytes of data. +/** + * Seobeo + * ------ + * + * Library for starting TCP, UDP server and serving static file or path. + */ #include #include @@ -22,11 +25,7 @@ #include #include -// SSL -#include -#include - -#include "dowa/dowa.h" +#include "seobeo/seobeo_internal.h" #define INITIAL_BUFFER_CAPACITY 4096 @@ -41,90 +40,33 @@ #define HTTP_NOT_FOUND 404 #define HTTP_INTERNAL_ERROR 500 -typedef enum { - SEOBEO_STREAM_TYPE_SERVER, - SEOBEO_STREAM_TYPE_CLIENT, -} Seobeo_SocketType; - -typedef struct { - uint32 ip; - uint16 port; -} Seobeo_Address, Seobeo_PAddress; - -typedef struct { - int32 socket; - Seobeo_SocketType type; - boolean connected; - - char *host; - char *port; - - SSL_CTX *ssl_ctx; - SSL *ssl; - - uint8 *read_buffer; - uint32 read_buffer_capacity; - uint32 read_buffer_len; // current size - uint32 read_buffer_used; // TODO: Implement this for client - - uint8 *write_buffer; - uint32 write_buffer_capacity; - uint32 write_buffer_len; // current size - - void *file; - void *text_copy; - char *file_name; - - atomic_bool destroyed; -} Sebeo_Handle, *Seobeo_PHandle; - -typedef struct { - Seobeo_PHandle srv; - Dowa_PHashMap cache; - int evfd; // epoll‐fd or kqueue‐fd -} WorkerArgs; - -typedef enum { - SEOBEO_MODE_FORK, - SEOBEO_MODE_EDGE, -} Seobeo_ServerMode; - -// --- Socket, IP related --- // -extern boolean Seobeo_DNS_LookUp(Seobeo_Address *address, char *dns_name); -extern void *Seobeo_GetIP4OrIP6(struct sockaddr *sa); - // --- TCP --- // +// --- Generate a Server Handle. ---// extern Seobeo_PHandle Seobeo_Stream_Handle_Server_Create(const char *host, const char* port); +// --- Generate a Client Handle. ---// extern Seobeo_PHandle Seobeo_Stream_Handle_Client_Create(const char *host, const char* port, boolean use_tls); -extern Seobeo_PHandle Seobeo_Stream_Handle_Accept(Seobeo_PHandle p_server_handle); -extern int Seobeo_Stream_Handle_Read(Seobeo_PHandle p_handle); +// --- Generate a Client Handle from given Server Handle. ---// +extern Seobeo_PHandle Seobeo_Stream_Handle_Server_Accept(Seobeo_PHandle p_server_handle); // --- Web --- // -extern void Seobeo_Web_GenerateResponseHeader(void *buffer, int status, const char *content_type, const int content_length); -extern void Seobeo_Web_HandleClientRequest(Seobeo_PHandle cli, Dowa_PHashMap p_html_cache); -extern int Seobeo_Web_ParseClientHeader(Seobeo_PHandle p_handle, Dowa_PHashMap map); -extern int Seobeo_Web_StartBasicHTTPServer(const char *folder_path, const char *port, Seobeo_ServerMode mode, int thread_count); -extern void *Seobeo_Web_Edge_Worker(void *vargs); // Maybe not web only... -extern void Seobeo_Web_Edge(Seobeo_PHandle p_server_handle, int thread_count, Dowa_PHashMap p_html_cache); -extern int Seobeo_Web_ClientGet(const char *host, const char *port, const char *path); - +/* Generate HTTP 1.1 Header value with given content_types and length. */ +extern void Seobeo_Web_Header_Generate(void *buffer, int status, const char *content_type, const int content_length); +/* Start a Generic HTTP static file server with given folder. It will store folder into memory. */ +extern int Seobeo_Web_Server_Start(const char *folder_path, const char *port, Seobeo_ServerMode mode, int thread_count); +/* Generic HTTP GET Rquest to given host and port with path. It will mimic chrome. */ +extern int Seobeo_Web_Client_Get(const char *host, const char *port, const char *path); // --- Helper functions --- // +/* Destroy handle. It will handle all NULL poointers. */ extern void Seobeo_Handle_Destroy(Seobeo_PHandle p_handle); -extern int Seobeo_Handle_Flush(Seobeo_PHandle p_handle); -extern int Seobeo_Handle_Queue(Seobeo_PHandle p_handle, const uint8_t *data, uint32_t data_size); -extern int Seobeo_Handle_Read(Seobeo_PHandle p_handle); +/* Write to socket from write_buffer in the handle. */ +extern int Seobeo_Handle_Flush(Seobeo_PHandle p_handle); +/* Write to socket with given data source, if the data source is bigger than the write buffer for handle then we just directly write from the data source. */ +extern int Seobeo_Handle_Queue(Seobeo_PHandle p_handle, const uint8_t *data, uint32_t data_size); +/* Read to socket from read_buffer in the handle. */ +extern int Seobeo_Handle_Read(Seobeo_PHandle p_handle); +/* Move to read_buffer to front and we already consumed the given amount in the handle. */ extern void Seobeo_Handle_Consume(Seobeo_PHandle p_handle, uint32 consumed); - -static void init_openssl(void) -{ - SSL_load_error_strings(); - OpenSSL_add_ssl_algorithms(); -} - -static void cleanup_openssl(void) -{ - EVP_cleanup(); -} - +/* Assign IP4 or IP6 to sockaddr. TODO: Maybe create my own struct for this? */ +extern void *Seobeo_Get_IP4_Or_IP6(struct sockaddr *sa); #endif diff -r fa2b8af609d9 -r 875bb6e10db7 seobeo/seobeo_internal.h --- a/seobeo/seobeo_internal.h Mon Oct 06 08:21:34 2025 -0700 +++ b/seobeo/seobeo_internal.h Mon Oct 06 09:55:34 2025 -0700 @@ -0,0 +1,71 @@ +#ifndef SEOBEO_SERVER_INTERNAL_H +#define SEOBEO_SERVER_INTERNAL_H + +// SSL +#include +#include + +#include "dowa/dowa.h" + +typedef enum { + SEOBEO_STREAM_TYPE_SERVER, + SEOBEO_STREAM_TYPE_CLIENT, +} Seobeo_SocketType; + +typedef struct { + int32 socket; + Seobeo_SocketType type; + boolean connected; + + char *host; + char *port; + + SSL_CTX *ssl_ctx; + SSL *ssl; + + uint8 *read_buffer; + uint32 read_buffer_capacity; + uint32 read_buffer_len; // current size + uint32 read_buffer_used; // TODO: Implement this for client + + uint8 *write_buffer; + uint32 write_buffer_capacity; + uint32 write_buffer_len; // current size + + void *file; + void *text_copy; + char *file_name; + + atomic_bool destroyed; +} Sebeo_Handle, *Seobeo_PHandle; + +typedef struct { + Seobeo_PHandle srv; + Dowa_PHashMap cache; + int evfd; // epoll‐fd or kqueue‐fd +} WorkerArgs; + +typedef enum { + SEOBEO_MODE_FORK, + SEOBEO_MODE_EDGE, +} Seobeo_ServerMode; + + + + +// --- Parse Header into Dowa Map ---// +extern int Seobeo_Web_Header_Parse(Seobeo_PHandle p_handle, Dowa_PHashMap map); + +// --- Handle Request --- // +extern void Seobeo_Web_HandleClientRequest(Seobeo_PHandle cli, Dowa_PHashMap p_html_cache); + +// --- SSL --- // +extern void Seobeo_Web_SSL_Init(); +extern void Seobeo_Web_SSL_Cleanup(); // Not used + +// --- Serving using Edge --- // +extern void *Seobeo_Web_Edge_Worker(void *vargs); +extern void Seobeo_Web_Edge(Seobeo_PHandle p_server_handle, int thread_count, Dowa_PHashMap p_html_cache); + +#endif +