Skip to content

Commit

Permalink
fix(fetch): connection is cancelled when redirecting (#1787)
Browse files Browse the repository at this point in the history
  • Loading branch information
KhafraDev committed Nov 29, 2022
1 parent bb84264 commit e49b68d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
5 changes: 4 additions & 1 deletion lib/fetch/index.js
Expand Up @@ -781,8 +781,11 @@ async function mainFetch (fetchParams, recursive = false) {
// https://fetch.spec.whatwg.org/#concept-scheme-fetch
// given a fetch params fetchParams
async function schemeFetch (fetchParams) {
// Note: since the connection is destroyed on redirect, which sets fetchParams to a
// cancelled state, we do not want this condition to trigger *unless* there have been
// no redirects. See https://github.com/nodejs/undici/issues/1776
// 1. If fetchParams is canceled, then return the appropriate network error for fetchParams.
if (isCancelled(fetchParams)) {
if (isCancelled(fetchParams) && fetchParams.request.redirectCount === 0) {
return makeAppropriateNetworkError(fetchParams)
}

Expand Down
2 changes: 1 addition & 1 deletion lib/fetch/response.js
Expand Up @@ -436,7 +436,7 @@ function makeAppropriateNetworkError (fetchParams) {
// otherwise return a network error.
return isAborted(fetchParams)
? makeNetworkError(new DOMException('The operation was aborted.', 'AbortError'))
: makeNetworkError(fetchParams.controller.terminated.reason)
: makeNetworkError('Request was cancelled.')
}

// https://whatpr.org/fetch/1392.html#initialize-a-response
Expand Down
29 changes: 29 additions & 0 deletions test/fetch/redirect.js
@@ -0,0 +1,29 @@
'use strict'

const { test } = require('tap')
const { createServer } = require('http')
const { once } = require('events')
const { fetch } = require('../..')

// https://github.com/nodejs/undici/issues/1776
test('Redirecting with a body does not cancel the current request - #1776', async (t) => {
const server = createServer((req, res) => {
if (req.url === '/redirect') {
res.statusCode = 301
res.setHeader('location', '/redirect/')
res.write('<a href="/redirect/">Moved Permanently</a>')
setTimeout(() => res.end(), 500)
return
}

res.write(req.url)
res.end()
}).listen(0)

t.teardown(server.close.bind(server))
await once(server, 'listening')

const resp = await fetch(`http://localhost:${server.address().port}/redirect`)
t.equal(await resp.text(), '/redirect/')
t.ok(resp.redirected)
})

0 comments on commit e49b68d

Please sign in to comment.