Skip to content

Commit

Permalink
fix: handle invalid redirect header in a response (#100)
Browse files Browse the repository at this point in the history
Co-authored-by: Mohammad macbook <m_ganji@sfu.ca>
  • Loading branch information
wraithgar and Mohammad macbook committed Apr 13, 2023
1 parent 95e81ca commit a1be115
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 2 deletions.
16 changes: 14 additions & 2 deletions lib/index.js
Expand Up @@ -143,8 +143,20 @@ const fetch = async (url, opts) => {
const location = headers.get('Location')

// HTTP fetch step 5.3
const locationURL = location === null ? null
: (new URL(location, request.url)).toString()
let locationURL = null
try {
locationURL = location === null ? null : new URL(location, request.url).toString()
} catch {
// error here can only be invalid URL in Location: header
// do not throw when options.redirect == manual
// let the user extract the errorneous redirect URL
if (request.redirect !== 'manual') {
/* eslint-disable-next-line max-len */
reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect'))
finalize()
return
}
}

// HTTP fetch step 5.5
if (request.redirect === 'error') {
Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/server.js
Expand Up @@ -223,6 +223,12 @@ class TestServer {
res.end()
}

if (p === '/redirect/301/invalid') {
res.statusCode = 301
res.setHeader('Location', '//super:invalid:url%/')
res.end()
}

if (p === '/redirect/302') {
res.statusCode = 302
res.setHeader('Location', '/inspect')
Expand Down
19 changes: 19 additions & 0 deletions test/index.js
Expand Up @@ -380,6 +380,25 @@ t.test('treat broken redirect as ordinary response (manual)', async t => {
t.equal(res.headers.get('location'), null)
})

t.test('should process an invalid redirect (manual)', async t => {
const url = `${base}redirect/301/invalid`
const options = {
redirect: 'manual',
}
const res = await fetch(url, options)
t.equal(res.url, url)
t.equal(res.status, 301)
t.equal(res.headers.get('location'), '//super:invalid:url%/')
})

t.test('should throw an error on invalid redirect url', async t => {
const url = `${base}redirect/301/invalid`
await t.rejects(fetch(url), {
name: 'FetchError',
message: 'uri requested responds with an invalid redirect URL: //super:invalid:url%/',
})
})

t.test('set redirected property on response when redirect', t =>
fetch(`${base}redirect/301`).then(res => t.equal(res.redirected, true)))

Expand Down

0 comments on commit a1be115

Please sign in to comment.