Skip to content

Commit 962a1c8

Browse files
authored
Merge pull request #36861 from github/repo-sync
Repo sync
2 parents fcaffb8 + 50202e8 commit 962a1c8

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

src/frame/middleware/trailing-slashes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export default function trailingSlashes(req: ExtendedRequest, res: Response, nex
1515
if (split.length) {
1616
url += `?${split.join('?')}`
1717
}
18+
url = url.replace(/\/+/g, '/') // Prevent multiple slashes
1819
defaultCacheControl(res)
1920
return res.redirect(301, url)
2021
}

src/redirects/middleware/handle-redirects.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default function handleRedirects(req: ExtendedRequest, res: Response, nex
1919

2020
// Any double-slashes in the URL should be removed first
2121
if (req.path.includes('//')) {
22-
return res.redirect(301, req.path.replace(/\/\//g, '/'))
22+
return res.redirect(301, req.path.replace(/(\/+)/g, '/'))
2323
}
2424

2525
// blanket redirects for languageless homepage

src/redirects/tests/redirects.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,6 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url))
1616
describe('redirects', () => {
1717
vi.setConfig({ testTimeout: 3 * 60 * 1000 })
1818

19-
let redirects
20-
beforeAll(async () => {
21-
const res = await get('/en?json=redirects')
22-
redirects = JSON.parse(res.body)
23-
})
24-
2519
test('page.buildRedirects() returns an array', async () => {
2620
const page = await Page.init({
2721
relativePath:
@@ -94,6 +88,12 @@ describe('redirects', () => {
9488
})
9589

9690
describe('trailing slashes', () => {
91+
let redirects
92+
beforeAll(async () => {
93+
const res = await get('/en?json=redirects')
94+
redirects = JSON.parse(res.body)
95+
})
96+
9797
test('are absent from all redirected URLs', async () => {
9898
const keys = Object.keys(redirects)
9999
expect(keys.length).toBeGreaterThan(100)
@@ -138,6 +138,12 @@ describe('redirects', () => {
138138
})
139139

140140
describe('external redirects', () => {
141+
let redirects
142+
beforeAll(async () => {
143+
const res = await get('/en?json=redirects')
144+
redirects = JSON.parse(res.body)
145+
})
146+
141147
test('no external redirect starts with a language prefix', () => {
142148
const values = Object.entries(redirects)
143149
.filter(([, to]) => to.includes('://'))
@@ -425,6 +431,14 @@ describe('redirects', () => {
425431
expect(res.headers.location).toBe(`/en`)
426432
})
427433

434+
test('no domain redirect on //example.com/', async () => {
435+
const res = await get(`//example.com/`)
436+
expect(res.statusCode).toBe(301)
437+
expect(res.headers.location).toBe(`/example.com`) // should not be //example.com
438+
const res2 = await get(res.headers.location)
439+
expect(res2.statusCode).toBe(404)
440+
})
441+
428442
test('double-slash elsewhere in the URL', async () => {
429443
const res = await get(`/en//rest`)
430444
expect(res.statusCode).toBe(301)

0 commit comments

Comments
 (0)