-
Notifications
You must be signed in to change notification settings - Fork 89
feat: add Next 13 request header mutation to middleware #1866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
2fe2570
1c22522
0aaa3ac
20f9464
52326fc
d322178
0912759
8f38808
23f9753
124d15b
4526461
93441ff
5355a44
ccfc06d
6e6152c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,6 +59,34 @@ function isMiddlewareResponse(response: Response | MiddlewareResponse): response | |
return 'dataTransforms' in response | ||
} | ||
|
||
// Next 13 supports request header mutations and has the side effect of prepending header values with 'x-middleware-request' | ||
// as part of invoking NextResponse.next() in the middleware. We need to remove that before sending the response the user | ||
// as the code that removes it in Next isn't run based on how we handle the middleware | ||
// | ||
// Related Next.js code: | ||
// * https://github.com/vercel/next.js/blob/68d06fe015b28d8f81da52ca107a5f4bd72ab37c/packages/next/server/next-server.ts#L1918-L1928 | ||
// * https://github.com/vercel/next.js/blob/43c9d8940dc42337dd2f7d66aa90e6abf952278e/packages/next/server/web/spec-extension/response.ts#L10-L27 | ||
export function updateModifiedHeaders(response: Response) { | ||
ascorbic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const overriddenHeaders = response.headers.get('x-middleware-override-headers') || '' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for the fallback if you're checking for falsiness right away |
||
|
||
if (!overriddenHeaders) { | ||
return response | ||
} | ||
|
||
const headersToUpdate = overriddenHeaders.split(',') | ||
|
||
for (const header of headersToUpdate) { | ||
const oldHeaderKey = 'x-middleware-request-' + header | ||
const headerValue = response.headers.get(oldHeaderKey) || '' | ||
|
||
response.headers.set(header, headerValue) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't want to set these in the response - it's the request that needs them, so we should be calling this before calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Would be happy to pair on this tomorrow though as there's likely more insight that you have that I'm missing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not setting them on the request though: https://deploy-preview-1866--next-plugin-edge-middleware.netlify.app/api/hello |
||
response.headers.delete(oldHeaderKey) | ||
} | ||
response.headers.delete('x-middleware-override-headers') | ||
|
||
return response | ||
} | ||
|
||
export const buildResponse = async ({ | ||
result, | ||
request, | ||
|
@@ -68,6 +96,8 @@ export const buildResponse = async ({ | |
request: Request | ||
context: Context | ||
}) => { | ||
result.response = updateModifiedHeaders(result.response) | ||
|
||
// They've returned the MiddlewareRequest directly, so we'll call `next()` for them. | ||
if (isMiddlewareRequest(result.response)) { | ||
result.response = await result.response.next() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const ElementHandlers = jest.fn() | ||
export const HTMLRewriter = jest.fn() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use
deno test
instead of Jest for EF stuffThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an example in the edge router PR: https://github.com/netlify/next-runtime/pull/1451/files#diff-c02e108e555d63f8e66ff0b099106e84ef940d69b5cb0e1d2c12b2f79c1f6322
There's a workflow for it in there too