diff seobeo/s_web.c @ 260:1f9877b637e9

Add Copilot-powered cyberpunk JRPG chat Integrate the production JRPG chat with Seobeo streaming, Deita persistence, and a Bazel-managed Copilot SDK and LiteLLM inference stack. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <mrjunejune@users.noreply.github.com>
date Wed, 05 Aug 2026 09:19:41 -0700
parents 609d3c6aff4e
children 04fee26ecce0
line wrap: on
line diff
--- a/seobeo/s_web.c	Wed Aug 05 09:19:41 2026 -0700
+++ b/seobeo/s_web.c	Wed Aug 05 09:19:41 2026 -0700
@@ -3,6 +3,17 @@
 #include <time.h>
 
 static char g_folder_path[512] = ".";
+static volatile sig_atomic_t g_server_stopping = 0;
+
+void Seobeo_Web_Server_Stop(void)
+{
+  g_server_stopping = 1;
+}
+
+boolean Seobeo_Web_Server_Is_Stopping(void)
+{
+  return g_server_stopping ? TRUE : FALSE;
+}
 
 static boolean Seobeo_Static_Path_Is_Safe(const char *path)
 {
@@ -155,7 +166,7 @@
   Dowa_Arena *p_request_arena = Dowa_Arena_Create(arena_size);
   if (!p_request_arena) { perror("Dowa_Arena_Create request"); return FALSE; }
 
-  Dowa_Arena *p_response_arena = Dowa_Arena_Create(arena_size);
+  Dowa_Arena *p_response_arena = Dowa_Arena_Create(1024 * 1024 * 16);
   if (!p_response_arena) { perror("Dowa_Arena_Create response"); Dowa_Arena_Free(p_request_arena); return FALSE; }
 
   void *p_response_header = Dowa_Arena_Allocate(p_response_arena, 1024*5); // 5Kb
@@ -270,6 +281,7 @@
   if (stream_handler != NULL)
   {
     stream_handler(p_cli_handle, p_req_map, p_response_arena);
+    should_keep_alive = p_cli_handle->is_sse;
     goto clean_up_arenas;
   }
 
@@ -659,6 +671,7 @@
     Seobeo_ServerMode mode,
     int                thread_count)
 {
+  g_server_stopping = 0;
   if (folder_path)
     strncpy(g_folder_path, folder_path, sizeof(g_folder_path) - 1);
 
@@ -684,7 +697,7 @@
     sa.sa_flags = SA_RESTART;
     sigaction(SIGCHLD, &sa, NULL);
 
-    while (1)
+    while (!Seobeo_Web_Server_Is_Stopping())
     {
       Seobeo_Handle *p_cli_handle =
         Seobeo_Stream_Handle_Server_Accept(p_server_handle);
@@ -704,7 +717,8 @@
     Seobeo_Web_Edge(p_server_handle, thread_count, p_html_cache);
   }
 
-  return -1;
+  Seobeo_Handle_Destroy(p_server_handle);
+  return 0;
 }
 
 /* Router logic */
@@ -766,13 +780,14 @@
   Dowa_Array_Push(g_routes, route);
 }
 
-void Seobeo_Router_Register_SSE(
+void Seobeo_Router_Register_SSE_Method(
+    const char *method,
     const char *path_pattern,
     Seobeo_SSE_Handler handler)
 {
   Seobeo_Route route = {0};
 
-  route.method = strdup("GET");
+  route.method = strdup(method);
   route.path_pattern = strdup(path_pattern);
   route.handler = NULL;
   route.stream_handler = NULL;
@@ -793,6 +808,13 @@
   Dowa_Array_Push(g_routes, route);
 }
 
+void Seobeo_Router_Register_SSE(
+    const char *path_pattern,
+    Seobeo_SSE_Handler handler)
+{
+  Seobeo_Router_Register_SSE_Method("GET", path_pattern, handler);
+}
+
 static boolean match_route_and_extract(
   Seobeo_Route *route,
   const char *request_path,