mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-08 04:22:09 +00:00
<!-- Thanks for opening a PR! Your contribution is much appreciated. To make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below. Choose the right checklist for the change that you're making: --> This PR adds a feature in middleware to add, modify, or delete request headers. This feature is quite useful to pass data from middleware to Serverless/Edge API routes. ### New APIs Adds a new option `request.headers` to the `MiddlewareResponseInit` parameter in `NextResponse.next()` and `NextResponse.rewrite()`. It's a [`Header`](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object holding *all* request headers. Specifically: ```ts interface ExtraResponseInit extends ResponseInit { request?: { headers?: Headers } } ``` ### Example ```ts // api/hello.ts export default (req, res) => { const valueFromMiddleware = req.headers['x-hello-from-middleware'] return res.send(valueFromMiddleware) } // middleware.ts import { next } from '@vercel/edge' export default function middleware(request: NextRequest) { // Clone request headers const headers = new Headers(request.headers); // Add a new request header headers.set('x-hello-from-middleware', 'foo'); // Delete a request header from the client headers.delete('x-from-client'); return next({ request: { headers } }); } ``` ### New middleware headers - `x-middleware-override-headers`: A comma separated list of *all* request header names. Headers not listed will be deleted. - `x-middleware-request-<name>`: A new value for the header `<name>`. ### Related Issues - Next.js' implementation: https://github.com/vercel/next.js/pull/41380 ### 📋 Checklist <!-- Please keep your PR as a Draft until the checklist is complete --> #### Tests - [ ] The code changed/added as part of this PR has been covered with tests - [ ] All tests pass locally with `yarn test-unit` #### Code Review - [ ] This PR has a concise title and thorough description useful to a reviewer - [ ] Issue from task tracker has a link to this PR Co-authored-by: Gal Schlezinger <gal@spitfire.co.il>
98 lines
2.6 KiB
TypeScript
Vendored
98 lines
2.6 KiB
TypeScript
Vendored
/**
|
|
* @jest-environment @edge-runtime/jest-environment
|
|
*/
|
|
|
|
import { next, rewrite } from '../src/middleware-helpers';
|
|
|
|
describe('rewrite', () => {
|
|
test('receives custom headers', () => {
|
|
const resp = rewrite(new URL('https://example.vercel.sh/'), {
|
|
headers: {
|
|
'x-custom-header': 'custom-value',
|
|
},
|
|
});
|
|
expect({
|
|
status: resp.status,
|
|
headers: Object.fromEntries(resp.headers),
|
|
}).toMatchObject({
|
|
status: 200,
|
|
headers: {
|
|
'x-custom-header': 'custom-value',
|
|
'x-middleware-rewrite': 'https://example.vercel.sh/',
|
|
},
|
|
});
|
|
});
|
|
|
|
test('receives new request headers', () => {
|
|
const headers = new Headers();
|
|
headers.set('x-from-middleware1', 'hello1');
|
|
headers.set('x-from-middleware2', 'hello2');
|
|
const resp = rewrite(new URL('https://example.vercel.sh/'), {
|
|
headers: {
|
|
'x-custom-header': 'custom-value',
|
|
},
|
|
request: { headers },
|
|
});
|
|
expect({
|
|
status: resp.status,
|
|
headers: Object.fromEntries(resp.headers),
|
|
}).toMatchObject({
|
|
status: 200,
|
|
headers: {
|
|
'x-middleware-rewrite': 'https://example.vercel.sh/',
|
|
'x-custom-header': 'custom-value',
|
|
'x-middleware-override-headers':
|
|
'x-from-middleware1,x-from-middleware2',
|
|
'x-middleware-request-x-from-middleware2': 'hello2',
|
|
'x-middleware-request-x-from-middleware1': 'hello1',
|
|
},
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('next', () => {
|
|
test('receives custom headers', () => {
|
|
const resp = next({
|
|
headers: {
|
|
'x-custom-header': 'custom-value',
|
|
},
|
|
});
|
|
expect({
|
|
status: resp.status,
|
|
headers: Object.fromEntries(resp.headers),
|
|
}).toMatchObject({
|
|
status: 200,
|
|
headers: {
|
|
'x-custom-header': 'custom-value',
|
|
'x-middleware-next': '1',
|
|
},
|
|
});
|
|
});
|
|
|
|
test('receives new request headers', () => {
|
|
const headers = new Headers();
|
|
headers.set('x-from-middleware1', 'hello1');
|
|
headers.set('x-from-middleware2', 'hello2');
|
|
const resp = next({
|
|
headers: {
|
|
'x-custom-header': 'custom-value',
|
|
},
|
|
request: { headers },
|
|
});
|
|
expect({
|
|
status: resp.status,
|
|
headers: Object.fromEntries(resp.headers),
|
|
}).toMatchObject({
|
|
status: 200,
|
|
headers: {
|
|
'x-middleware-next': '1',
|
|
'x-custom-header': 'custom-value',
|
|
'x-middleware-override-headers':
|
|
'x-from-middleware1,x-from-middleware2',
|
|
'x-middleware-request-x-from-middleware2': 'hello2',
|
|
'x-middleware-request-x-from-middleware1': 'hello1',
|
|
},
|
|
});
|
|
});
|
|
});
|