Skip to content

Commit

Permalink
Fix encoding error with location and refresh headers
Browse files Browse the repository at this point in the history
Fixes the merge conflicts in vercel#27003

Fixes vercel#24977
Fixes vercel#24047
Closes vercel#27003

Co-Authored-By: Jamie <5964236+jamsinclair@users.noreply.github.com>
  • Loading branch information
timneutkens and jamsinclair committed Jan 28, 2022
1 parent 5ebc6d0 commit 8ff428b
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 4 deletions.
20 changes: 16 additions & 4 deletions packages/next/server/server-route-utils.ts
Expand Up @@ -140,15 +140,27 @@ export const createRedirectRoute = ({
// we need to re-encode them here but still allow passing through
// values from rewrites/redirects
export const stringifyQuery = (req: BaseNextRequest, query: ParsedUrlQuery) => {
const initialQueryValues = Object.values(
getRequestMeta(req, '__NEXT_INIT_QUERY') || {}
)
const initialQuery = getRequestMeta(req, '__NEXT_INIT_QUERY') || {}
const initialQueryValues: Array<string | string[]> =
Object.values(initialQuery)

return stringifyQs(query, undefined, undefined, {
encodeURIComponent(value) {
if (initialQueryValues.some((val) => val === value)) {
const queryContainsValue = (initialQueryVal: string | string[]) => {
// `value` always refers to a query value, even if it's nested in an array
return Array.isArray(initialQueryVal)
? initialQueryVal.includes(value)
: initialQueryVal === value
}

if (
value in initialQuery ||
initialQueryValues.some(queryContainsValue)
) {
// Encode keys and values from initial query
return encodeURIComponent(value)
}

return value
},
})
Expand Down
20 changes: 20 additions & 0 deletions test/integration/custom-routes/test/index.test.js
Expand Up @@ -690,6 +690,26 @@ const runTests = (isDev = false) => {
expect(res.headers.get('refresh')).toBe(`0;url=/`)
})

it('should have correctly encoded query in location and refresh headers', async () => {
const res = await fetchViaHTTP(
appPort,
// Query unencoded is ?テスト=あ
'/redirect4?%E3%83%86%E3%82%B9%E3%83%88=%E3%81%82',
undefined,
{
redirect: 'manual',
}
)
expect(res.status).toBe(308)

expect(res.headers.get('location').split('?')[1]).toBe(
'%E3%83%86%E3%82%B9%E3%83%88=%E3%81%82'
)
expect(res.headers.get('refresh')).toBe(
'0;url=/?%E3%83%86%E3%82%B9%E3%83%88=%E3%81%82'
)
})

it('should handle basic api rewrite successfully', async () => {
const data = await renderViaHTTP(appPort, '/api-hello')
expect(JSON.parse(data)).toEqual({ query: {} })
Expand Down

0 comments on commit 8ff428b

Please sign in to comment.