Mercurial
comparison mrjunejune/main.c @ 173:827c6ac504cd hg-web
Merged in default here.
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Mon, 19 Jan 2026 18:59:10 -0800 |
| parents | 295ac2e5ec00 |
| children | 90dfcef375fb |
comparison
equal
deleted
inserted
replaced
| 151:c033667da5f9 | 173:827c6ac504cd |
|---|---|
| 1 // Debug mode is now controlled by build target: use //seobeo:seobeo_tcp_server_ws_debug | |
| 2 #include "seobeo/seobeo.h" | 1 #include "seobeo/seobeo.h" |
| 2 #include "markdown_converter/markdown_to_html.h" | |
| 3 #include <time.h> | 3 #include <time.h> |
| 4 | 4 |
| 5 // UUID + /tmp/ + format (max 4) | 5 // UUID + /tmp/ + format (max 4) |
| 6 #define TMP_FILE_LENGTH 47 | 6 #define TMP_FILE_LENGTH 47 |
| 7 #define UUID_LEN 37 | 7 #define UUID_LEN 37 |
| 13 { | 13 { |
| 14 printf("Failed\n"); | 14 printf("Failed\n"); |
| 15 stop_server = 1; | 15 stop_server = 1; |
| 16 } | 16 } |
| 17 | 17 |
| 18 void Seobeo_ServerSideRender( | 18 void Seobeo_Render_Html( |
| 19 char *final_body, | 19 char *final_body, |
| 20 char *path, | 20 char *template, |
| 21 Dowa_Arena *arena | 21 Dowa_Arena *arena |
| 22 ) { | 22 ) |
| 23 Seobeo_Log(SEOBEO_DEBUG, "[Curr] %s\n", path); | 23 { |
| 24 size_t html_size = 0; | |
| 25 char *template = Seobeo_Web_LoadFile(path, &html_size); | |
| 26 if (!template) return; | |
| 27 Seobeo_Log(SEOBEO_DEBUG, "[Curr] ??\n"); | |
| 28 | |
| 29 size_t current_offset = 0; | 24 size_t current_offset = 0; |
| 30 char *cursor = template; | 25 char *cursor = template; |
| 31 | 26 |
| 32 int32 token_len = 2; | 27 int32 token_len = 2; |
| 33 | 28 |
| 59 } | 54 } |
| 60 | 55 |
| 61 cursor = end_tag + 2; | 56 cursor = end_tag + 2; |
| 62 } | 57 } |
| 63 strcpy(final_body + current_offset, cursor); | 58 strcpy(final_body + current_offset, cursor); |
| 64 free(template); | 59 } |
| 60 | |
| 61 | |
| 62 void Seobeo_Render_Html_FilePath( | |
| 63 char *final_body, | |
| 64 char *path, | |
| 65 Dowa_Arena *arena | |
| 66 ) { | |
| 67 Seobeo_Log(SEOBEO_DEBUG, "[Curr] %s\n", path); | |
| 68 size_t html_size = 0; | |
| 69 char *template = Seobeo_Web_LoadFile(path, &html_size); | |
| 70 if (!template) return; | |
| 71 Seobeo_Render_Html(final_body, template, arena); | |
| 65 } | 72 } |
| 66 | 73 |
| 67 Seobeo_Request_Entry* GetHomePage(Seobeo_Request_Entry *req, Dowa_Arena *arena) | 74 Seobeo_Request_Entry* GetHomePage(Seobeo_Request_Entry *req, Dowa_Arena *arena) |
| 68 { | 75 { |
| 69 Seobeo_Request_Entry *resp = NULL; | 76 Seobeo_Request_Entry *resp = NULL; |
| 70 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); | 77 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); |
| 71 Seobeo_ServerSideRender(final_body, "/index.html", arena); | 78 Seobeo_Render_Html_FilePath(final_body, "/index.html", arena); |
| 72 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); | 79 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); |
| 73 return resp; | 80 return resp; |
| 74 } | 81 } |
| 75 | 82 |
| 76 Seobeo_Request_Entry* GetResume(Seobeo_Request_Entry *req, Dowa_Arena *arena) | 83 Seobeo_Request_Entry* GetResume(Seobeo_Request_Entry *req, Dowa_Arena *arena) |
| 77 { | 84 { |
| 78 Seobeo_Request_Entry *resp = NULL; | 85 Seobeo_Request_Entry *resp = NULL; |
| 79 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); | 86 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); |
| 80 Seobeo_ServerSideRender(final_body, "/resume/index.html", arena); | 87 Seobeo_Render_Html_FilePath(final_body, "/resume/index.html", arena); |
| 81 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); | 88 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); |
| 82 return resp; | 89 return resp; |
| 83 } | 90 } |
| 84 | 91 |
| 85 Seobeo_Request_Entry* GetTools(Seobeo_Request_Entry *req, Dowa_Arena *arena) | 92 Seobeo_Request_Entry* GetTools(Seobeo_Request_Entry *req, Dowa_Arena *arena) |
| 86 { | 93 { |
| 87 Seobeo_Request_Entry *resp = NULL; | 94 Seobeo_Request_Entry *resp = NULL; |
| 88 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); | 95 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); |
| 89 Seobeo_ServerSideRender(final_body, "/tools/index.html", arena); | 96 Seobeo_Render_Html_FilePath(final_body, "/tools/index.html", arena); |
| 90 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); | 97 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); |
| 91 return resp; | 98 return resp; |
| 92 } | 99 } |
| 93 | 100 |
| 94 | 101 |
| 95 Seobeo_Request_Entry* GetMDToHTML(Seobeo_Request_Entry *req, Dowa_Arena *arena) | 102 Seobeo_Request_Entry* GetMDToHTML(Seobeo_Request_Entry *req, Dowa_Arena *arena) |
| 96 { | 103 { |
| 97 Seobeo_Request_Entry *resp = NULL; | 104 Seobeo_Request_Entry *resp = NULL; |
| 98 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); | 105 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); |
| 99 Seobeo_ServerSideRender(final_body, "/tools/markdown_to_html/index.html", arena); | 106 Seobeo_Render_Html_FilePath(final_body, "/tools/markdown_to_html/index.html", arena); |
| 100 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); | 107 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); |
| 101 return resp; | 108 return resp; |
| 102 } | 109 } |
| 103 | 110 |
| 104 Seobeo_Request_Entry* GetFileConverter(Seobeo_Request_Entry *req, Dowa_Arena *arena) | 111 Seobeo_Request_Entry* GetFileConverter(Seobeo_Request_Entry *req, Dowa_Arena *arena) |
| 105 { | 112 { |
| 106 Seobeo_Request_Entry *resp = NULL; | 113 Seobeo_Request_Entry *resp = NULL; |
| 107 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); | 114 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); |
| 108 Seobeo_ServerSideRender(final_body, "/tools/file_converter/index.html", arena); | 115 Seobeo_Render_Html_FilePath(final_body, "/tools/file_converter/index.html", arena); |
| 109 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); | 116 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); |
| 110 return resp; | 117 return resp; |
| 111 } | 118 } |
| 112 | 119 |
| 113 Seobeo_Request_Entry *ConvertImageToWebP(Seobeo_Request_Entry *req, Dowa_Arena *arena) | 120 Seobeo_Request_Entry *ConvertImageToWebP(Seobeo_Request_Entry *req, Dowa_Arena *arena) |
| 158 const char *content_length_str = ((Seobeo_Request_Entry*)cl_kv)->value; | 165 const char *content_length_str = ((Seobeo_Request_Entry*)cl_kv)->value; |
| 159 size_t file_size = atoi(content_length_str); | 166 size_t file_size = atoi(content_length_str); |
| 160 | 167 |
| 161 printf("DEBUG: Converting image, file_size=%zu bytes\n", file_size); | 168 printf("DEBUG: Converting image, file_size=%zu bytes\n", file_size); |
| 162 | 169 |
| 163 | |
| 164 int open_flags = O_RDWR | O_CREAT | O_EXCL; | 170 int open_flags = O_RDWR | O_CREAT | O_EXCL; |
| 165 | 171 |
| 166 char *uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN); | 172 char *uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN); |
| 167 uint32 seed = (uint32)time(NULL) ^ (uint32)pthread_self() ^ counter++; | 173 uint32 seed = (uint32)time(NULL) ^ (uint32)pthread_self() ^ counter++; |
| 168 Dowa_String_UUID(seed, uuid4); | 174 Dowa_String_UUID(seed, uuid4); |
| 277 const char *content_length_str = ((Seobeo_Request_Entry*)cl_kv)->value; | 283 const char *content_length_str = ((Seobeo_Request_Entry*)cl_kv)->value; |
| 278 size_t file_size = atoi(content_length_str); | 284 size_t file_size = atoi(content_length_str); |
| 279 | 285 |
| 280 printf("DEBUG: Converting video, file_size=%zu bytes\n", file_size); | 286 printf("DEBUG: Converting video, file_size=%zu bytes\n", file_size); |
| 281 | 287 |
| 288 int open_flags = O_RDWR | O_CREAT | O_EXCL; | |
| 289 | |
| 282 char *uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN); | 290 char *uuid4 = (char *)Dowa_Arena_Allocate(arena, UUID_LEN); |
| 283 Dowa_String_UUID((uint32)time(NULL), uuid4); | 291 uint32 seed = (uint32)time(NULL) ^ (uint32)pthread_self() ^ counter++; |
| 292 Dowa_String_UUID(seed, uuid4); | |
| 284 char *input_path = Dowa_Arena_Allocate(arena, TMP_FILE_LENGTH); | 293 char *input_path = Dowa_Arena_Allocate(arena, TMP_FILE_LENGTH); |
| 285 snprintf(input_path, TMP_FILE_LENGTH, "/tmp/%s", uuid4); | 294 snprintf(input_path, TMP_FILE_LENGTH, "/tmp/%s", uuid4); |
| 286 int input_fd = mkstemp(input_path); | 295 Seobeo_Log(SEOBEO_DEBUG, "Input path: %s\n", input_path); |
| 296 | |
| 297 int input_fd = open(input_path, open_flags, 0600); | |
| 287 if (input_fd == -1) | 298 if (input_fd == -1) |
| 288 { | 299 { |
| 300 Seobeo_Log(SEOBEO_DEBUG, "errno: %d (%s)\n", errno, strerror(errno)); | |
| 289 char *error_msg = "Failed to create temporary file"; | 301 char *error_msg = "Failed to create temporary file"; |
| 290 Dowa_HashMap_Push_Arena(resp, "status", "500", arena); | 302 Dowa_HashMap_Push_Arena(resp, "status", "500", arena); |
| 291 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena); | 303 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena); |
| 292 Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena); | 304 Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena); |
| 293 return resp; | 305 return resp; |
| 294 } | 306 } |
| 295 | 307 |
| 296 write(input_fd, file_data, file_size); | 308 write(input_fd, file_data, file_size); |
| 297 close(input_fd); | 309 close(input_fd); |
| 298 | 310 |
| 299 int open_flags = O_RDWR | O_CREAT | O_EXCL; | 311 seed = (uint32)time(NULL) ^ (uint32)pthread_self() ^ counter++; |
| 300 | |
| 301 uint32 seed = (uint32)time(NULL) ^ (uint32)pthread_self() ^ counter++;; | |
| 302 Dowa_String_UUID(seed, uuid4); | 312 Dowa_String_UUID(seed, uuid4); |
| 303 char *output_path = (char *)Dowa_Arena_Allocate(arena, TMP_FILE_LENGTH);; | 313 char *output_path = (char *)Dowa_Arena_Allocate(arena, TMP_FILE_LENGTH);; |
| 304 snprintf(output_path, TMP_FILE_LENGTH, "/tmp/%s.mp4", uuid4); | 314 snprintf(output_path, TMP_FILE_LENGTH, "/tmp/%s.mp4", uuid4); |
| 305 int output_fd = open(output_path, open_flags, 0600); | 315 int output_fd = open(output_path, open_flags, 0600); |
| 306 if (output_fd == -1) | 316 if (output_fd == -1) |
| 425 | 435 |
| 426 unlink(filepath); | 436 unlink(filepath); |
| 427 | 437 |
| 428 printf("DEBUG: Served and deleted file: %s (%zu bytes)\n", filename, file_size); | 438 printf("DEBUG: Served and deleted file: %s (%zu bytes)\n", filename, file_size); |
| 429 | 439 |
| 430 // Set proper Content-Length for binary data | |
| 431 char *content_length = Dowa_Arena_Allocate(arena, 32); | 440 char *content_length = Dowa_Arena_Allocate(arena, 32); |
| 432 snprintf(content_length, 32, "%zu", file_size); | 441 snprintf(content_length, 32, "%zu", file_size); |
| 433 | 442 |
| 434 Dowa_HashMap_Push_Arena(resp, "status", "200", arena); | 443 Dowa_HashMap_Push_Arena(resp, "status", "200", arena); |
| 435 Dowa_HashMap_Push_Arena(resp, "content-type", content_type, arena); | 444 Dowa_HashMap_Push_Arena(resp, "content-type", content_type, arena); |
| 441 | 450 |
| 442 Seobeo_Request_Entry *RenderBlogList(Seobeo_Request_Entry *req, Dowa_Arena *arena) | 451 Seobeo_Request_Entry *RenderBlogList(Seobeo_Request_Entry *req, Dowa_Arena *arena) |
| 443 { | 452 { |
| 444 Seobeo_Request_Entry *resp = NULL; | 453 Seobeo_Request_Entry *resp = NULL; |
| 445 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); | 454 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); |
| 446 Seobeo_ServerSideRender(final_body, "/blog/index.html", arena); | 455 Seobeo_Render_Html_FilePath(final_body, "/blog/index.html", arena); |
| 447 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); | 456 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); |
| 448 return resp; | 457 return resp; |
| 449 } | 458 } |
| 450 | 459 |
| 451 | 460 |
| 452 Seobeo_Request_Entry *RenderBlog(Seobeo_Request_Entry *req, Dowa_Arena *arena) | 461 Seobeo_Request_Entry *RenderBlog(Seobeo_Request_Entry *req, Dowa_Arena *arena) |
| 453 { | 462 { |
| 454 Seobeo_Log(SEOBEO_DEBUG, "[CURR], Hello\n"); | 463 Seobeo_Request_Entry *resp = NULL; |
| 455 Seobeo_Request_Entry *resp = NULL; | 464 |
| 456 | 465 char *file_path = Dowa_Arena_Allocate(arena, 1024); |
| 457 void *blog_id_kv = Dowa_HashMap_Get_Ptr(req, ":blog_id"); | 466 void *blog_id_kv = Dowa_HashMap_Get_Ptr(req, ":blog_id"); |
| 458 if (!blog_id_kv) | 467 char *blog_id = ((Seobeo_Request_Entry*)blog_id_kv)->value; |
| 459 { | 468 snprintf(file_path, 1024, "/blog/%s/index.html", blog_id); |
| 460 char *error_msg = "No Blog Id"; | 469 |
| 461 Dowa_HashMap_Push_Arena(resp, "status", "404", arena); | 470 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); |
| 462 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena); | 471 Seobeo_Render_Html_FilePath(final_body, file_path, arena); |
| 463 Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena); | |
| 464 return resp; | |
| 465 } | |
| 466 | |
| 467 const char *blog_id = ((Seobeo_Request_Entry *)blog_id_kv)->value; | |
| 468 char *html_path = Dowa_Arena_Allocate(arena, 512); | |
| 469 sprintf(html_path, "/blog/%s/index.html", blog_id); | |
| 470 | |
| 471 char *final_body = Dowa_Arena_Allocate(arena, 100 * 1024); // TODO: Think about the sizes | |
| 472 Seobeo_ServerSideRender(final_body, html_path, arena); | |
| 473 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); | 472 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); |
| 474 return resp; | 473 return resp; |
| 475 } | 474 } |
| 476 | 475 |
| 477 void Chat_Handler(Seobeo_WebSocket_Server_Connection *p_conn, Seobeo_WebSocket_Message *p_msg, void *p_user_data) | 476 void Chat_Handler(Seobeo_WebSocket_Server_Connection *p_conn, Seobeo_WebSocket_Message *p_msg, void *p_user_data) |
| 490 | 489 |
| 491 Seobeo_Request_Entry *GetTalk(Seobeo_Request_Entry *req, Dowa_Arena *arena) | 490 Seobeo_Request_Entry *GetTalk(Seobeo_Request_Entry *req, Dowa_Arena *arena) |
| 492 { | 491 { |
| 493 Seobeo_Request_Entry *resp = NULL; | 492 Seobeo_Request_Entry *resp = NULL; |
| 494 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); | 493 char *final_body = Dowa_Arena_Allocate(arena, 50 * 1024); |
| 495 Seobeo_ServerSideRender(final_body, "/talk/index.html", arena); | 494 Seobeo_Render_Html_FilePath(final_body, "/talk/index.html", arena); |
| 496 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); | 495 Dowa_HashMap_Push_Arena(resp, "body", final_body, arena); |
| 497 return resp; | 496 return resp; |
| 498 } | 497 } |
| 499 | 498 |
| 500 CREATE_REDIRECT_HANDLER(HomePage, "/") | 499 CREATE_REDIRECT_HANDLER(HomePage, "/") |
| 532 Seobeo_Router_Register("GET", "/blog", RenderBlogList); | 531 Seobeo_Router_Register("GET", "/blog", RenderBlogList); |
| 533 Seobeo_Router_Register("GET", "/blog/:blog_id", RenderBlog); | 532 Seobeo_Router_Register("GET", "/blog/:blog_id", RenderBlog); |
| 534 | 533 |
| 535 // -- Talk --/ | 534 // -- Talk --/ |
| 536 Seobeo_Router_Register("GET", "/talk", GetTalk); | 535 Seobeo_Router_Register("GET", "/talk", GetTalk); |
| 537 // TODO: Bug where I can't est redriect huh... | |
| 538 Seobeo_Router_Register("GET", "/talk/index.html", GetRedirectTalk); | 536 Seobeo_Router_Register("GET", "/talk/index.html", GetRedirectTalk); |
| 539 | |
| 540 printf("Registered Websockets\n"); | |
| 541 | 537 |
| 542 Seobeo_WebSocket_Server_Init(); | 538 Seobeo_WebSocket_Server_Init(); |
| 543 Seobeo_WebSocket_Server_Register("/chat", Chat_Handler, NULL); | 539 Seobeo_WebSocket_Server_Register("/chat", Chat_Handler, NULL); |
| 544 | 540 |
| 545 Seobeo_Web_Server_Start("mrjunejune/src", "6969", SEOBEO_MODE_EDGE, 3); | 541 Seobeo_Web_Server_Start("mrjunejune/src", "6969", SEOBEO_MODE_EDGE, 3); |