From b9c74083b1ac6ebc0caf01faf3a89bf8c5453aa3 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 8 Nov 2022 09:57:21 -0800 Subject: [PATCH] Apply normalize patch --- packages/next/build/index.ts | 3 +++ packages/next/server/next-server.ts | 21 ++++++++++++------- .../app/middleware.js | 13 ++++++++++-- .../index.test.ts | 19 +++++++++++++++-- 4 files changed, 45 insertions(+), 11 deletions(-) diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 898072e333e3d..d9778b94e950a 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -695,6 +695,7 @@ export default async function build( defaultLocale: string localeDetection?: false } + skipMiddlewareUrlNormalize?: boolean } = nextBuildSpan.traceChild('generate-routes-manifest').traceFn(() => { const sortedRoutes = getSortedRoutes([ ...pageKeys.pages, @@ -721,6 +722,8 @@ export default async function build( staticRoutes, dataRoutes: [], i18n: config.i18n || undefined, + skipMiddlewareUrlNormalize: + config.experimental.skipMiddlewareUrlNormalize, } }) diff --git a/packages/next/server/next-server.ts b/packages/next/server/next-server.ts index c70db3599b317..f90d96dd3185b 100644 --- a/packages/next/server/next-server.ts +++ b/packages/next/server/next-server.ts @@ -1714,14 +1714,21 @@ export default class NextNodeServer extends BaseServer { const normalizedPathname = removeTrailingSlash(params.parsed.pathname || '') // For middleware to "fetch" we must always provide an absolute URL - const query = urlQueryToSearchParams(params.parsed.query).toString() - const locale = params.parsed.query.__nextLocale + let url: string - const url = `${getRequestMeta(params.request, '_protocol')}://${ - this.hostname - }:${this.port}${locale ? `/${locale}` : ''}${params.parsed.pathname}${ - query ? `?${query}` : '' - }` + if (this.nextConfig.experimental.skipMiddlewareUrlNormalize) { + url = getRequestMeta(params.request, '__NEXT_INIT_URL')! + } else { + // For middleware to "fetch" we must always provide an absolute URL + const query = urlQueryToSearchParams(params.parsed.query).toString() + const locale = params.parsed.query.__nextLocale + + url = `${getRequestMeta(params.request, '_protocol')}://${ + this.hostname + }:${this.port}${locale ? `/${locale}` : ''}${params.parsed.pathname}${ + query ? `?${query}` : '' + }` + } if (!url.startsWith('http')) { throw new Error( diff --git a/test/e2e/skip-trailing-slash-redirect/app/middleware.js b/test/e2e/skip-trailing-slash-redirect/app/middleware.js index a92b36d5f3987..bc28d0ae4770c 100644 --- a/test/e2e/skip-trailing-slash-redirect/app/middleware.js +++ b/test/e2e/skip-trailing-slash-redirect/app/middleware.js @@ -1,16 +1,25 @@ import { NextResponse } from 'next/server' export default function handler(req) { + console.log(req.nextUrl) + if (req.nextUrl.pathname.startsWith('/_next/data/missing-id')) { console.log(`missing-id rewrite: ${req.nextUrl.toString()}`) return NextResponse.rewrite('https://example.vercel.sh') } - if (req.nextUrl.pathname === '/middleware-rewrite-with-slash') { + if ( + req.nextUrl.pathname.startsWith('/_next/data') && + req.nextUrl.pathname.endsWith('valid.json') + ) { + return NextResponse.rewrite('https://example.vercel.sh') + } + + if (req.nextUrl.pathname.includes('/middleware-rewrite-with-slash')) { return NextResponse.rewrite(new URL('/another/', req.nextUrl)) } - if (req.nextUrl.pathname === '/middleware-rewrite-without-slash') { + if (req.nextUrl.pathname.includes('/middleware-rewrite-without-slash')) { return NextResponse.rewrite(new URL('/another', req.nextUrl)) } diff --git a/test/e2e/skip-trailing-slash-redirect/index.test.ts b/test/e2e/skip-trailing-slash-redirect/index.test.ts index 76b54feb80fd3..e31d7a6909fc6 100644 --- a/test/e2e/skip-trailing-slash-redirect/index.test.ts +++ b/test/e2e/skip-trailing-slash-redirect/index.test.ts @@ -35,6 +35,21 @@ describe('skip-trailing-slash-redirect', () => { } }) + it('should provide original _next/data URL with skipMiddlewareUrlNormalize', async () => { + const res = await fetchViaHTTP( + next.url, + `/_next/data/${next.buildId}/valid.json`, + undefined, + { + headers: { + 'x-nextjs-data': '1', + }, + } + ) + expect(res.status).toBe(200) + expect(await res.text()).toContain('Example Domain') + }) + it('should allow response body from middleware with flag', async () => { const res = await fetchViaHTTP(next.url, '/middleware-response-body') expect(res.status).toBe(200) @@ -88,7 +103,7 @@ describe('skip-trailing-slash-redirect', () => { it('should correct skip URL normalizing in middleware', async () => { let res = await fetchViaHTTP( next.url, - '/middleware-rewrite-with-slash', + `/_next/data/${next.buildId}/middleware-rewrite-with-slash.json`, undefined, { redirect: 'manual', headers: { 'x-nextjs-data': '1' } } ) @@ -96,7 +111,7 @@ describe('skip-trailing-slash-redirect', () => { res = await fetchViaHTTP( next.url, - '/middleware-rewrite-without-slash', + `/_next/data/${next.buildId}/middleware-rewrite-without-slash.json`, undefined, { redirect: 'manual', headers: { 'x-nextjs-data': '1' } } )