Skip to content

Commit 9f42311

Browse files
authored
fix: produce relative redirect location url for same origin (#3129)
1 parent c29381e commit 9f42311

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

edge-runtime/lib/response.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ export const buildResponse = async ({
210210
logger.withFields({ redirect_url: redirect }).debug('Redirect url is same as original url')
211211
return
212212
}
213-
edgeResponse.headers.set('location', redirect)
213+
edgeResponse.headers.set('location', relativizeURL(redirect, request.url))
214214
}
215215

216216
// Data requests shouldn't automatically redirect in the browser (they might be HTML pages): they're handled by the router

edge-runtime/lib/util.test.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { assertEquals } from 'https://deno.land/std@0.175.0/testing/asserts.ts'
2-
import { rewriteDataPath } from './util.ts'
2+
import { relativizeURL, rewriteDataPath } from './util.ts'
33

44
Deno.test('rewriteDataPath', async (t) => {
55
await t.step('should rewrite a data url', async () => {
@@ -37,3 +37,26 @@ Deno.test('rewriteDataPath', async (t) => {
3737
assertEquals(result, '/_next/data/build-id/target.json')
3838
})
3939
})
40+
41+
Deno.test('relativizeURL', async (t) => {
42+
await t.step('should relativize a URL when origin matches', async () => {
43+
const url = 'https://example.com/pathname'
44+
const base = 'https://example.com/'
45+
const result = relativizeURL(url, base)
46+
assertEquals(result, '/pathname')
47+
})
48+
49+
await t.step('should NOT relativize a URL when origin does not match', async () => {
50+
const url = 'https://example.com/pathname'
51+
const base = 'https://not-example.com/'
52+
const result = relativizeURL(url, base)
53+
assertEquals(result, 'https://example.com/pathname')
54+
})
55+
56+
await t.step('accepts relative URL strings and produce relative URL as output', async () => {
57+
const url = '/pathname'
58+
const base = 'https://example.com/'
59+
const result = relativizeURL(url, base)
60+
assertEquals(result, '/pathname')
61+
})
62+
})

tests/integration/middleware.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ for (const {
130130
expect(response.status).toBe(307)
131131
expect(response.headers.get('location'), 'added a location header').toBeTypeOf('string')
132132
expect(
133-
new URL(response.headers.get('location') as string).pathname,
133+
new URL(response.headers.get('location') as string, 'http://n').pathname,
134134
'redirected to the correct path',
135135
).toEqual('/other')
136136
expect(response.headers.get('x-runtime')).toEqual(expectedRuntime)
@@ -154,7 +154,7 @@ for (const {
154154
expect(response.status).toBe(307)
155155
expect(response.headers.get('location'), 'added a location header').toBeTypeOf('string')
156156
expect(
157-
new URL(response.headers.get('location') as string).pathname,
157+
new URL(response.headers.get('location') as string, 'http://n').pathname,
158158
'redirected to the correct path',
159159
).toEqual('/other')
160160
expect(response.headers.get('x-header-from-redirect'), 'hello').toBe('hello')
@@ -357,7 +357,7 @@ for (const {
357357
expect(response.status).toBe(307)
358358
expect(response.headers.get('location'), 'added a location header').toBeTypeOf('string')
359359
expect(
360-
new URL(response.headers.get('location') as string).pathname,
360+
new URL(response.headers.get('location') as string, 'http://n').pathname,
361361
'redirected to the correct path',
362362
).toEqual('/other')
363363
expect(response.headers.get('x-header-from-redirect'), 'hello').toBe('hello')
@@ -382,7 +382,7 @@ for (const {
382382
expect(response.status).toBe(307)
383383
expect(response.headers.get('location'), 'added a location header').toBeTypeOf('string')
384384
expect(
385-
new URL(response.headers.get('location') as string).pathname,
385+
new URL(response.headers.get('location') as string, 'http://n').pathname,
386386
'redirected to the correct path',
387387
).toEqual('/other')
388388
expect(response.headers.get('x-header-from-redirect'), 'hello').toBe('hello')

0 commit comments

Comments
 (0)