diff options
Diffstat (limited to 'internal/web/handlers_media.go')
| -rw-r--r-- | internal/web/handlers_media.go | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/internal/web/handlers_media.go b/internal/web/handlers_media.go index 7c4b739..99fdb64 100644 --- a/internal/web/handlers_media.go +++ b/internal/web/handlers_media.go @@ -4,6 +4,7 @@ import ( "errors" "io/fs" "net/http" + "strings" "github.com/google/uuid" "github.com/gramanas/blogspace/internal/store" @@ -38,9 +39,21 @@ func (s *Server) handleMedia(w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "public, max-age=31536000, immutable") w.Header().Set("ETag", etag) w.Header().Set("X-Content-Type-Options", "nosniff") + singleRangeOnly(r) http.ServeContent(w, r, f.Filename, f.CreatedAt, blogStore(r).FileReader(r.Context(), f)) } +// singleRangeOnly drops a multi-range request so the file is served whole. +// ServeContent honours any number of ranges and chunkReader caches one slice, +// so a header alternating between two chunks would cost a substring() query +// per range — tens of thousands per request. Browsers and download managers +// only ever ask for one range. +func singleRangeOnly(r *http.Request) { + if strings.Contains(r.Header.Get("Range"), ",") { + r.Header.Del("Range") + } +} + // handleFavicon answers the browsers that ask for /favicon.ico regardless of // the <link rel="icon"> tags: the blog's own icon if it set one, else the // Blogspace default. Without this the request would render the 404 page. |
