Commit Graph

1 Commits

Author SHA1 Message Date
James Anderson 24a1bd4edc fix(middleware): redirect protocol — relative Location and x-nextjs-redirect (#1377)
* fix(middleware): redirect protocol — relative Location and x-nextjs-redirect

Match Next.js's edge adapter behaviour for middleware redirects:

1. Relativize the `Location` header for same-host redirects. Next.js only
   emits absolute URLs when the redirect target is cross-origin; vinext
   was always emitting `http://host/path` for same-host targets, which
   broke deploy-suite parity tests.

2. Translate redirects to the `x-nextjs-redirect` soft-redirect protocol
   when the request carries `x-nextjs-data: 1`. The client router uses
   this header instead of a raw HTTP 3xx to avoid CORS issues on
   cross-origin data fetches.

Both fixes live in `executeMiddleware`, so all four call sites
(prod-server, dev plugin, deploy worker, app-middleware) inherit them.

Refs #1334

* fix(middleware): thread isDataRequest through all callers

Address Bonk review. The previous commit checked `x-nextjs-data` on the
middleware request, but that header is in INTERNAL_HEADERS and is
stripped by `filterInternalHeaders` before any caller constructs the
middleware request -- so the soft-redirect branch was unreachable.

Make `isDataRequest` an explicit option on `ExecuteMiddlewareOptions`
and `ApplyAppMiddlewareOptions`, and capture it from the raw incoming
headers in each of the four entry points (dev plugin, prod server,
deploy worker, App Router RSC handler) before filtering. The generated
Pages Router runMiddleware now accepts a third `options` argument
carrying the flag through to the runtime helper.

Also: drop redundant lowercase `headers.delete("location")` -- the
Fetch spec makes Headers.delete case-insensitive.

Add a regression test ensuring a forged `x-nextjs-data: 1` request
header cannot trigger the soft-redirect path without the caller
explicitly opting in.

Refs #1334
2026-05-21 11:34:52 +01:00