Skip to content

Commit

Permalink
Strip internal routing headers (#55114)
Browse files Browse the repository at this point in the history
This strips the internal routing headers added by the routing server. Based on some of the changes being introduced in #54813 this strips the headers, but this also adds some internal flags to turn this off during testing to validate correct routing beheviour.
  • Loading branch information
wyattjoh authored Sep 7, 2023
1 parent 7267538 commit 2b514ea
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 1 deletion.
27 changes: 27 additions & 0 deletions packages/next/src/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ import {
} from './web/spec-extension/adapters/next-request'
import { matchNextDataPathname } from './lib/match-next-data-pathname'
import getRouteFromAssetPath from '../shared/lib/router/utils/get-route-from-asset-path'
import { stripInternalHeaders } from './internal-utils'

export type FindComponentsResult = {
components: LoadComponentsReturnType
Expand Down Expand Up @@ -1538,6 +1539,28 @@ export default abstract class Server<ServerOptions extends Options = Options> {
)
}

protected stripInternalHeaders(req: BaseNextRequest): void {
// Skip stripping internal headers in test mode while the header stripping
// has been explicitly disabled. This allows tests to verify internal
// routing behavior.
if (
process.env.__NEXT_TEST_MODE &&
process.env.__NEXT_NO_STRIP_INTERNAL_HEADERS === '1'
) {
return
}

// Strip the internal headers from both the request and the original
// request.
stripInternalHeaders(req.headers)
if (
'originalRequest' in req &&
'headers' in (req as NodeNextRequest).originalRequest
) {
stripInternalHeaders((req as NodeNextRequest).originalRequest.headers)
}
}

private async renderToResponseWithComponentsImpl(
{ req, res, pathname, renderOpts: opts }: RequestContext,
{ components, query }: FindComponentsResult
Expand All @@ -1546,6 +1569,10 @@ export default abstract class Server<ServerOptions extends Options = Options> {
// For edge runtime 404 page, /_not-found needs to be treated as 404 page
(process.env.NEXT_RUNTIME === 'edge' && pathname === '/_not-found') ||
pathname === '/404'

// Strip the internal headers.
this.stripInternalHeaders(req)

const is500Page = pathname === '/500'
const isAppPath = components.isAppPath
const hasServerProps = !!components.getServerSideProps
Expand Down
28 changes: 27 additions & 1 deletion packages/next/src/server/internal-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { NEXT_RSC_UNION_QUERY } from '../client/components/app-router-headers'
import type { IncomingHttpHeaders } from 'http'
import type { NextParsedUrlQuery } from './request-meta'

import { NEXT_RSC_UNION_QUERY } from '../client/components/app-router-headers'

const INTERNAL_QUERY_NAMES = [
'__nextFallback',
'__nextLocale',
Expand Down Expand Up @@ -36,3 +38,27 @@ export function stripInternalSearchParams<T extends string | URL>(

return (isStringUrl ? instance.toString() : instance) as T
}

/**
* Headers that are set by the Next.js server and should be stripped from the
* request headers going to the user's application.
*/
const INTERNAL_HEADERS = [
'x-invoke-path',
'x-invoke-status',
'x-invoke-error',
'x-invoke-query',
'x-invoke-output',
'x-middleware-invoke',
] as const

/**
* Strip internal headers from the request headers.
*
* @param headers the headers to strip of internal headers
*/
export function stripInternalHeaders(headers: IncomingHttpHeaders) {
for (const key of INTERNAL_HEADERS) {
delete headers[key]
}
}
3 changes: 3 additions & 0 deletions packages/next/src/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1585,6 +1585,9 @@ export default class NextNodeServer extends BaseServer {
ReturnType<typeof NextNodeServer.prototype.runMiddleware>
>

// Strip the internal headers.
this.stripInternalHeaders(req)

try {
await this.ensureMiddleware()

Expand Down
4 changes: 4 additions & 0 deletions test/e2e/i18n-data-route/i18n-data-route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ createNextDescribe(
'i18n-data-route',
{
files: __dirname,
env: {
// Disable internal header stripping so we can test the invoke output.
__NEXT_NO_STRIP_INTERNAL_HEADERS: '1',
},
},
({ next }) => {
describe('with locale prefix', () => {
Expand Down

0 comments on commit 2b514ea

Please sign in to comment.