From e7b222bc7d0fd1c3ffe585d515443cce6d13866f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6sche?= Date: Sun, 25 Jan 2026 03:22:39 +0100 Subject: [PATCH] Force correct Content-Type for public files and add OPTIONS handlers for CORS --- go_cloud/internal/http/routes.go | 42 +++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/go_cloud/internal/http/routes.go b/go_cloud/internal/http/routes.go index 0a2c53b..f1f96eb 100644 --- a/go_cloud/internal/http/routes.go +++ b/go_cloud/internal/http/routes.go @@ -356,12 +356,30 @@ func NewRouter(cfg *config.Config, db *database.DB, jwtManager *jwt.Manager, aut r.Get("/share/{token}", func(w http.ResponseWriter, req *http.Request) { publicFileShareHandler(w, req, db, jwtManager) }) + r.Options("/share/{token}", func(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Range") + w.WriteHeader(http.StatusOK) + }) r.Get("/share/{token}/download", func(w http.ResponseWriter, req *http.Request) { publicFileDownloadHandler(w, req, db, cfg, jwtManager) }) + r.Options("/share/{token}/download", func(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Range") + w.WriteHeader(http.StatusOK) + }) r.Get("/share/{token}/view", func(w http.ResponseWriter, req *http.Request) { publicFileViewHandler(w, req, db, cfg, jwtManager) }) + r.Options("/share/{token}/view", func(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS") + w.Header().Set("Access-Control-Allow-Headers", "Range") + w.WriteHeader(http.StatusOK) + }) }) return r @@ -3062,15 +3080,15 @@ func publicFileDownloadHandler(w http.ResponseWriter, r *http.Request, db *datab w.Header().Set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Range") - // Copy headers from Nextcloud response + // Copy headers from Nextcloud response, but skip Content-Type to ensure correct MIME type for k, v := range resp.Header { - w.Header()[k] = v + if k != "Content-Type" { + w.Header()[k] = v + } } - // Ensure Content-Type is set - if w.Header().Get("Content-Type") == "" { - w.Header().Set("Content-Type", mimeType) - } + // Set correct Content-Type based on file extension + w.Header().Set("Content-Type", mimeType) // Ensure download behavior w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", file.Name)) @@ -3170,15 +3188,15 @@ func publicFileViewHandler(w http.ResponseWriter, r *http.Request, db *database. w.Header().Set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Range") - // Copy headers from Nextcloud response + // Copy headers from Nextcloud response, but skip Content-Type to ensure correct MIME type for k, v := range resp.Header { - w.Header()[k] = v + if k != "Content-Type" { + w.Header()[k] = v + } } - // Ensure Content-Type is set - if w.Header().Get("Content-Type") == "" { - w.Header().Set("Content-Type", mimeType) - } + // Set correct Content-Type based on file extension + w.Header().Set("Content-Type", mimeType) // Ensure inline viewing behavior (no Content-Disposition attachment) w.Header().Del("Content-Disposition")