Mercurial
diff seobeo/s_web.c @ 251:117c4d53c9a4
[ui] Add HTML-first Web Component system
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Tue, 04 Aug 2026 09:14:57 -0700 |
| parents | b8aa08503378 |
| children | 609d3c6aff4e |
line wrap: on
line diff
--- a/seobeo/s_web.c Tue Aug 04 06:23:37 2026 -0700 +++ b/seobeo/s_web.c Tue Aug 04 09:14:57 2026 -0700 @@ -4,6 +4,27 @@ static char g_folder_path[512] = "."; +static boolean Seobeo_Static_Path_Is_Safe(const char *path) +{ + if (!path || strchr(path, '\\')) + return FALSE; + const char *segment = path; + while (*segment) + { + while (*segment == '/') + segment++; + const char *end = segment; + while (*end && *end != '/') + end++; + if ((size_t)(end - segment) == 2 && + segment[0] == '.' && + segment[1] == '.') + return FALSE; + segment = end; + } + return TRUE; +} + static char *canonical_request_header(char *header) { if (strcasecmp(header, "content-length") == 0) return "Content-Length"; @@ -241,6 +262,22 @@ // --- Static files fallback for GET (use original large arena logic) --- if (strcmp(method, "GET") == 0) { + if (!Seobeo_Static_Path_Is_Safe(path)) + { + Seobeo_Web_Header_Generate_KeepAlive( + p_response_header, + HTTP_BAD_REQUEST, + "text/plain", + 0, + should_keep_alive); + Seobeo_Handle_Queue( + p_cli_handle, + (const uint8 *)p_response_header, + (uint32)strlen(p_response_header)); + Seobeo_Handle_Flush(p_cli_handle); + goto clean_up_arenas; + } + char *file_path = Dowa_Arena_Allocate(p_response_arena, (size_t)5 * 1024); if (!path || strcmp(path, "/") == 0) @@ -261,27 +298,10 @@ strcpy(file_path, path); } - void *p_file_kv = Dowa_HashMap_Get_Ptr(p_html_cache, file_path); - const char *file_content = NULL; + char *file_content = NULL; size_t body_size = 0; - - if (p_file_kv) - { - Seobeo_Cached_File *cached = ((Seobeo_Cache_Entry*)p_file_kv)->value; - file_content = cached->content; - body_size = cached->size; - } - else - { - file_content = Seobeo_Web_LoadFile(file_path, &body_size); - if (file_content) - { - Seobeo_Cached_File *cached = malloc(sizeof(Seobeo_Cached_File)); - cached->content = (char*)file_content; - cached->size = body_size; - Dowa_HashMap_Push(p_html_cache, file_path, cached); - } - } + (void)p_html_cache; + file_content = Seobeo_Web_LoadFile(file_path, &body_size); if (!file_content) { @@ -336,6 +356,7 @@ (const uint8*)file_content, (uint32)body_size); Seobeo_Handle_Flush(p_cli_handle); + free(file_content); } else { @@ -600,14 +621,34 @@ Seobeo_ServerMode mode, int thread_count) { + return Seobeo_Web_Server_Start_On( + NULL, + folder_path, + port, + mode, + thread_count); +} + +int Seobeo_Web_Server_Start_On( + const char *host, + const char *folder_path, + const char *port, + Seobeo_ServerMode mode, + int thread_count) +{ if (folder_path) strncpy(g_folder_path, folder_path, sizeof(g_folder_path) - 1); Seobeo_Cache_Entry *p_html_cache = NULL; Seobeo_Handle *p_server_handle = - Seobeo_Stream_Handle_Server_Create(NULL, port); - if (p_server_handle->socket < 0) return 1; + Seobeo_Stream_Handle_Server_Create(host, port); + if (!p_server_handle || p_server_handle->socket < 0) + { + if (p_server_handle) + Seobeo_Handle_Destroy(p_server_handle); + return 1; + } Seobeo_Log(SEOBEO_INFO, "Listening on port %s\n", port);