comparison seobeo/s_web.c @ 71:75de5903355c

Giagantic changes that update Dowa library to be more align with stb style array and hashmap. Updated Seobeo to be caching on server side instead of file level caching. Deleted bunch of things I don't really use.
author June Park <parkjune1995@gmail.com>
date Sun, 28 Dec 2025 20:34:22 -0800
parents 6626ec933933
children 4532ce6d9eb8
comparison
equal deleted inserted replaced
70:4bc56e88e1f3 71:75de5903355c
1 #include "seobeo/seobeo.h" 1 #include "seobeo/seobeo.h"
2
3 // Global folder path for serving files
4 static char g_folder_path[512] = ".";
2 5
3 int Seobeo_Web_GenerateRequestHeader(void *buffer, const char *host, 6 int Seobeo_Web_GenerateRequestHeader(void *buffer, const char *host,
4 const char *path) 7 const char *path)
5 { 8 {
6 return sprintf( 9 return sprintf(
24 "\r\n", 27 "\r\n",
25 path, host 28 path, host
26 ); 29 );
27 } 30 }
28 31
32 // Load file from disk and cache it
33 static char* Seobeo_Web_LoadFile(const char *file_path, size_t *p_file_size)
34 {
35 char full_path[1024];
36 snprintf(full_path, sizeof(full_path), "%s/%s", g_folder_path, file_path);
37
38 FILE *p_file = fopen(full_path, "rb");
39 if (!p_file)
40 return NULL;
41
42 fseek(p_file, 0, SEEK_END);
43 size_t file_size = ftell(p_file);
44 fseek(p_file, 0, SEEK_SET);
45
46 char *p_content = (char*)malloc(file_size + 1);
47 if (!p_content)
48 {
49 fclose(p_file);
50 return NULL;
51 }
52
53 fread(p_content, 1, file_size, p_file);
54 p_content[file_size] = '\0';
55 fclose(p_file);
56
57 if (p_file_size)
58 *p_file_size = file_size;
59
60 return p_content;
61 }
62
29 void Seobeo_Web_Header_Generate(void *buffer, int status, 63 void Seobeo_Web_Header_Generate(void *buffer, int status,
30 const char *content_type, const int content_length) 64 const char *content_type, const int content_length)
31 { 65 {
32 const char *status_text; 66 const char *status_text;
33 switch(status) 67 switch(status)
34 { 68 {
35 case HTTP_OK: status_text = "OK"; break; 69 case HTTP_OK: status_text = "OK"; break;
54 status, status_text, content_type, content_length 88 status, status_text, content_type, content_length
55 ); 89 );
56 } 90 }
57 91
58 void Seobeo_Web_HandleClientRequest(Seobeo_Handle *p_cli_handle, 92 void Seobeo_Web_HandleClientRequest(Seobeo_Handle *p_cli_handle,
59 Dowa_HashMap *p_html_cache) 93 Seobeo_Cache_Entry *p_html_cache)
60 { 94 {
61 printf("p_cli_handle: %p", p_cli_handle); 95 Dowa_Arena *p_request_arena = Dowa_Arena_Create(1*1024*1024); // 1MB for request parsing
62 Dowa_HashEntry *entry = NULL; 96 if (!p_request_arena) { perror("Dowa_Arena_Create request"); goto clean_up; }
63 Dowa_HashMap *p_current = p_html_cache; 97
64 char *slash; 98 Dowa_Arena *p_response_arena = Dowa_Arena_Create(1*1024*1024); // 1MB for response
65 99 if (!p_response_arena) { perror("Dowa_Arena_Create response"); goto clean_up; }
66 Dowa_Arena *p_response_arena = Dowa_Arena_Create(1*1024*1024); 100
67 if (!p_response_arena) { perror("Dowa_Arena_Initialize"); goto clean_up; } 101 void *p_response_header = Dowa_Arena_Allocate(p_response_arena, (size_t)1024*5); // 5Kb
68
69 void *p_response_header = Dowa_Arena_Allocate(p_response_arena, (size_t)2048);
70 if (!p_response_header) { perror("Dowa_Arena_Allocate"); goto clean_up; } 102 if (!p_response_header) { perror("Dowa_Arena_Allocate"); goto clean_up; }
71 103
72 // Parse request headers into hashmap 104 // Parse request headers into hashmap using arena
73 Dowa_HashMap *p_req_map = Dowa_HashMap_Create_With_Arena(100, p_response_arena); 105 Seobeo_Request_Entry *p_req_map = NULL;
74 if (Seobeo_Web_Header_Parse(p_cli_handle, p_req_map) != 0) 106 if (Seobeo_Web_Header_Parse(p_cli_handle, &p_req_map, p_request_arena) != 0)
75 { 107 {
76 Seobeo_Web_Header_Generate(p_response_header, 108 Seobeo_Web_Header_Generate(p_response_header,
77 HTTP_BAD_REQUEST, 109 HTTP_BAD_REQUEST,
78 "text/plain", 0); 110 "text/plain", 0);
79 Seobeo_Handle_Queue(p_cli_handle, 111 Seobeo_Handle_Queue(p_cli_handle,
80 (const uint8*)p_response_header, 112 (const uint8*)p_response_header,
81 (uint32)strlen(p_response_header)); 113 (uint32)strlen(p_response_header));
82 Seobeo_Handle_Flush(p_cli_handle); 114 Seobeo_Handle_Flush(p_cli_handle);
83 goto clean_up; 115 goto clean_up;
84 return; 116 }
85 }
86
87 // Dowa_HashMap_Print(p_req_map);
88 117
89 // Extract method (GET, POST, etc.) 118 // Extract method (GET, POST, etc.)
90 const char *method = (const char*)Dowa_HashMap_Get(p_req_map, "HTTP_Method"); 119 void *p_method_kv = Dowa_HashMap_Get_Ptr(p_req_map, "HTTP_Method");
120 const char *method = p_method_kv ? ((Seobeo_Request_Entry*)p_method_kv)->value : NULL;
121
91 if (!method) 122 if (!method)
92 { 123 {
93 Seobeo_Web_Header_Generate(p_response_header, 124 Seobeo_Web_Header_Generate(p_response_header,
94 HTTP_BAD_REQUEST, 125 HTTP_BAD_REQUEST,
95 "text/plain", 0); 126 "text/plain", 0);
98 (uint32)strlen(p_response_header)); 129 (uint32)strlen(p_response_header));
99 Seobeo_Handle_Flush(p_cli_handle); 130 Seobeo_Handle_Flush(p_cli_handle);
100 goto clean_up; 131 goto clean_up;
101 } 132 }
102 133
103 // --- Separate GET map for caching or routing ---
104 Dowa_HashMap *p_get_map = Dowa_HashMap_Create(64);
105 if (!p_get_map)
106 {
107 perror("Dowa_HashMap_Create (p_get_map)");
108 goto clean_up;
109 }
110
111 // --- Handle different HTTP methods --- 134 // --- Handle different HTTP methods ---
112 if (strcmp(method, "GET") == 0) 135 if (strcmp(method, "GET") == 0)
113 { 136 {
114 const char *path = (const char*)Dowa_HashMap_Get(p_req_map, "Path"); 137 void *p_kv = Dowa_HashMap_Get_Ptr(p_req_map, "Path");
115 char *file_path = Dowa_Arena_Allocate(p_response_arena, (size_t)512); 138 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
116 140
117 if (!path || strcmp(path, "/") == 0) 141 if (!path || strcmp(path, "/") == 0)
118 { 142 {
119 strcpy(file_path, "index.html"); 143 strcpy(file_path, "index.html");
120 } 144 }
132 { 156 {
133 strcpy(file_path, path); 157 strcpy(file_path, path);
134 } 158 }
135 } 159 }
136 160
137 // Store path for GET handling map 161 // Check if file is in cache, load if not
138 Dowa_HashMap_Push_Value(p_get_map, "Path", file_path, strlen(file_path) + 1); 162 void *p_file_kv = Dowa_HashMap_Get_Ptr(p_html_cache, file_path);
139 163 const char *file_content = NULL;
140 // Walk through nested maps to find content 164 size_t body_size = 0;
141 while ((slash = strchr(file_path, '/'))) 165
142 { 166 if (p_file_kv)
143 *slash = '\0'; 167 {
144 char *dir = file_path; 168 // File is cached
145 file_path = slash + 1; 169 file_content = ((Seobeo_Cache_Entry*)p_file_kv)->value;
146 170 body_size = strlen(file_content);
147 printf("Directory: %s\n", dir); 171 }
148 172 else
149 p_current = Dowa_HashMap_Get(p_current, dir); 173 {
150 if (!p_current) 174 // Load from disk and cache
175 file_content = Seobeo_Web_LoadFile(file_path, &body_size);
176 if (file_content)
151 { 177 {
152 fprintf(stderr, "No value in hashmap key: %s\n\n", dir); 178 Dowa_HashMap_Push(p_html_cache, file_path, file_content);
153 Seobeo_Web_Header_Generate(p_response_header,
154 HTTP_NOT_FOUND,
155 "text/html", 0);
156 Seobeo_Handle_Queue(p_cli_handle,
157 (const uint8*)p_response_header,
158 (uint32)strlen(p_response_header));
159 Seobeo_Handle_Flush(p_cli_handle);
160 goto clean_up;
161 } 179 }
162 } 180 }
163 181
164 size_t pos = Dowa_HashMap_Get_Position(p_current, file_path); 182 if (!file_content)
165 entry = p_current->entries[pos];
166
167 if (!entry)
168 { 183 {
169 Seobeo_Web_Header_Generate(p_response_header, 184 Seobeo_Web_Header_Generate(p_response_header,
170 HTTP_NOT_FOUND, 185 HTTP_NOT_FOUND,
171 "text/html", 0); 186 "text/html", 0);
172 Seobeo_Handle_Queue(p_cli_handle, 187 Seobeo_Handle_Queue(p_cli_handle,
185 else if (strstr(file_path, ".gif")) mime = "image/gif"; 200 else if (strstr(file_path, ".gif")) mime = "image/gif";
186 else if (strstr(file_path, ".svg")) mime = "image/svg+xml"; 201 else if (strstr(file_path, ".svg")) mime = "image/svg+xml";
187 else if (strstr(file_path, ".ico")) mime = "image/x-icon"; 202 else if (strstr(file_path, ".ico")) mime = "image/x-icon";
188 else if (strstr(file_path, ".json")) mime = "application/json"; 203 else if (strstr(file_path, ".json")) mime = "application/json";
189 204
190 size_t body_size = entry->capacity; 205 printf("File path: %s\nBody Size: %zu\n", file_path, body_size);
191 printf("key: %s\nBody Size: %zu\n", entry->key, body_size);
192 206
193 Seobeo_Web_Header_Generate(p_response_header, 207 Seobeo_Web_Header_Generate(p_response_header,
194 HTTP_OK, 208 HTTP_OK,
195 mime, 209 mime,
196 body_size); 210 body_size);
197 211
198 Seobeo_Handle_Queue(p_cli_handle, 212 Seobeo_Handle_Queue(p_cli_handle,
199 (const uint8*)p_response_header, 213 (const uint8*)p_response_header,
200 (uint32)strlen(p_response_header)); 214 (uint32)strlen(p_response_header));
201 Seobeo_Handle_Queue(p_cli_handle, 215 Seobeo_Handle_Queue(p_cli_handle,
202 (const uint8*)entry->buffer, 216 (const uint8*)file_content,
203 (uint32)body_size); 217 (uint32)body_size);
204 Seobeo_Handle_Flush(p_cli_handle); 218 Seobeo_Handle_Flush(p_cli_handle);
205 printf("DONE\n\n\n"); 219 printf("DONE\n\n\n");
206 } 220 }
207 else if (strcmp(method, "POST") == 0) 221 else if (strcmp(method, "POST") == 0)
252 266
253 clean_up: 267 clean_up:
254 printf("clean up\n\n"); 268 printf("clean up\n\n");
255 if (p_cli_handle) 269 if (p_cli_handle)
256 Seobeo_Handle_Destroy(p_cli_handle); 270 Seobeo_Handle_Destroy(p_cli_handle);
271 if (p_request_arena)
272 Dowa_Arena_Destroy(p_request_arena);
257 if (p_response_arena) 273 if (p_response_arena)
258 Dowa_Arena_Destroy(p_response_arena); 274 Dowa_Arena_Destroy(p_response_arena);
259 return; 275 return;
260 } 276 }
261 277
262 278
263 int Seobeo_Web_Header_Parse(Seobeo_Handle *p_handle, Dowa_HashMap *map) 279 int Seobeo_Web_Header_Parse(Seobeo_Handle *p_handle, Seobeo_Request_Entry **pp_map, Dowa_Arena *p_arena)
264 { 280 {
265 // 1) Fill read_buffer until we see "\r\n\r\n" 281 // 1) Fill read_buffer until we see "\r\n\r\n"
266 while (1) 282 while (1)
267 { 283 {
268 int r = Seobeo_Handle_Read(p_handle); 284 int r = Seobeo_Handle_Read(p_handle);
269 if (r < 0) return -1; // fatal error 285 if (r < 0)
270 if (r == -2) return -2; // connection closed TODO: Add this as part of Handle struct. 286 return -1; // fatal error
287 if (r == -2)
288 return -2; // connection closed TODO: Add this as part of Handle struct.
271 289
272 if (p_handle->read_buffer_len >= 4 && 290 if (p_handle->read_buffer_len >= 4 &&
273 strstr((char*)p_handle->read_buffer, "\r\n\r\n") != NULL) 291 strstr((char*)p_handle->read_buffer, "\r\n\r\n") != NULL)
274 { 292 {
275 break; 293 break;
276 } 294 }
277 if (r == 0) return 1; // EAGAIN, try again later TODO: Add this as part of Handle struct. 295 if (r == 0)
296 return 1; // EAGAIN, try again later TODO: Add this as part of Handle struct.
278 } 297 }
279 298
280 // 2) Parse request‐line "METHOD SP PATH SP VERSION CRLF" 299 // 2) Parse request‐line "METHOD SP PATH SP VERSION CRLF"
281 char *buf = (char*)p_handle->read_buffer; 300 char *buf = (char*)p_handle->read_buffer;
282 char *hdr_end = strstr(buf, "\r\n\r\n"); 301 char *hdr_end = strstr(buf, "\r\n\r\n");
287 if (sscanf(buf, "%15s %255s %15s", method, path, version) != 3) 306 if (sscanf(buf, "%15s %255s %15s", method, path, version) != 3)
288 { 307 {
289 return -1; 308 return -1;
290 } 309 }
291 310
292 Dowa_HashMap_Push_Value_With_Type(map, "HTTP_Method", method, strlen(method) + 1, DOWA_HASH_MAP_TYPE_STRING); 311 // Copy strings to arena and store in hashmap
293 printf("Method: %s Pointer %p\n\n", Dowa_HashMap_Get(map, "HTTP_Method"), map); 312 char *method_copy = Dowa_Arena_Allocate(p_arena, strlen(method) + 1);
294 Dowa_HashMap_Push_Value_With_Type(map, "Version", version, strlen(version) + 1, DOWA_HASH_MAP_TYPE_STRING); 313 if (!method_copy) return -1;
314 strcpy(method_copy, method);
315
316 char *version_copy = Dowa_Arena_Allocate(p_arena, strlen(version) + 1);
317 if (!version_copy) return -1;
318 strcpy(version_copy, version);
319
320 Dowa_HashMap_Push_Arena(*pp_map, "HTTP_Method", method_copy, p_arena);
321 Dowa_HashMap_Push_Arena(*pp_map, "Version", version_copy, p_arena);
295 322
296 // 1) Separate raw path and query string 323 // 1) Separate raw path and query string
297 char *raw_path = path; 324 char *raw_path = path;
298 char *query_start = strchr(raw_path, '?'); 325 char *query_start = strchr(raw_path, '?');
299 char *query_str = NULL; 326 char *query_str = NULL;
303 *query_start = '\0'; // now raw_path ends before '?' 330 *query_start = '\0'; // now raw_path ends before '?'
304 query_str = query_start + 1; 331 query_str = query_start + 1;
305 } 332 }
306 333
307 // push only the clean path 334 // push only the clean path
308 Dowa_HashMap_Push_Value_With_Type( 335 char *path_copy = Dowa_Arena_Allocate(p_arena, strlen(raw_path) + 1);
309 map, 336 if (!path_copy) return -1;
310 "Path", 337 strcpy(path_copy, raw_path);
311 raw_path, 338 Dowa_HashMap_Push_Arena(*pp_map, "Path", path_copy, p_arena);
312 strlen(raw_path) + 1,
313 DOWA_HASH_MAP_TYPE_STRING);
314 339
315 // 2) If there *is* a query, tokenize into a sub-map 340 // 2) If there *is* a query, tokenize into the same map with "query_" prefix
316 if (query_str && *query_str) 341 if (query_str && *query_str)
317 { 342 {
318 // create nested map for GET params
319 Dowa_HashMap *p_query_map = Dowa_HashMap_Create_With_Arena(100, map->p_arena);
320
321 char *cur = query_str; 343 char *cur = query_str;
322 while (cur && *cur) 344 while (cur && *cur)
323 { 345 {
324 // find the next '&'
325 char *next_amp = strchr(cur, '&'); 346 char *next_amp = strchr(cur, '&');
326 // if none, treat end-of-string as the boundary
327 char *pair_end = next_amp ? next_amp : cur + strlen(cur); 347 char *pair_end = next_amp ? next_amp : cur + strlen(cur);
328 348
329 // find '=' in [cur, pair_end)
330 char *eq = memchr(cur, '=', pair_end - cur); 349 char *eq = memchr(cur, '=', pair_end - cur);
331 if (eq) { 350 if (eq)
351 {
332 size_t key_len = eq - cur; 352 size_t key_len = eq - cur;
333 size_t val_len = pair_end - (eq + 1); 353 size_t val_len = pair_end - (eq + 1);
334 354
335 // extract key 355 char key_buf[256];
336 char key_buf[key_len + 1]; 356 snprintf(key_buf, sizeof(key_buf), "query_%.*s", (int)key_len, cur);
337 memcpy(key_buf, cur, key_len); 357
338 key_buf[key_len] = '\0'; 358 char *val_copy = Dowa_Arena_Allocate(p_arena, val_len + 1);
339 359 if (!val_copy) return -1;
340 // extract value 360 memcpy(val_copy, eq + 1, val_len);
341 char val_buf[val_len + 1]; 361 val_copy[val_len] = '\0';
342 memcpy(val_buf, eq + 1, val_len); 362
343 val_buf[val_len] = '\0'; 363 Dowa_HashMap_Push_Arena(*pp_map, key_buf, val_copy, p_arena);
344
345 printf("key: '%s', value: '%s'\n", key_buf, val_buf);
346 // push into map with strlen(val_buf)+1 to include '\0'
347 Dowa_HashMap_Push_Value_With_Type(
348 p_query_map,
349 key_buf,
350 val_buf,
351 (uint32_t)(val_len + 1),
352 DOWA_HASH_MAP_TYPE_STRING);
353 } 364 }
354 365
355 // advance past '&' if present, else end loop
356 cur = next_amp ? next_amp + 1 : NULL; 366 cur = next_amp ? next_amp + 1 : NULL;
357 }
358 if (
359 Dowa_HashMap_Push_Value_With_Type_NoCopy(
360 map,
361 "QueryParams",
362 p_query_map,
363 sizeof(p_query_map),
364 DOWA_HASH_MAP_TYPE_HASHMAP) == -1
365 )
366 {
367 printf("Something went wrong...\n\n");
368 } 367 }
369 } 368 }
370 369
371 // int qp = Dowa_HashMap_Get_Position(map, "QueryParams"); 370 // int qp = Dowa_HashMap_Get_Position(map, "QueryParams");
372 // Dowa_HashEntry *p_qp_entry = map->entries[qp]; 371 // Dowa_HashEntry *p_qp_entry = map->entries[qp];
392 { 391 {
393 val_start++; 392 val_start++;
394 value_len--; 393 value_len--;
395 } 394 }
396 395
397 char *key = malloc(key_len + 1); 396 char *key = Dowa_Arena_Allocate(p_arena, key_len + 1);
397 if (!key) return -1;
398 memcpy(key, line, key_len); 398 memcpy(key, line, key_len);
399 key[key_len] = '\0'; 399 key[key_len] = '\0';
400 400
401 char *val = malloc(value_len + 1); 401 char *val = Dowa_Arena_Allocate(p_arena, value_len + 1);
402 if (!val) return -1;
402 memcpy(val, val_start, value_len); 403 memcpy(val, val_start, value_len);
403 val[value_len] = '\0'; 404 val[value_len] = '\0';
404 405
405 Dowa_HashMap_Push_Value_With_Type(map, key, val, value_len + 1, DOWA_HASH_MAP_TYPE_STRING); 406 // Both key and value are arena-allocated, hashmap will use them
406 407 Dowa_HashMap_Push_Arena(*pp_map, key, val, p_arena);
407 // printf("Capacity: %d, Length: %d ", (int)map->p_arena->capacity, (int)map->p_arena->offset);
408 // printf("value_len: %d, key: %s value %s position: %d\n\n", (int)value_len + 1, key, val, Dowa_HashMap_Get_Position(map, key));
409 // printf("Method: %s Position: %d Pointer %p\n\n", Dowa_HashMap_Get(map, "HTTP_Method"), Dowa_HashMap_Get_Position(map, "HTTP_Method"), map);
410
411 Dowa_Free(key);
412 Dowa_Free(val);
413 } 408 }
414 409
415 line = next + 2; 410 line = next + 2;
416 } 411 }
412
417 Seobeo_Handle_Consume(p_handle, (uint32)hdr_len); 413 Seobeo_Handle_Consume(p_handle, (uint32)hdr_len);
418 414
419 // 4) If Content-Length was provided, read that much body 415 // 4) If Content-Length was provided, read that much body
420 int content_length_pos = Dowa_HashMap_Get_Position(map, "Content-Length"); 416 void *p_cl_kv = Dowa_HashMap_Get_Ptr(*pp_map, "Content-Length");
421 Dowa_HashEntry *p_content_length_entry = map->entries[content_length_pos]; 417 if (p_cl_kv)
422 if (p_content_length_entry) 418 {
423 { 419 const char *content_length_str = ((Seobeo_Request_Entry*)p_cl_kv)->value;
424 size_t body_len = atoi((char*)p_content_length_entry->buffer); 420 size_t body_len = atoi(content_length_str);
425 while (p_handle->read_buffer_len < body_len) 421 while (p_handle->read_buffer_len < body_len)
426 { 422 {
427 int r = Seobeo_Handle_Read(p_handle); 423 int r = Seobeo_Handle_Read(p_handle);
428 if (r < 0) return -1; 424 if (r < 0) return -1;
429 if (r == 0) return 1; // wait for more data 425 if (r == 0) return 1; // wait for more data
430 } 426 }
431 427
432 char *body = malloc(body_len + 1); 428 char *body = Dowa_Arena_Allocate(p_arena, body_len + 1);
429 if (!body) return -1;
433 memcpy(body, p_handle->read_buffer, body_len); 430 memcpy(body, p_handle->read_buffer, body_len);
434 body[body_len] = '\0'; 431 body[body_len] = '\0';
435 432
436 Dowa_HashMap_Push_Value(map, "Body", body, body_len + 1); 433 // Body is arena-allocated
437 Dowa_Free(body); 434 Dowa_HashMap_Push_Arena(*pp_map, "Body", body, p_arena);
438 435
439 Seobeo_Handle_Consume(p_handle, (uint32)body_len); 436 Seobeo_Handle_Consume(p_handle, (uint32)body_len);
440 } 437 }
441 438
442 return 0; // success; map now holds Method, Path, Version, headers, and optional Body 439 return 0; // success; map now holds Method, Path, Version, headers, and optional Body
459 const char *folder_path, 456 const char *folder_path,
460 const char *port, 457 const char *port,
461 Seobeo_ServerMode mode, 458 Seobeo_ServerMode mode,
462 int thread_count) 459 int thread_count)
463 { 460 {
464 Dowa_HashMap *p_html_cache = Dowa_HashMap_Create(200); 461 // Store folder path globally
465 if (Dowa_HashMap_Cache_Folder(p_html_cache, 462 if (folder_path)
466 folder_path) != 0) 463 strncpy(g_folder_path, folder_path, sizeof(g_folder_path) - 1);
467 { 464
468 perror("Dowa_Cache_Folder"); 465 // Initialize empty cache - files will be loaded on-demand
469 return -1; 466 Seobeo_Cache_Entry *p_html_cache = NULL;
470 }
471 467
472 Seobeo_Handle *p_server_handle = 468 Seobeo_Handle *p_server_handle =
473 Seobeo_Stream_Handle_Server_Create(NULL, port); 469 Seobeo_Stream_Handle_Server_Create(NULL, port);
474 if (p_server_handle->socket < 0) return 1; 470 if (p_server_handle->socket < 0) return 1;
475 471
501 } 497 }
502 498
503 if (mode == SEOBEO_MODE_EDGE) 499 if (mode == SEOBEO_MODE_EDGE)
504 { 500 {
505 printf("EDGE MODE\n"); 501 printf("EDGE MODE\n");
506 // Seobeo_Web_Edge_2(p_server_handle, p_html_cache);
507 Seobeo_Web_Edge(p_server_handle, thread_count, p_html_cache); 502 Seobeo_Web_Edge(p_server_handle, thread_count, p_html_cache);
508 } 503 }
509 504
510 return -1; 505 return -1;
511 } 506 }