Skip to content

Commit

Permalink
Fix middleware rewrite for _next/data (vercel#41341)
Browse files Browse the repository at this point in the history
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 authored and Kikobeats committed Oct 24, 2022
1 parent 168999f commit e29d021
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 2 deletions.
8 changes: 8 additions & 0 deletions packages/next/server/next-server.ts
Expand Up @@ -1062,9 +1062,17 @@ export default class NextNodeServer extends BaseServer {
name: '_next/data catchall',
check: true,
fn: async (req, res, params, _parsedUrl) => {
const isNextDataNormalizing = getRequestMeta(
req,
'_nextDataNormalizing'
)

// Make sure to 404 for /_next/data/ itself and
// we also want to 404 if the buildId isn't correct
if (!params.path || params.path[0] !== this.buildId) {
if (isNextDataNormalizing) {
return { finished: false }
}
await this.render404(req, res, _parsedUrl)
return {
finished: true,
Expand Down
1 change: 1 addition & 0 deletions packages/next/server/request-meta.ts
Expand Up @@ -23,6 +23,7 @@ export interface RequestMeta {
_nextRewroteUrl?: string
_nextMiddlewareCookie?: string[]
_protocol?: string
_nextDataNormalizing?: boolean
}

export function getRequestMeta(
Expand Down
21 changes: 19 additions & 2 deletions packages/next/server/router.ts
Expand Up @@ -7,7 +7,11 @@ import type {
} from '../shared/lib/router/utils/route-matcher'
import type { RouteHas } from '../lib/load-custom-routes'

import { getNextInternalQuery, NextUrlWithParsedQuery } from './request-meta'
import {
addRequestMeta,
getNextInternalQuery,
NextUrlWithParsedQuery,
} from './request-meta'
import { getPathMatch } from '../shared/lib/router/utils/path-match'
import { removeTrailingSlash } from '../shared/lib/router/utils/remove-trailing-slash'
import { normalizeLocalePath } from '../shared/lib/i18n/normalize-locale-path'
Expand Down Expand Up @@ -189,7 +193,11 @@ export default class Router {
...(middlewareCatchAllRoute
? this.fsRoutes
.filter((route) => route.name === '_next/data catchall')
.map((route) => ({ ...route, check: false }))
.map((route) => ({
...route,
name: '_next/data normalizing',
check: false,
}))
: []),
...this.headers,
...this.redirects,
Expand Down Expand Up @@ -433,6 +441,11 @@ export default class Router {
}

if (params) {
const isNextDataNormalizing = route.name === '_next/data normalizing'

if (isNextDataNormalizing) {
addRequestMeta(req, '_nextDataNormalizing', true)
}
parsedUrlUpdated.pathname = matchPathname
const result = await route.fn(
req,
Expand All @@ -441,6 +454,10 @@ export default class Router {
parsedUrlUpdated,
upgradeHead
)

if (isNextDataNormalizing) {
addRequestMeta(req, '_nextDataNormalizing', false)
}
if (result.finished) {
return true
}
Expand Down
5 changes: 5 additions & 0 deletions test/e2e/middleware-rewrites/app/middleware.js
Expand Up @@ -13,6 +13,11 @@ 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: 17 additions & 0 deletions test/e2e/middleware-rewrites/test/index.test.ts
Expand Up @@ -23,6 +23,23 @@ 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

0 comments on commit e29d021

Please sign in to comment.