Correct multi-match behavior for queries and header values (#13017)

This commit is contained in:
JJ Kasper 2020-05-18 12:04:54 -05:00 committed by GitHub
parent dd264f582f
commit 97587eb8e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 2 deletions

View file

@ -482,7 +482,11 @@ export default class Server {
!parsedDestination.pathname ||
!parsedDestination.pathname.startsWith('/')
) {
return compilePathToRegex(value, { validate: false })(params)
// the value needs to start with a forward-slash to be compiled
// correctly
return compilePathToRegex(`/${value}`, { validate: false })(
params
).substr(1)
}
return formatUrl(parsedDestination)
}

View file

@ -58,8 +58,11 @@ export const prepareDestination = (
for (const [key, strOrArray] of Object.entries(destQuery)) {
let value = Array.isArray(strOrArray) ? strOrArray[0] : strOrArray
if (value) {
// the value needs to start with a forward-slash to be compiled
// correctly
value = `/${value}`
const queryCompiler = compilePathToRegex(value, { validate: false })
value = queryCompiler(params)
value = queryCompiler(params).substr(1)
}
destQuery[key] = value
}

View file

@ -91,6 +91,10 @@ module.exports = {
source: '/catchall-rewrite/:path*',
destination: '/with-params',
},
{
source: '/catchall-query/:path*',
destination: '/with-params?another=:path*',
},
]
},
async redirects() {
@ -283,6 +287,15 @@ module.exports = {
},
],
},
{
source: '/catchall-header/:path*',
headers: [
{
key: 'x-value',
value: ':path*',
},
],
},
]
},
},

View file

@ -178,6 +178,22 @@ const runTests = (isDev = false) => {
})
})
it('should have correct query for catchall rewrite', async () => {
const html = await renderViaHTTP(appPort, '/catchall-query/hello/world?a=b')
const $ = cheerio.load(html)
expect(JSON.parse($('#__NEXT_DATA__').html()).query).toEqual({
a: 'b',
another: 'hello/world',
path: ['hello', 'world'],
})
})
it('should have correct query for catchall rewrite', async () => {
const res = await fetchViaHTTP(appPort, '/catchall-header/hello/world?a=b')
const headerValue = res.headers.get('x-value')
expect(headerValue).toBe('hello/world')
})
it('should allow params in query for redirect', async () => {
const res = await fetchViaHTTP(
appPort,
@ -716,6 +732,18 @@ const runTests = (isDev = false) => {
regex: normalizeRegEx('^\\/named-pattern(?:\\/(.*))$'),
source: '/named-pattern/:path(.*)',
},
{
headers: [
{
key: 'x-value',
value: ':path*',
},
],
regex: normalizeRegEx(
'^\\/catchall-header(?:\\/((?:[^\\/]+?)(?:\\/(?:[^\\/]+?))*))?$'
),
source: '/catchall-header/:path*',
},
],
rewrites: [
{
@ -840,6 +868,13 @@ const runTests = (isDev = false) => {
),
source: '/catchall-rewrite/:path*',
},
{
destination: '/with-params?another=:path*',
regex: normalizeRegEx(
'^\\/catchall-query(?:\\/((?:[^\\/]+?)(?:\\/(?:[^\\/]+?))*))?$'
),
source: '/catchall-query/:path*',
},
],
dynamicRoutes: [
{