[Bug]: Compressed asset responses lose their Content-Type, so HTML previews render as plain text
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 84/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
Research direction
Start in apps/server/src/http.ts by reading httpCompressionLayer and assetResponseHeaders, then inspect the two related expectations in http.test.ts. Reproduce an asset request with and without Accept-Encoding and update the handling so compressed HTML, CSS, JS, and PDF responses retain their content type; the tests and browser response headers should confirm the fix.
Written by the indexing model from the issue text.
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server
Steps to reproduce
- Run the server from
mainat or after bd56e920b7 (the Effect rc.112 upgrade, #10652). Reproduced against a dev server from 7220dfe2c; the relevant code is unchanged onmainas of 6c583620ff. - Get a signed asset URL for an
.htmlworkspace file larger than 1 KiB (assets.createUrlwith aworkspace-fileresource, which is what opening an HTML file in the file viewer does) and request it the way a browser does:curl -sD - -o /dev/null -H 'Accept-Encoding: gzip, deflate, br, zstd' 'http://127.0.0.1:<port>/api/assets/<token>/page.html' - Request the same URL without
Accept-Encoding.
Expected behavior
Both responses carry content-type: text/html; charset=utf-8 and the sandbox CSP that assetResponseHeaders sets, and the browser renders the page.
Actual behavior
Step 2 answers 200 with content-encoding: br, x-content-type-options: nosniff and the CSP header, and no content-type at all. Step 3 answers with content-type: text/html; charset=utf-8. Because of nosniff, Chromium shows the HTML source as plain text, and a .css file served the same way is refused as a stylesheet. Images are unaffected (the middleware does not compress them) and so are bodies under 1 KiB.
The tracer records headers before the compression handler runs, so http.server GET spans still show text/html for a response that reached the client without a type.
Impact
Major degradation: every HTML, CSS, JS and PDF file the asset route serves to a browser that accepts compression, which is every browser.
Cause
httpCompressionLayer in apps/server/src/http.ts is Effect's HttpMiddleware.compression(). In effect 4.0.0-rc.112 the Node implementation rebuilds a file response around a body that carries no content type, and HttpServerResponse.setBody then strips the header. HttpServerResponse.text(..., { contentType }) survives because its body carries the type; HttpServerResponse.file puts the type in the headers only. Details, a minimal reproduction and a suggested fix are in the Effect issue: https://github.com/Effect-TS/effect/issues/8146
Workaround
Append no-transform to the asset Cache-Control value in assetResponseHeaders. The middleware honours the directive and asset responses go out uncompressed with their type. Two expectations in http.test.ts pin the exact header value and need the same change.
- Dominant language
- TypeScript
- Stars
- 23.2k
- Forks
- 5.9k
- Avg merge
- 10h 57m
- Merged PRs (30d)
- 365
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from pingdotgg/t3code
-
bug via-triage
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
accepted bug via-triage
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
-
accepted bug via-triage
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
-
accepted bug via-triage
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
All issues in pingdotgg/t3code
Similar issues
-
calcite-components needs triage refactor
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Esri/calcite-design-system#15203 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 91/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 95/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Automattic/studio#4908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 90/100