From 858b277c9d05316b045bf711fb1481955712ab87 Mon Sep 17 00:00:00 2001 From: FahdShalhoub Date: Wed, 26 Aug 2026 18:45:32 +0300 Subject: [PATCH] FIX: Checked If File Exists Before Submitting Queue Job --- cms/internal/handlers/videos.go | 23 +++++++++-------------- cms/internal/services/s3.go | 10 +++------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/cms/internal/handlers/videos.go b/cms/internal/handlers/videos.go index c2d295f..8c2884c 100644 --- a/cms/internal/handlers/videos.go +++ b/cms/internal/handlers/videos.go @@ -10,7 +10,6 @@ import ( "net/http" "path/filepath" "slices" - "strconv" "strings" "thamanyah/cms/v2/internal/api" "thamanyah/cms/v2/internal/db/repositories" @@ -21,7 +20,7 @@ import ( const ( videoUploadPrefix = "videos" - uploadURLExpiry = 15 * time.Minute + uploadURLExpiry = 60 * time.Minute maxJSONBodySize = 1 << 20 // 1 MiB ) @@ -92,7 +91,7 @@ func PresignVideoUpload(w http.ResponseWriter, r *http.Request) { } key := videoUploadPrefix + "/" + filename - presignedURL, err := services.S3Client.GetPresignedURL(r.Context(), key, req.ContentType, time.Hour) + presignedURL, err := services.S3Client.GetPresignedURL(r.Context(), key, req.ContentType, uploadURLExpiry) if err != nil { writeProblem(w, http.StatusInternalServerError, "Could not prepare upload.", "A presigned upload URL could not be issued for the storage bucket. This is a server-side fault; no upload slot was reserved, so retry the request.") @@ -145,6 +144,13 @@ func CompleteVideoUpload(w http.ResponseWriter, r *http.Request) { return } + exists := services.S3Client.DoesFileExist(r.Context(), key) + if exists { + writeProblem(w, http.StatusUnprocessableEntity, "Failed to find video in storage", + "The video file that was supposed to be uploaded via the url sent in the PresignVideoUpload endpoint was not uploaded before calling this endpoint") + return + } + err := validateCatagoryIDS(r.Context(), req.CategoryIDs) if err != nil { log.Printf("Something Went Wrong Loading Categories: %s", err) @@ -210,17 +216,6 @@ func validateCatagoryIDS(ctx context.Context, submitted []int16) (err error) { return nil } -func formatCategoryIDs(ids []int16) string { - formatted := make([]string, 0, len(ids)) - for _, id := range ids { - formatted = append(formatted, strconv.Itoa(int(id))) - } - if len(formatted) == 1 { - return "id " + formatted[0] - } - return "ids " + strings.Join(formatted, ", ") -} - func randomFilename(original string) (string, error) { ext := filepath.Ext(filepath.Base(original)) buf := make([]byte, 16) diff --git a/cms/internal/services/s3.go b/cms/internal/services/s3.go index 7f8f67b..bbb4dc9 100644 --- a/cms/internal/services/s3.go +++ b/cms/internal/services/s3.go @@ -14,7 +14,7 @@ var S3Client S3 type S3 interface { GetPresignedURL(ctx context.Context, key, contentType string, expiry time.Duration) (string, error) - DoesFileExist(ctx context.Context, key string) (bool, error) + DoesFileExist(ctx context.Context, key string) bool } type S3Concrete struct { @@ -37,17 +37,13 @@ func (svc S3Concrete) GetPresignedURL(ctx context.Context, key, contentType stri return request.URL, nil } -func (svc S3Concrete) DoesFileExist(ctx context.Context, key string) (bool, error) { +func (svc S3Concrete) DoesFileExist(ctx context.Context, key string) bool { _, error := svc.S3Client.HeadObject(ctx, &s3.HeadObjectInput{ Bucket: &svc.Bucket, Key: &key, }) - if error != nil { - return false, error - } - - return true, nil + return error != nil } // AssertSuccessfulConnection verifies that the bucket is reachable and that