diff options
| author | grm <grm@eyesin.space> | 2026-09-18 13:45:16 +0300 |
|---|---|---|
| committer | grm <grm@eyesin.space> | 2026-09-18 13:45:16 +0300 |
| commit | 90578f02d851ab4e28a066404fbcf4be6a0ed9a7 (patch) | |
| tree | d8e5f5fea70c0e8f11a93eebaa3d3add79b6c14a /internal/web/web_test.go | |
| parent | 19353a51c869f4b24ef2253d856084b6e6728048 (diff) | |
| download | blogspace-90578f02d851ab4e28a066404fbcf4be6a0ed9a7.tar.gz blogspace-90578f02d851ab4e28a066404fbcf4be6a0ed9a7.tar.bz2 blogspace-90578f02d851ab4e28a066404fbcf4be6a0ed9a7.zip | |
Security: Serve /media single-range only
http.ServeContent honours any number of comma-separated ranges and
chunkReader caches one 512 KiB slice, so a Range header alternating
between two chunks costs a substring() query per range: one 1 MB header
could make Postgres read tens of gigabytes for a single anonymous
request. Browsers and download managers only ever send one range, so a
multi-range header is dropped and the file served whole.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Sd8UPWrvyYCLj97JexNw3A
Diffstat (limited to 'internal/web/web_test.go')
| -rw-r--r-- | internal/web/web_test.go | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/internal/web/web_test.go b/internal/web/web_test.go index fc38536..1d4db4c 100644 --- a/internal/web/web_test.go +++ b/internal/web/web_test.go @@ -907,3 +907,16 @@ func TestImagePickKeepsOlderChoice(t *testing.T) { } } } + +func TestSingleRangeOnly(t *testing.T) { + for in, want := range map[string]string{"bytes=0-9": "bytes=0-9", "bytes=0-0,1-1": "", "": ""} { + req := httptest.NewRequest("GET", "/media/x", nil) + if in != "" { + req.Header.Set("Range", in) + } + singleRangeOnly(req) + if got := req.Header.Get("Range"); got != want { + t.Errorf("Range %q: kept %q, want %q", in, got, want) + } + } +} |
