comparison seobeo/s_web.c @ 72:4532ce6d9eb8

[Seobeo] Added router to the server logic. Few dowa string manipulation logics.
author June Park <parkjune1995@gmail.com>
date Mon, 29 Dec 2025 07:50:07 -0800
parents 75de5903355c
children 35b1abc37969
comparison
equal deleted inserted replaced
71:75de5903355c 72:4532ce6d9eb8
93 Seobeo_Cache_Entry *p_html_cache) 93 Seobeo_Cache_Entry *p_html_cache)
94 { 94 {
95 Dowa_Arena *p_request_arena = Dowa_Arena_Create(1*1024*1024); // 1MB for request parsing 95 Dowa_Arena *p_request_arena = Dowa_Arena_Create(1*1024*1024); // 1MB for request parsing
96 if (!p_request_arena) { perror("Dowa_Arena_Create request"); goto clean_up; } 96 if (!p_request_arena) { perror("Dowa_Arena_Create request"); goto clean_up; }
97 97
98 Dowa_Arena *p_response_arena = Dowa_Arena_Create(1*1024*1024); // 1MB for response 98 Dowa_Arena *p_response_arena = Dowa_Arena_Create(5*1024*1024); // 1MB for response
99 if (!p_response_arena) { perror("Dowa_Arena_Create response"); goto clean_up; } 99 if (!p_response_arena) { perror("Dowa_Arena_Create response"); goto clean_up; }
100 100
101 void *p_response_header = Dowa_Arena_Allocate(p_response_arena, (size_t)1024*5); // 5Kb 101 void *p_response_header = Dowa_Arena_Allocate(p_response_arena, (size_t)1024*5); // 5Kb
102 if (!p_response_header) { perror("Dowa_Arena_Allocate"); goto clean_up; } 102 if (!p_response_header) { perror("Dowa_Arena_Allocate"); goto clean_up; }
103 103
129 (uint32)strlen(p_response_header)); 129 (uint32)strlen(p_response_header));
130 Seobeo_Handle_Flush(p_cli_handle); 130 Seobeo_Handle_Flush(p_cli_handle);
131 goto clean_up; 131 goto clean_up;
132 } 132 }
133 133
134 // --- Handle different HTTP methods --- 134 // Extract path
135 void *p_path_kv = Dowa_HashMap_Get_Ptr(p_req_map, "Path");
136 const char *path = p_path_kv ? ((Seobeo_Request_Entry*)p_path_kv)->value : "/";
137
138 // --- Try to match API route first ---
139 Seobeo_Route_Handler handler = Seobeo_Router_Find_Handler(method, path, &p_req_map, p_request_arena);
140
141 if (handler != NULL)
142 {
143 // Call the API handler
144 Seobeo_Request_Entry *p_response_map = handler(p_req_map, p_response_arena);
145
146 // Send the response
147 Seobeo_Router_Send_Response(p_cli_handle, p_response_map, p_response_arena);
148 goto clean_up;
149 }
150
151 // --- Handle different HTTP methods (static files fallback) ---
135 if (strcmp(method, "GET") == 0) 152 if (strcmp(method, "GET") == 0)
136 { 153 {
137 void *p_kv = Dowa_HashMap_Get_Ptr(p_req_map, "Path"); 154 void *p_kv = Dowa_HashMap_Get_Ptr(p_req_map, "Path");
138 const char *path = p_kv ? ((Seobeo_Request_Entry*)p_kv)->value : NULL; 155 const char *path = p_kv ? ((Seobeo_Request_Entry*)p_kv)->value : NULL;
139 char *file_path = Dowa_Arena_Allocate(p_response_arena, (size_t)5 * 1024); // 5Kb only for path 156 char *file_path = Dowa_Arena_Allocate(p_response_arena, (size_t)5 * 1024); // 5Kb only for path
151 snprintf(file_path, 512, "%.*s/index.html", (int)(L-1), path+1); 168 snprintf(file_path, 512, "%.*s/index.html", (int)(L-1), path+1);
152 else 169 else
153 snprintf(file_path, 512, "%.*s", (int)(L-1), path+1); 170 snprintf(file_path, 512, "%.*s", (int)(L-1), path+1);
154 } 171 }
155 else 172 else
156 {
157 strcpy(file_path, path); 173 strcpy(file_path, path);
158 }
159 } 174 }
160 175
161 // Check if file is in cache, load if not 176 // Check if file is in cache, load if not
162 void *p_file_kv = Dowa_HashMap_Get_Ptr(p_html_cache, file_path); 177 void *p_file_kv = Dowa_HashMap_Get_Ptr(p_html_cache, file_path);
163 const char *file_content = NULL; 178 const char *file_content = NULL;
169 file_content = ((Seobeo_Cache_Entry*)p_file_kv)->value; 184 file_content = ((Seobeo_Cache_Entry*)p_file_kv)->value;
170 body_size = strlen(file_content); 185 body_size = strlen(file_content);
171 } 186 }
172 else 187 else
173 { 188 {
174 // Load from disk and cache
175 file_content = Seobeo_Web_LoadFile(file_path, &body_size); 189 file_content = Seobeo_Web_LoadFile(file_path, &body_size);
176 if (file_content) 190 if (file_content)
177 {
178 Dowa_HashMap_Push(p_html_cache, file_path, file_content); 191 Dowa_HashMap_Push(p_html_cache, file_path, file_content);
179 }
180 } 192 }
181 193
182 if (!file_content) 194 if (!file_content)
183 { 195 {
184 Seobeo_Web_Header_Generate(p_response_header, 196 Seobeo_Web_Header_Generate(p_response_header,
189 (uint32)strlen(p_response_header)); 201 (uint32)strlen(p_response_header));
190 Seobeo_Handle_Flush(p_cli_handle); 202 Seobeo_Handle_Flush(p_cli_handle);
191 goto clean_up; 203 goto clean_up;
192 } 204 }
193 205
206 // Serve static file
194 const char *mime = "application/octet-stream"; 207 const char *mime = "application/octet-stream";
195 if (strstr(file_path, ".html")) mime = "text/html; charset=utf-8"; 208 if (strstr(file_path, ".html")) mime = "text/html; charset=utf-8";
196 else if (strstr(file_path, ".css")) mime = "text/css"; 209 else if (strstr(file_path, ".css")) mime = "text/css";
197 else if (strstr(file_path, ".js")) mime = "application/javascript"; 210 else if (strstr(file_path, ".js")) mime = "application/javascript";
198 else if (strstr(file_path, ".png")) mime = "image/png"; 211 else if (strstr(file_path, ".png")) mime = "image/png";
216 (const uint8*)file_content, 229 (const uint8*)file_content,
217 (uint32)body_size); 230 (uint32)body_size);
218 Seobeo_Handle_Flush(p_cli_handle); 231 Seobeo_Handle_Flush(p_cli_handle);
219 printf("DONE\n\n\n"); 232 printf("DONE\n\n\n");
220 } 233 }
221 else if (strcmp(method, "POST") == 0)
222 {
223 // --- TODO: Add POST logic here ---
224 Seobeo_Web_Header_Generate(p_response_header,
225 HTTP_NOT_FOUND,
226 "text/plain", 0);
227 Seobeo_Handle_Queue(p_cli_handle,
228 (const uint8*)p_response_header,
229 (uint32)strlen(p_response_header));
230 Seobeo_Handle_Flush(p_cli_handle);
231 }
232 else if (strcmp(method, "PUT") == 0)
233 {
234 // --- TODO: Add PUT logic here ---
235 Seobeo_Web_Header_Generate(p_response_header,
236 HTTP_NOT_FOUND,
237 "text/plain", 0);
238 Seobeo_Handle_Queue(p_cli_handle,
239 (const uint8*)p_response_header,
240 (uint32)strlen(p_response_header));
241 Seobeo_Handle_Flush(p_cli_handle);
242 }
243 else if (strcmp(method, "DELETE") == 0)
244 {
245 // --- TODO: Add DELETE logic here ---
246 Seobeo_Web_Header_Generate(p_response_header,
247 HTTP_NOT_FOUND,
248 "text/plain", 0);
249 Seobeo_Handle_Queue(p_cli_handle,
250 (const uint8*)p_response_header,
251 (uint32)strlen(p_response_header));
252 Seobeo_Handle_Flush(p_cli_handle);
253 }
254 else 234 else
255 { 235 {
256 // Unknown or unsupported method
257 Seobeo_Web_Header_Generate(p_response_header, 236 Seobeo_Web_Header_Generate(p_response_header,
258 HTTP_FORBIDDEN, 237 HTTP_FORBIDDEN,
259 "text/plain", 0); 238 "text/plain", 0);
260 Seobeo_Handle_Queue(p_cli_handle, 239 Seobeo_Handle_Queue(p_cli_handle,
261 (const uint8*)p_response_header, 240 (const uint8*)p_response_header,
267 clean_up: 246 clean_up:
268 printf("clean up\n\n"); 247 printf("clean up\n\n");
269 if (p_cli_handle) 248 if (p_cli_handle)
270 Seobeo_Handle_Destroy(p_cli_handle); 249 Seobeo_Handle_Destroy(p_cli_handle);
271 if (p_request_arena) 250 if (p_request_arena)
272 Dowa_Arena_Destroy(p_request_arena); 251 Dowa_Arena_Free(p_request_arena);
273 if (p_response_arena) 252 if (p_response_arena)
274 Dowa_Arena_Destroy(p_response_arena); 253 Dowa_Arena_Free(p_response_arena);
275 return; 254 return;
276 } 255 }
277 256
278 257
279 int Seobeo_Web_Header_Parse(Seobeo_Handle *p_handle, Seobeo_Request_Entry **pp_map, Dowa_Arena *p_arena) 258 int Seobeo_Web_Header_Parse(Seobeo_Handle *p_handle, Seobeo_Request_Entry **pp_map, Dowa_Arena *p_arena)
559 // peer closed; we’ve got everything 538 // peer closed; we’ve got everything
560 printf("\n\nCLOSED\n\n"); 539 printf("\n\nCLOSED\n\n");
561 break; 540 break;
562 }else 541 }else
563 { 542 {
564 Dowa_Arena_Destroy(p_request_arena); 543 Dowa_Arena_Free(p_request_arena);
565 Seobeo_Handle_Destroy(h); 544 Seobeo_Handle_Destroy(h);
566 return -1; 545 return -1;
567 } 546 }
568 } 547 }
569 548
570 // Debug 549 // Debug
571 printf("Request body %s", p_request_body); 550 printf("Request body %s", p_request_body);
572 Dowa_Arena_Destroy(p_request_arena); 551 Dowa_Arena_Free(p_request_arena);
573 Seobeo_Handle_Destroy(h); 552 Seobeo_Handle_Destroy(h);
574 return 0; 553 return 0;
575 } 554 }