Mercurial
comparison seobeo/s_web.c @ 101:3468e2fe8d88
[Seobeo] log ngnix proxy values (for myself). took out unneeded stuff fflush.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Sat, 03 Jan 2026 08:19:02 -0800 |
| parents | 65e5a5b89a4e |
| children | 99c4530e4629 |
comparison
equal
deleted
inserted
replaced
| 100:65e5a5b89a4e | 101:3468e2fe8d88 |
|---|---|
| 91 } | 91 } |
| 92 | 92 |
| 93 void Seobeo_Web_HandleClientRequest(Seobeo_Handle *p_cli_handle, | 93 void Seobeo_Web_HandleClientRequest(Seobeo_Handle *p_cli_handle, |
| 94 Seobeo_Cache_Entry *p_html_cache) | 94 Seobeo_Cache_Entry *p_html_cache) |
| 95 { | 95 { |
| 96 Seobeo_Log(SEOBEO_INFO, "Client is from %s\n", p_cli_handle->host); | |
| 97 Dowa_Arena *p_request_arena = Dowa_Arena_Create(1*1024*1024); // 1MB for request parsing | 96 Dowa_Arena *p_request_arena = Dowa_Arena_Create(1*1024*1024); // 1MB for request parsing |
| 98 if (!p_request_arena) { perror("Dowa_Arena_Create request"); goto clean_up; } | 97 if (!p_request_arena) { perror("Dowa_Arena_Create request"); goto clean_up; } |
| 99 | 98 |
| 100 Dowa_Arena *p_response_arena = Dowa_Arena_Create(5*1024*1024); // 5MB for response | 99 Dowa_Arena *p_response_arena = Dowa_Arena_Create(5*1024*1024); // 5MB for response |
| 101 if (!p_response_arena) { perror("Dowa_Arena_Create response"); goto clean_up; } | 100 if (!p_response_arena) { perror("Dowa_Arena_Create response"); goto clean_up; } |
| 107 int parse_result = Seobeo_Web_Header_Parse(p_cli_handle, &p_req_map, p_request_arena); | 106 int parse_result = Seobeo_Web_Header_Parse(p_cli_handle, &p_req_map, p_request_arena); |
| 108 | 107 |
| 109 if (parse_result != 0 && parse_result != 1) | 108 if (parse_result != 0 && parse_result != 1) |
| 110 { | 109 { |
| 111 Seobeo_Log(SEOBEO_ERROR, "Seobeo_Web_Header_Parse failed with code %d\n", parse_result); | 110 Seobeo_Log(SEOBEO_ERROR, "Seobeo_Web_Header_Parse failed with code %d\n", parse_result); |
| 112 fflush(stdout); | |
| 113 Seobeo_Web_Header_Generate(p_response_header, | 111 Seobeo_Web_Header_Generate(p_response_header, |
| 114 HTTP_BAD_REQUEST, | 112 HTTP_BAD_REQUEST, |
| 115 "text/plain", 0); | 113 "text/plain", 0); |
| 116 Seobeo_Handle_Queue(p_cli_handle, | 114 Seobeo_Handle_Queue(p_cli_handle, |
| 117 (const uint8*)p_response_header, | 115 (const uint8*)p_response_header, |
| 119 Seobeo_Handle_Flush(p_cli_handle); | 117 Seobeo_Handle_Flush(p_cli_handle); |
| 120 goto clean_up; | 118 goto clean_up; |
| 121 } | 119 } |
| 122 | 120 |
| 123 Seobeo_Log(SEOBEO_DEBUG, "Parse completed with code %d\n", parse_result); | 121 Seobeo_Log(SEOBEO_DEBUG, "Parse completed with code %d\n", parse_result); |
| 124 fflush(stdout); | 122 |
| 123 // Recording IP to see who is ddosing or any web scrappers... | |
| 124 void *p_real_ip_kv = Dowa_HashMap_Get_Ptr(p_req_map, "X-Real-IP"); | |
| 125 const char *real_ip = p_real_ip_kv ? ((Seobeo_Request_Entry*)p_real_ip_kv)->value : NULL; | |
| 126 // Fallback | |
| 127 if (!real_ip) | |
| 128 { | |
| 129 void *p_forwarded_kv = Dowa_HashMap_Get_Ptr(p_req_map, "X-Forwarded-For"); | |
| 130 real_ip = p_forwarded_kv ? ((Seobeo_Request_Entry*)p_forwarded_kv)->value : NULL; | |
| 131 } | |
| 132 // Fallback | |
| 133 if (!real_ip) | |
| 134 real_ip = p_cli_handle->host; | |
| 125 | 135 |
| 126 void *p_method_kv = Dowa_HashMap_Get_Ptr(p_req_map, "HTTP_Method"); | 136 void *p_method_kv = Dowa_HashMap_Get_Ptr(p_req_map, "HTTP_Method"); |
| 127 const char *method = p_method_kv ? ((Seobeo_Request_Entry*)p_method_kv)->value : NULL; | 137 const char *method = p_method_kv ? ((Seobeo_Request_Entry*)p_method_kv)->value : NULL; |
| 128 | 138 |
| 139 void *p_path_kv_log = Dowa_HashMap_Get_Ptr(p_req_map, "Path"); | |
| 140 const char *path_log = p_path_kv_log ? ((Seobeo_Request_Entry*)p_path_kv_log)->value : "/"; | |
| 141 | |
| 142 Seobeo_Log(SEOBEO_INFO, "%s - %s %s\n", | |
| 143 real_ip ? real_ip : "unknown", | |
| 144 method ? method : "UNKNOWN", | |
| 145 path_log); | |
| 146 | |
| 129 Seobeo_Log(SEOBEO_DEBUG, "Parsed request, method=%s\n", method ? method : "NULL"); | 147 Seobeo_Log(SEOBEO_DEBUG, "Parsed request, method=%s\n", method ? method : "NULL"); |
| 130 fflush(stdout); | |
| 131 | 148 |
| 132 if (!method) | 149 if (!method) |
| 133 { | 150 { |
| 134 Seobeo_Log(SEOBEO_ERROR, "No HTTP method found in request\n"); | 151 Seobeo_Log(SEOBEO_ERROR, "No HTTP method found in request\n"); |
| 135 fflush(stdout); | |
| 136 Seobeo_Web_Header_Generate(p_response_header, | 152 Seobeo_Web_Header_Generate(p_response_header, |
| 137 HTTP_BAD_REQUEST, | 153 HTTP_BAD_REQUEST, |
| 138 "text/plain", 0); | 154 "text/plain", 0); |
| 139 Seobeo_Handle_Queue(p_cli_handle, | 155 Seobeo_Handle_Queue(p_cli_handle, |
| 140 (const uint8*)p_response_header, | 156 (const uint8*)p_response_header, |
| 293 char *first_line_end = strstr(buf, "\r\n"); | 309 char *first_line_end = strstr(buf, "\r\n"); |
| 294 if (first_line_end) | 310 if (first_line_end) |
| 295 { | 311 { |
| 296 size_t first_line_len = first_line_end - buf; | 312 size_t first_line_len = first_line_end - buf; |
| 297 Seobeo_Log(SEOBEO_DEBUG, "Request line (first %zu bytes)\n", first_line_len > 200 ? 200 : first_line_len); | 313 Seobeo_Log(SEOBEO_DEBUG, "Request line (first %zu bytes)\n", first_line_len > 200 ? 200 : first_line_len); |
| 298 fflush(stdout); | |
| 299 } | 314 } |
| 300 | 315 |
| 301 // This seems kinda bad ? | 316 // This seems kinda bad ? |
| 302 char method[16], path[256], version[16]; | 317 char method[16], path[256], version[16]; |
| 303 int scan_result = sscanf(buf, "%15s %255s %15s", method, path, version); | 318 int scan_result = sscanf(buf, "%15s %255s %15s", method, path, version); |
| 304 Seobeo_Log(SEOBEO_DEBUG, "sscanf returned %d (method='%s', path='%s', version='%s')\n", | 319 Seobeo_Log(SEOBEO_DEBUG, "sscanf returned %d (method='%s', path='%s', version='%s')\n", |
| 305 scan_result, | 320 scan_result, |
| 306 scan_result >= 1 ? method : "N/A", | 321 scan_result >= 1 ? method : "N/A", |
| 307 scan_result >= 2 ? path : "N/A", | 322 scan_result >= 2 ? path : "N/A", |
| 308 scan_result >= 3 ? version : "N/A"); | 323 scan_result >= 3 ? version : "N/A"); |
| 309 fflush(stdout); | |
| 310 | 324 |
| 311 if (scan_result != 3) | 325 if (scan_result != 3) |
| 312 { | 326 { |
| 313 Seobeo_Log(SEOBEO_ERROR, "Failed to parse request line\n"); | 327 Seobeo_Log(SEOBEO_ERROR, "Failed to parse request line\n"); |
| 314 fflush(stdout); | |
| 315 return -1; | 328 return -1; |
| 316 } | 329 } |
| 317 | 330 |
| 318 // Copy strings to arena and store in hashmap | 331 // Copy strings to arena and store in hashmap |
| 319 Seobeo_Log(SEOBEO_DEBUG, "Allocating method_copy\n"); | 332 Seobeo_Log(SEOBEO_DEBUG, "Allocating method_copy\n"); |
| 320 fflush(stdout); | |
| 321 char *method_copy = Dowa_Arena_Allocate(p_arena, strlen(method) + 1); | 333 char *method_copy = Dowa_Arena_Allocate(p_arena, strlen(method) + 1); |
| 322 if (!method_copy) { Seobeo_Log(SEOBEO_ERROR, "Failed to allocate method_copy\n"); return -1; } | 334 if (!method_copy) { Seobeo_Log(SEOBEO_ERROR, "Failed to allocate method_copy\n"); return -1; } |
| 323 strcpy(method_copy, method); | 335 strcpy(method_copy, method); |
| 324 | 336 |
| 325 Seobeo_Log(SEOBEO_DEBUG, "Allocating version_copy\n"); | 337 Seobeo_Log(SEOBEO_DEBUG, "Allocating version_copy\n"); |
| 326 fflush(stdout); | |
| 327 char *version_copy = Dowa_Arena_Allocate(p_arena, strlen(version) + 1); | 338 char *version_copy = Dowa_Arena_Allocate(p_arena, strlen(version) + 1); |
| 328 if (!version_copy) { Seobeo_Log(SEOBEO_ERROR, "Failed to allocate version_copy\n"); return -1; } | 339 if (!version_copy) { Seobeo_Log(SEOBEO_ERROR, "Failed to allocate version_copy\n"); return -1; } |
| 329 strcpy(version_copy, version); | 340 strcpy(version_copy, version); |
| 330 | 341 |
| 331 Seobeo_Log(SEOBEO_DEBUG, "Pushing HTTP_Method and Version to map\n"); | 342 Seobeo_Log(SEOBEO_DEBUG, "Pushing HTTP_Method and Version to map\n"); |
| 332 fflush(stdout); | |
| 333 Dowa_HashMap_Push_Arena(*pp_map, "HTTP_Method", method_copy, p_arena); | 343 Dowa_HashMap_Push_Arena(*pp_map, "HTTP_Method", method_copy, p_arena); |
| 334 Dowa_HashMap_Push_Arena(*pp_map, "Version", version_copy, p_arena); | 344 Dowa_HashMap_Push_Arena(*pp_map, "Version", version_copy, p_arena); |
| 335 Seobeo_Log(SEOBEO_DEBUG, "Map now has %zu entries\n", Dowa_Array_Length(*pp_map)); | 345 Seobeo_Log(SEOBEO_DEBUG, "Map now has %zu entries\n", Dowa_Array_Length(*pp_map)); |
| 336 fflush(stdout); | |
| 337 | 346 |
| 338 // 1) Separate raw path and query string | 347 // 1) Separate raw path and query string |
| 339 char *raw_path = path; | 348 char *raw_path = path; |
| 340 char *query_start = strchr(raw_path, '?'); | 349 char *query_start = strchr(raw_path, '?'); |
| 341 char *query_str = NULL; | 350 char *query_str = NULL; |
| 433 { | 442 { |
| 434 const char *content_length_str = ((Seobeo_Request_Entry*)p_cl_kv)->value; | 443 const char *content_length_str = ((Seobeo_Request_Entry*)p_cl_kv)->value; |
| 435 size_t body_len = atoi(content_length_str); | 444 size_t body_len = atoi(content_length_str); |
| 436 | 445 |
| 437 Seobeo_Log(SEOBEO_DEBUG, "Content-Length=%zu, reading body in chunks...\n", body_len); | 446 Seobeo_Log(SEOBEO_DEBUG, "Content-Length=%zu, reading body in chunks...\n", body_len); |
| 438 fflush(stdout); | |
| 439 | 447 |
| 440 // Allocate buffer for entire body | 448 // Allocate buffer for entire body |
| 441 char *body = Dowa_Arena_Allocate(p_arena, body_len + 1); | 449 char *body = Dowa_Arena_Allocate(p_arena, body_len + 1); |
| 442 if (!body) | 450 if (!body) |
| 443 { | 451 { |
| 444 Seobeo_Log(SEOBEO_ERROR, "Failed to allocate %zu bytes for body\n", body_len); | 452 Seobeo_Log(SEOBEO_ERROR, "Failed to allocate %zu bytes for body\n", body_len); |
| 445 fflush(stdout); | |
| 446 return -1; | 453 return -1; |
| 447 } | 454 } |
| 448 | 455 |
| 449 size_t total_read = 0; | 456 size_t total_read = 0; |
| 450 | 457 |
| 460 memcpy(body + total_read, p_handle->read_buffer, to_copy); | 467 memcpy(body + total_read, p_handle->read_buffer, to_copy); |
| 461 total_read += to_copy; | 468 total_read += to_copy; |
| 462 Seobeo_Handle_Consume(p_handle, (uint32)to_copy); | 469 Seobeo_Handle_Consume(p_handle, (uint32)to_copy); |
| 463 | 470 |
| 464 Seobeo_Log(SEOBEO_DEBUG, "Copied %zu bytes, total %zu/%zu\n", to_copy, total_read, body_len); | 471 Seobeo_Log(SEOBEO_DEBUG, "Copied %zu bytes, total %zu/%zu\n", to_copy, total_read, body_len); |
| 465 fflush(stdout); | |
| 466 } | 472 } |
| 467 | 473 |
| 468 // If we still need more data, read another chunk | 474 // If we still need more data, read another chunk |
| 469 if (total_read < body_len) | 475 if (total_read < body_len) |
| 470 { | 476 { |
| 471 int r = Seobeo_Handle_Read(p_handle); | 477 int r = Seobeo_Handle_Read(p_handle); |
| 472 if (r < 0) | 478 if (r < 0) |
| 473 { | 479 { |
| 474 Seobeo_Log(SEOBEO_ERROR, "Read failed with %d\n", r); | 480 Seobeo_Log(SEOBEO_ERROR, "Read failed with %d\n", r); |
| 475 fflush(stdout); | |
| 476 return -1; | 481 return -1; |
| 477 } | 482 } |
| 478 if (r == 0) | 483 if (r == 0) |
| 479 { | 484 { |
| 480 // No data available yet, continue waiting | 485 // No data available yet, continue waiting |
| 481 // printf("DEBUG: Waiting for more data... (have %zu/%zu bytes)\n", total_read, body_len); | 486 // printf("DEBUG: Waiting for more data... (have %zu/%zu bytes)\n", total_read, body_len); |
| 482 fflush(stdout); | |
| 483 continue; | 487 continue; |
| 484 } | 488 } |
| 485 } | 489 } |
| 486 } | 490 } |
| 487 | 491 |
| 488 body[body_len] = '\0'; | 492 body[body_len] = '\0'; |
| 489 Seobeo_Log(SEOBEO_DEBUG, "Body fully received (%zu bytes)\n", body_len); | 493 Seobeo_Log(SEOBEO_DEBUG, "Body fully received (%zu bytes)\n", body_len); |
| 490 fflush(stdout); | |
| 491 | 494 |
| 492 // Body is arena-allocated | 495 // Body is arena-allocated |
| 493 Dowa_HashMap_Push_Arena(*pp_map, "Body", body, p_arena); | 496 Dowa_HashMap_Push_Arena(*pp_map, "Body", body, p_arena); |
| 494 } | 497 } |
| 495 | 498 |