Skip to content

Commit

Permalink
Fix middleware URL normalize case (#41342)
Browse files Browse the repository at this point in the history
Follow-up to #41341 this fixes a
related issue with the URL normalizing in middleware and updates the
regression tests.

x-ref: [slack
thread](https://vercel.slack.com/archives/C01224Q5M99/p1665161421775079?thread_ts=1664536480.045539&cid=C01224Q5M99)

## Bug

- [x] Related issues linked using `fixes #number`
- [x] Integration tests added
- [ ] Errors have a helpful link attached, see `contributing.md`
  • Loading branch information
ijjk committed Oct 11, 2022
1 parent c1de0c0 commit 7777130
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 33 deletions.
24 changes: 15 additions & 9 deletions packages/next/server/next-server.ts
Expand Up @@ -1724,15 +1724,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

const url = `${getRequestMeta(params.request, '_protocol')}://${
this.hostname
}:${this.port}${locale ? `/${locale}` : ''}${params.parsed.pathname}${
query ? `?${query}` : ''
}`
let url: string

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(
Expand Down
2 changes: 1 addition & 1 deletion packages/next/server/web/next-url.ts
Expand Up @@ -72,7 +72,7 @@ export class NextURL {
private analyzeUrl() {
const pathnameInfo = getNextPathnameInfo(this[Internal].url.pathname, {
nextConfig: this[Internal].options.nextConfig,
parseData: true,
parseData: !process.env.__NEXT_NO_MIDDLEWARE_URL_NORMALIZE,
})

this[Internal].domainLocale = detectDomainLocale(
Expand Down
5 changes: 0 additions & 5 deletions test/e2e/middleware-rewrites/app/middleware.js
Expand Up @@ -13,11 +13,6 @@ export async function middleware(request) {
return NextResponse.next()
}

if (url.pathname.startsWith('/_next/data/missing-id')) {
console.log(`missing-id rewrite: ${url.toString()}`)
return NextResponse.rewrite('https://example.vercel.sh')
}

if (url.pathname.includes('/to/some/404/path')) {
return NextResponse.next({
'x-matched-path': '/404',
Expand Down
17 changes: 0 additions & 17 deletions test/e2e/middleware-rewrites/test/index.test.ts
Expand Up @@ -23,23 +23,6 @@ describe('Middleware Rewrite', () => {
})

function tests() {
it('should allow rewriting invalid buildId correctly', async () => {
const res = await fetchViaHTTP(
next.url,
'/_next/data/missing-id/hello.json',
undefined,
{
headers: {
'x-nextjs-data': '1',
},
}
)
expect(res.status).toBe(200)
expect(await res.text()).toContain('Example Domain')
await check(() => next.cliOutput, /missing-id rewrite/)
expect(next.cliOutput).toContain('/_next/data/missing-id/hello.json')
})

it('should not have un-necessary data request on rewrite', async () => {
const browser = await webdriver(next.url, '/to-blog/first', {
waitHydration: false,
Expand Down
5 changes: 5 additions & 0 deletions test/e2e/skip-trailing-slash-redirect/app/middleware.js
@@ -1,6 +1,11 @@
import { NextResponse } from 'next/server'

export default function handler(req) {
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') {
return NextResponse.rewrite(new URL('/another/', req.nextUrl))
}
Expand Down
22 changes: 21 additions & 1 deletion test/e2e/skip-trailing-slash-redirect/index.test.ts
@@ -1,6 +1,6 @@
import { createNext, FileRef } from 'e2e-utils'
import { NextInstance } from 'test/lib/next-modes/base'
import { fetchViaHTTP } from 'next-test-utils'
import { check, fetchViaHTTP } from 'next-test-utils'
import { join } from 'path'
import webdriver from 'next-webdriver'

Expand All @@ -15,6 +15,26 @@ describe('skip-trailing-slash-redirect', () => {
})
afterAll(() => next.destroy())

it('should allow rewriting invalid buildId correctly', async () => {
const res = await fetchViaHTTP(
next.url,
'/_next/data/missing-id/hello.json',
undefined,
{
headers: {
'x-nextjs-data': '1',
},
}
)
expect(res.status).toBe(200)
expect(await res.text()).toContain('Example Domain')

if (!(global as any).isNextDeploy) {
await check(() => next.cliOutput, /missing-id rewrite/)
expect(next.cliOutput).toContain('/_next/data/missing-id/hello.json')
}
})

it('should allow response body from middleware with flag', async () => {
const res = await fetchViaHTTP(next.url, '/middleware-response-body')
expect(res.status).toBe(200)
Expand Down

0 comments on commit 7777130

Please sign in to comment.