From a1d156bbd57bb5570a0d152e48d9daa2970dfb2d Mon Sep 17 00:00:00 2001 From: James Date: Thu, 12 Feb 2026 17:50:12 -0500 Subject: [PATCH] Fix download: serve file manually to avoid http.ServeFile header conflicts --- main.go | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/main.go b/main.go index 762a714..001cacf 100644 --- a/main.go +++ b/main.go @@ -277,36 +277,40 @@ func servePDF(w http.ResponseWriter, r *http.Request) { hash := chi.URLParam(r, "hash") download := r.URL.Query().Get("download") == "1" - // Try PDF first, then TXT - for _, ext := range []string{".pdf", ".txt"} { + // Try PDF first, then TXT, then bare + for _, ext := range []string{".pdf", ".txt", ""} { path := filepath.Join(storeDir, hash+ext) - if _, err := os.Stat(path); err == nil { - if ext == ".pdf" { - w.Header().Set("Content-Type", "application/pdf") - } else { - w.Header().Set("Content-Type", "text/plain") - } - if download { - filename := hash + ext - if doc, err := GetDocument(hash); err == nil && doc.Title != "" { - filename = sanitizeFilename(doc.Title) + ext - } - w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filename)) - } - http.ServeFile(w, r, path) - return + fi, err := os.Stat(path) + if err != nil { + continue } - } - // Try without extension - path := filepath.Join(storeDir, hash) - if _, err := os.Stat(path); err == nil { if download { - filename := hash + filename := hash + ext if doc, err := GetDocument(hash); err == nil && doc.Title != "" { filename = sanitizeFilename(doc.Title) + if ext != "" && !strings.HasSuffix(strings.ToLower(filename), ext) { + filename += ext + } } + f, err := os.Open(path) + if err != nil { + http.Error(w, "Cannot read file", http.StatusInternalServerError) + return + } + defer f.Close() + w.Header().Set("Content-Type", "application/octet-stream") w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, filename)) + w.Header().Set("Content-Length", fmt.Sprintf("%d", fi.Size())) + io.Copy(w, f) + return + } + + // Inline viewing + if ext == ".pdf" || ext == "" { + w.Header().Set("Content-Type", "application/pdf") + } else { + w.Header().Set("Content-Type", "text/plain") } http.ServeFile(w, r, path) return