diff --git a/lib/fetch/constants.js b/lib/fetch/constants.js index bc90a031cde..a5294a994fb 100644 --- a/lib/fetch/constants.js +++ b/lib/fetch/constants.js @@ -48,11 +48,17 @@ const requestCache = [ 'only-if-cached' ] +// https://fetch.spec.whatwg.org/#request-body-header-name const requestBodyHeader = [ 'content-encoding', 'content-language', 'content-location', - 'content-type' + 'content-type', + // See https://github.com/nodejs/undici/issues/2021 + // 'Content-Length' is a forbidden header name, which is typically + // removed in the Headers implementation. However, undici doesn't + // filter out headers, so we add it here. + 'content-length' ] // https://fetch.spec.whatwg.org/#enumdef-requestduplex diff --git a/test/fetch/issue-2021.js b/test/fetch/issue-2021.js new file mode 100644 index 00000000000..cd28a7165d7 --- /dev/null +++ b/test/fetch/issue-2021.js @@ -0,0 +1,32 @@ +'use strict' + +const { test } = require('tap') +const { once } = require('events') +const { createServer } = require('http') +const { fetch } = require('../..') + +// https://github.com/nodejs/undici/issues/2021 +test('content-length header is removed on redirect', async (t) => { + const server = createServer((req, res) => { + if (req.url === '/redirect') { + res.writeHead(302, { Location: '/redirect2' }) + res.end() + return + } + + res.end() + }).listen(0).unref() + + t.teardown(server.close.bind(server)) + await once(server, 'listening') + + const body = 'a+b+c' + + await t.resolves(fetch(`http://localhost:${server.address().port}/redirect`, { + method: 'POST', + body, + headers: { + 'content-length': Buffer.byteLength(body) + } + })) +})