From 6a04edcd5867c4de6bd53d10f6b44eaecf02755e Mon Sep 17 00:00:00 2001 From: angelyan <46203110+angelyan@users.noreply.github.com> Date: Tue, 26 Dec 2023 13:45:32 -0300 Subject: [PATCH] fix(fetch): do not abort fetch on redirect (#2545) --- lib/fetch/index.js | 8 +++++--- test/fetch/redirect.js | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/lib/fetch/index.js b/lib/fetch/index.js index 54dc6f35b18..f16ce4b4536 100644 --- a/lib/fetch/index.js +++ b/lib/fetch/index.js @@ -1206,7 +1206,7 @@ async function httpFetch (fetchParams) { // encouraged to, transmit an RST_STREAM frame. // See, https://github.com/whatwg/fetch/issues/1288 if (request.redirect !== 'manual') { - fetchParams.controller.connection.destroy() + fetchParams.controller.connection.destroy(undefined, false) } // 2. Switch on request’s redirect mode: @@ -1718,10 +1718,12 @@ async function httpNetworkFetch ( fetchParams.controller.connection = { abort: null, destroyed: false, - destroy (err) { + destroy (err, abort = true) { if (!this.destroyed) { this.destroyed = true - this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError')) + if (abort) { + this.abort?.(err ?? new DOMException('The operation was aborted.', 'AbortError')) + } } } } diff --git a/test/fetch/redirect.js b/test/fetch/redirect.js index 7e3681b3d23..dd90418880c 100644 --- a/test/fetch/redirect.js +++ b/test/fetch/redirect.js @@ -48,3 +48,29 @@ test('Redirecting with an empty body does not throw an error - #2027', async (t) t.equal(await resp.text(), '/redirect/') t.ok(resp.redirected) }) + +test('Redirecting with a body does not fail to write body - #2543', async (t) => { + const server = createServer((req, res) => { + if (req.url === '/redirect') { + res.writeHead(307, { location: '/target' }) + res.write('Moved Permanently') + setTimeout(() => res.end(), 500) + } else { + let body = '' + req.on('data', (chunk) => { body += chunk }) + req.on('end', () => t.equals(body, 'body')) + res.write('ok') + res.end() + } + }).listen(0) + + t.teardown(server.close.bind(server)) + await once(server, 'listening') + + const resp = await fetch(`http://localhost:${server.address().port}/redirect`, { + method: 'POST', + body: 'body' + }) + t.equal(await resp.text(), 'ok') + t.ok(resp.redirected) +})