comparison mrjunejune/main.c @ 263:ee04e4e69fed

Add functional JRPG frame and tools Add full-screen background_2 apertures, functional frame chrome, card-driven details, dual-window tools, live conversion workflows, and bounded cleanup for generated downloads. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <mrjunejune@users.noreply.github.com>
date Thu, 06 Aug 2026 11:31:30 -0700
parents 1f9877b637e9
children 04fee26ecce0
comparison
equal deleted inserted replaced
262:0f45474c1b1a 263:ee04e4e69fed
689 689
690 printf("DEBUG: Video converted, available at /api/download/%s\n", filename); 690 printf("DEBUG: Video converted, available at /api/download/%s\n", filename);
691 return resp; 691 return resp;
692 } 692 }
693 693
694 static boolean Converted_Filename_Is_Valid(const char *filename)
695 {
696 if (!filename)
697 return FALSE;
698 const char *extension = strrchr(filename, '.');
699 if (!extension || (strcmp(extension, ".webp") != 0 &&
700 strcmp(extension, ".mp4") != 0))
701 return FALSE;
702 if ((size_t)(extension - filename) != 36)
703 return FALSE;
704 for (size_t i = 0; i < 36; i++)
705 {
706 char value = filename[i];
707 if (i == 8 || i == 13 || i == 18 || i == 23)
708 {
709 if (value != '-')
710 return FALSE;
711 continue;
712 }
713 if (!((value >= '0' && value <= '9') ||
714 (value >= 'a' && value <= 'f') ||
715 (value >= 'A' && value <= 'F')))
716 return FALSE;
717 }
718 return TRUE;
719 }
720
721 static Seobeo_Request_Entry *Converted_File_Error(
722 Dowa_Arena *arena,
723 char *status,
724 char *message)
725 {
726 Seobeo_Request_Entry *resp = NULL;
727 Dowa_HashMap_Push_Arena(resp, "status", status, arena);
728 Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
729 Dowa_HashMap_Push_Arena(resp, "body", message, arena);
730 return resp;
731 }
732
733 Seobeo_Request_Entry *DeleteConvertedFile(
734 Seobeo_Request_Entry *req,
735 Dowa_Arena *arena)
736 {
737 void *filename_kv = Dowa_HashMap_Get_Ptr(req, ":filename");
738 const char *filename = filename_kv
739 ? ((Seobeo_Request_Entry *)filename_kv)->value
740 : NULL;
741 if (!Converted_Filename_Is_Valid(filename))
742 return Converted_File_Error(arena, "400", "Invalid converted filename");
743
744 char filepath[512];
745 snprintf(filepath, sizeof(filepath), "/tmp/%s", filename);
746 if (unlink(filepath) != 0 && errno != ENOENT)
747 return Converted_File_Error(arena, "500", "Unable to delete converted file");
748
749 Seobeo_Request_Entry *resp = NULL;
750 Dowa_HashMap_Push_Arena(resp, "status", "204", arena);
751 Dowa_HashMap_Push_Arena(resp, "body", "", arena);
752 return resp;
753 }
754
694 Seobeo_Request_Entry *DownloadConvertedFile(Seobeo_Request_Entry *req, Dowa_Arena *arena) 755 Seobeo_Request_Entry *DownloadConvertedFile(Seobeo_Request_Entry *req, Dowa_Arena *arena)
695 { 756 {
696 Seobeo_Request_Entry *resp = NULL; 757 Seobeo_Request_Entry *resp = NULL;
697 758
698 void *filename_kv = Dowa_HashMap_Get_Ptr(req, ":filename"); 759 void *filename_kv = Dowa_HashMap_Get_Ptr(req, ":filename");
704 Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena); 765 Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
705 return resp; 766 return resp;
706 } 767 }
707 768
708 const char *filename = ((Seobeo_Request_Entry*)filename_kv)->value; 769 const char *filename = ((Seobeo_Request_Entry*)filename_kv)->value;
709 770 if (!Converted_Filename_Is_Valid(filename))
710 // TODO: Maybe check if the uuid is allowed or not? 771 return Converted_File_Error(arena, "400", "Invalid converted filename");
711 // if (strlen(filename) != TMP_FILE_LENGTH)
712 // {
713 // char *error_msg = "Not Allowed Filename";
714 // Dowa_HashMap_Push_Arena(resp, "status", "404", arena);
715 // Dowa_HashMap_Push_Arena(resp, "content-type", "text/plain", arena);
716 // Dowa_HashMap_Push_Arena(resp, "body", error_msg, arena);
717 // return resp;
718 // }
719 // boolean allowed = FALSE;
720 // for (int i = 0; i < Dowa_Array_Length(g_uuid4_array); i++)
721 // {
722 // if strcmp(g_uuid4_array, filename)
723 // {
724 // allowed = TRUE;
725 // break;
726 // }
727 // g_uuid4_array++;
728 // }
729 772
730 char filepath[512]; 773 char filepath[512];
731 snprintf(filepath, sizeof(filepath), "/tmp/%s", filename); 774 snprintf(filepath, sizeof(filepath), "/tmp/%s", filename);
732 775
733 FILE *file = fopen(filepath, "rb"); 776 FILE *file = fopen(filepath, "rb");
757 800
758 fread(file_data, 1, file_size, file); 801 fread(file_data, 1, file_size, file);
759 file_data[file_size] = '\0'; 802 file_data[file_size] = '\0';
760 fclose(file); 803 fclose(file);
761 804
762 const char *content_type = "application/octet-stream"; 805 char *content_type = "application/octet-stream";
763 if (strstr(filename, ".webp")) 806 if (strcmp(strrchr(filename, '.'), ".webp") == 0)
764 content_type = "image/webp"; 807 content_type = "image/webp";
765 else if (strstr(filename, ".mp4")) 808 else if (strstr(filename, ".mp4"))
766 content_type = "video/mp4"; 809 content_type = "video/mp4";
767 810
768 char *body = Dowa_Arena_Allocate(arena, file_size + 1); 811 char *body = Dowa_Arena_Allocate(arena, file_size + 1);
2065 2108
2066 // -- File converter --/ 2109 // -- File converter --/
2067 Seobeo_Router_Register("POST", "/api/convert/image-to-webp", ConvertImageToWebP); 2110 Seobeo_Router_Register("POST", "/api/convert/image-to-webp", ConvertImageToWebP);
2068 Seobeo_Router_Register("POST", "/api/convert/video-to-mp4", ConvertVideoToMP4); 2111 Seobeo_Router_Register("POST", "/api/convert/video-to-mp4", ConvertVideoToMP4);
2069 Seobeo_Router_Register("GET", "/api/download/:filename", DownloadConvertedFile); 2112 Seobeo_Router_Register("GET", "/api/download/:filename", DownloadConvertedFile);
2113 Seobeo_Router_Register("DELETE", "/api/download/:filename", DeleteConvertedFile);
2070 Seobeo_Router_Register("POST", "/api/latex/render", RenderLatexPdf); 2114 Seobeo_Router_Register("POST", "/api/latex/render", RenderLatexPdf);
2071 2115
2072 // -- S3 Upload --/ 2116 // -- S3 Upload --/
2073 Seobeo_Router_Register("POST", "/api/s3/upload-url", GetS3UploadUrl); 2117 Seobeo_Router_Register("POST", "/api/s3/upload-url", GetS3UploadUrl);
2074 2118