fix(static): compressed public assets never actually served (only bundled) - #4501
fix(static): compressed public assets never actually served (only bundled)#4501lxtzfr wants to merge 1 commit into
Conversation
… is found
The inner loop's break only exited the innermost for-of, so after finding
a matching compressed asset (e.g. .br or .gz) the outer loop kept iterating
and re-checked the next encoding candidate — which always includes the
empty (uncompressed) suffix last. That uncompressed variant always exists
too, so it silently overwrote `asset`, meaning compressPublicAssets-built
.gz/.br files were generated but never actually served, regardless of the
client's Accept-Encoding header.
Repro: build with compressPublicAssets: { gzip: true, brotli: true }, then
request any public asset with `Accept-Encoding: gzip` — the response is
always the full uncompressed size with no Content-Encoding header.
|
@lxtzfr is attempting to deploy a commit to the Nitro Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe static asset lookup now exits both nested encoding and path loops after it finds a matching asset. ChangesAsset lookup
Estimated code review effort: 1 (Trivial) | ~5 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Closing — I mis-tested this. My repro was contaminated by a stale local dev-server process that was serving an older, actually-broken build; once properly killed and re-tested cleanly, the current code on |
Summary
compressPublicAssetscorrectly generates.gz/.br/.zstsibling files at build time, and the manifest correctly records theirencoding.runtime/internal/static.ts's encoding-negotiation loop has a bug: thebreakinside the innerforonly exits that inner loop, not the outerfor (const encoding of encodings)loop. Sinceencodingsalways ends with""(the uncompressed variant, which always exists), the outer loop keeps going after finding a compressed match and the uncompressed asset silently overwritesasseton the last iteration.Accept-Encoding, silently (no error,Vary: Accept-Encodingheader still present, just always the wrong body).Repro
Build, then:
curl -sD - -H "Accept-Encoding: gzip, br" http://localhost:3000/some-large-asset.css -o /dev/nullResponse is always the full uncompressed
Content-Length, with noContent-Encodingheader.Fix
Label the outer loop and break out of both loops once a match is found, instead of only the inner one. One-line change, verified locally (built, confirmed
Content-Encoding: br+ correct compressedContent-Lengthafter the fix, both missing before it).