perf(backend): cache thumbnail, preview and content responses

These endpoints had no Cache-Control, so the browser re-downloaded every
thumbnail on each grid mount (the client fetches them with an auth header,
which also bypasses default image caching). Returning to the grid after
viewing a file re-fetched the whole visible page of thumbnails. Add
Cache-Control: private, max-age=3600. Content is immutable per file id from
the client's perspective (there is no replace-content UI); a future replace
flow should cache-bust via a versioned URL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 14:50:32 +03:00
parent 5b973cf534
commit ec96fced40
+3
View File
@@ -382,6 +382,7 @@ func (h *FileHandler) GetContent(c *gin.Context) {
defer res.Body.Close() defer res.Body.Close()
c.Header("Content-Type", res.MIMEType) c.Header("Content-Type", res.MIMEType)
c.Header("Cache-Control", "private, max-age=3600")
if res.OriginalName != nil { if res.OriginalName != nil {
c.Header("Content-Disposition", c.Header("Content-Disposition",
fmt.Sprintf("attachment; filename=%q", *res.OriginalName)) fmt.Sprintf("attachment; filename=%q", *res.OriginalName))
@@ -457,6 +458,7 @@ func (h *FileHandler) GetThumbnail(c *gin.Context) {
defer rc.Close() defer rc.Close()
c.Header("Content-Type", "image/jpeg") c.Header("Content-Type", "image/jpeg")
c.Header("Cache-Control", "private, max-age=3600")
c.Status(http.StatusOK) c.Status(http.StatusOK)
io.Copy(c.Writer, rc) //nolint:errcheck io.Copy(c.Writer, rc) //nolint:errcheck
} }
@@ -479,6 +481,7 @@ func (h *FileHandler) GetPreview(c *gin.Context) {
defer rc.Close() defer rc.Close()
c.Header("Content-Type", "image/jpeg") c.Header("Content-Type", "image/jpeg")
c.Header("Cache-Control", "private, max-age=3600")
c.Status(http.StatusOK) c.Status(http.StatusOK)
io.Copy(c.Writer, rc) //nolint:errcheck io.Copy(c.Writer, rc) //nolint:errcheck
} }