fix(site): avoid duplicating bin download headers (#22981)

## Summary
- avoid duplicating preset headers when cachecompress serves compressed
`/bin/*` responses
- add a cachecompress regression test for preset
`X-Original-Content-Length` and `ETag` headers
- strengthen site binary tests to assert those headers stay
single-valued

## Problem
`site/bin.go` sets `X-Original-Content-Length` and `ETag` on the real
response writer before delegating.
`cachecompress` then snapshotted those headers and replayed them with
`Header().Add(...)`, which duplicated them on compressed responses.

For `coder-desktop-macos`, duplicate `X-Original-Content-Length` values
can collapse into a comma-separated string and fail `Int64` parsing,
causing the file size to show as `Unknown`.

## Testing
- `/usr/local/go/bin/go test ./coderd/cachecompress -run
'TestCompressorPresetHeaders|TestCompressorHeadings' -count=1`
- `/usr/local/go/bin/go test ./site -run TestServingBin -count=1`
- `PATH=/usr/local/go/bin:$PATH make lint/go`

## Notes
- Skipped full `make pre-commit` with explicit approval because local
environment/tooling blocked it (Node version/path interaction in
generated site targets, plus missing local tools before setup).
This commit is contained in:
Ethan
2026-03-13 00:22:55 +11:00
committed by GitHub
parent fd6346265c
commit 2b70122e4a
3 changed files with 39 additions and 4 deletions
+1 -3
View File
@@ -240,9 +240,7 @@ func (c *Compressor) serveRef(w http.ResponseWriter, r *http.Request, headers ht
}
for key, values := range headers {
for _, value := range values {
w.Header().Add(key, value)
}
w.Header()[key] = values
}
w.Header().Set("Content-Encoding", cref.key.encoding)
w.Header().Add("Vary", "Accept-Encoding")
@@ -155,6 +155,41 @@ type nopEncoder struct {
func (nopEncoder) Close() error { return nil }
func TestCompressorPresetHeaders(t *testing.T) {
t.Parallel()
logger := testutil.Logger(t)
tempDir := t.TempDir()
cacheDir := filepath.Join(tempDir, "cache")
err := os.MkdirAll(cacheDir, 0o700)
require.NoError(t, err)
srcDir := filepath.Join(tempDir, "src")
err = os.MkdirAll(srcDir, 0o700)
require.NoError(t, err)
err = os.WriteFile(filepath.Join(srcDir, "file.html"), []byte("textstring"), 0o600)
require.NoError(t, err)
compressor := NewCompressor(logger, 5, cacheDir, http.FS(os.DirFS(srcDir)))
for range 2 {
ctx := testutil.Context(t, testutil.WaitShort)
req := httptest.NewRequestWithContext(ctx, "GET", "/file.html", nil)
req.Header.Set("Accept-Encoding", "gzip")
respRec := httptest.NewRecorder()
respRec.Header().Set("X-Original-Content-Length", "10")
respRec.Header().Set("ETag", `"abc123"`)
compressor.ServeHTTP(respRec, req)
resp := respRec.Result()
require.Equal(t, http.StatusOK, resp.StatusCode)
require.Equal(t, []string{"10"}, resp.Header.Values("X-Original-Content-Length"))
require.Equal(t, []string{`"abc123"`}, resp.Header.Values("ETag"))
require.NoError(t, resp.Body.Close())
}
}
// nolint: tparallel // we want to assert the state of the cache, so run synchronously
func TestCompressorHeadings(t *testing.T) {
t.Parallel()