Repository navigation
fix(cloudflare): do not let browsers cache a 404 from public assets - #4727
Conversation
The _headers rule of a public assets base also applies to a missing file returned by env.ASSETS.fetch(). Answer such a 404 with cache-control: no-store. Signed-off-by: Charan Rathore <[email protected]>
|
@charan-rathore is attempting to deploy a commit to the Nitro Team on Vercel. A member of the Team first needs to authorize it. |
|
Important Review skippedReview was skipped as selected files did not have any reviewable changes. ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
| Check name | Status | Explanation |
|---|---|---|
| Title check | ✅ Passed | The title follows the Conventional Commits format with type fix, scope cloudflare, and a description that matches the change. |
| Description check | ✅ Passed | The description explains the Cloudflare public-asset 404 cache issue, the fix, and the test coverage. |
| Linked Issues check | ✅ Passed | Issue #4648 requires cloudflare-module to prevent a 404 from a public asset from retaining a long-lived cache policy. The fetch handler now detects 404 responses with positive max-age or `immutabl… |
| Out of Scope Changes check | ✅ Passed | The changes are limited to the cloudflare-module asset response and a test for that behavior. Both changes directly support issue #4648. The PR does not change the unverified cloudflare-pages beha… |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2… |
✨ Finishing Touches 💡 1
-
🛠️ Fix failing CI checks 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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 @coderabbitai help to get the list of available commands.
commit: |
🔗 Linked issue
Resolves #4648
❓ Type of change
📚 Description
For a public assets base with
maxAge(Nuxt's/_nuxt/is one), nitro writes a_headersrule withcache-control: public, max-age=<maxAge>, immutable. Thecloudflare-moduleentry hands every path under such a base toenv.ASSETS.fetch()and returns the result as it is. Cloudflare's asset layer applies the_headersrule to a 404 as well, so a missing file comes back as404with the one year immutable header. A 404 with an explicitmax-ageis cacheable, so the browser keeps "this file does not exist" until the user does a hard reload. This is theFailed to fetch dynamically imported modulecase described in #4648. Because the entry answers before h3 runs, route rules and server middleware cannot change it.This PR changes
src/presets/cloudflare/runtime/cloudflare-module.ts. Whenenv.ASSETS.fetch()returns a 404 whosecache-controlhas a positivemax-ageorimmutable, the entry returns a copy of the response withcache-control: no-store. Successful asset responses and 404s without a long lived cache policy are passed through untouched.Test:
test/presets/cloudflare-module.test.tsruns the built fixture in Miniflare with theASSETSbinding. It requests an existing file under the fixture's/buildbase (expects 200 andmax-age=3600) and a missing one (expects 404 andno-store). The missing file case fails onmainwithpublic, max-age=3600, immutableand passes with this change.What I ran:
pnpm fmt,pnpm lintandpnpm typecheck: clean.vitest run test/presets/cloudflare-module.test.ts test/presets/cloudflare-pages.test.ts test/unit: 601 passed, 1 failed. The failure isvirtual-routing.test.ts > node format handler interop > receives the real Request when registered as a fetch object, and it fails the same way on an untouchedmain.What I did not run: a real Cloudflare deployment or
wrangler devwith a Nuxt app. The fullpnpm testpipeline was not run.📝 Checklist