Skip to content

Commit

Permalink
Fix encoding error with location and refresh headers (vercel#33763)
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>



## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`
  • Loading branch information
timneutkens authored and natew committed Feb 16, 2022
1 parent c727f96 commit 4481a6b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
18 changes: 14 additions & 4 deletions packages/next/server/server-route-utils.ts
Expand Up @@ -140,15 +140,25 @@ 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)) {
if (
value in initialQuery ||
initialQueryValues.some((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
})
) {
// 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 4481a6b

Please sign in to comment.