fix(cloudflare): return redirects from cache-facing fetches - #3242
JamesbbBriz wants to merge 2 commits into
Conversation
A fetch through the cache-enabled response entrypoint follows redirects by default. When a shared-cache render responds with a redirect, the runtime follows it and re-enters the entrypoint for the redirect target while the response-stage invocation still describes the original URL — so the redirect source re-renders and redirects again, until the runtime's redirect budget is exhausted (TypeError: Too many redirects). Observed on a Payload CMS app whose /admin route redirects unauthenticated visitors to /admin/login: every hop logged another /admin/login render performed with the original /admin invocation, and the page 500ed. Bisected to 35af791 (cloudflare#3168), which routes public traffic through the cache-fronted entrypoint. Set redirect: manual on the cache-facing request so redirect responses are returned to the caller, matching the pre-cloudflare#3168 gateway behavior.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
@vinext/cloudflare
create-vinext-app
@vinext/types
vinext
@cloudflare/workers-response-store
commit: |
Performance benchmarksCompared 0 improved · 0 regressed · 6 within ±1.5%
View detailed results and traces 🟢 improvement · 🔴 regression · ⚫ change below 1.5% · paired base/head |
|
/bigbonk review for issues Time limit: 8 minutes. Complete the review and post all findings within that limit. |
|
@james-elicx Bonk workflow was cancelled. View workflow run · To retry, trigger Bonk again. |
63b5e03 to
43f4ff4
Compare
43f4ff4 to
88cb127
Compare
|
/bigbonk review for issues Time limit: 8 minutes. Complete the review and post all findings within that limit. |
|
LGTM! |
Problem
Since #3168 (
35af7910), any shared-cache App or Pages render that responds with a redirect returns500 TypeError: Too many redirectsinstead of surfacing the redirect to the client.A Payload CMS
/adminroute exposed this: unauthenticated visitors should receive307 -> /admin/login, but the request instead exhausted the Workers redirect budget.Fixes #3243.
Root cause
createCacheFacingRequestintentionally constructs a freshRequestso browser cache-bypass state does not leak into the cache-enabled entrypoint. A fresh WorkersRequestdefaults toredirect: "follow", unlike the client-originated Worker request whose mode ismanual.When a response-stage render returns a redirect, following it re-enters the cache entrypoint for the destination while the configurable-entrypoint invocation still describes the original route. The original route renders and redirects again until workerd exhausts its redirect limit.
Cloudflare also documents that followed redirects forward request headers to the destination, including cross-origin destinations, so the cache-stage transport must treat a render redirect as its terminal response.
Fix
Set
redirect: "manual"on the single cache-facing request factory. This returns the 3xx response to the uncached gateway, preserves its status andLocation, and matches the pre-#3168 gateway behavior.The same factory serves both App and Pages shared response stages. Bypass/probe stages keep their direct request path.
Parity
Next.js document requests surface
redirect()as a 307. The runtime regression ports that invariant from:https://github.com/vercel/next.js/blob/canary/test/e2e/app-dir/rsc-redirect/rsc-redirect.test.ts
Validation
redirect()and a Pages RoutergetStaticPropsredirect, with client redirect following disabled.500 TypeError: Too many redirects, with 20 repeated destination hops.Location.vp test run tests/cloudflare-cdn-worker.test.ts: 60/60 passed.vp check: formatting, lint, and types passed.vp run @vinext/cloudflare#build: passed.