From 33b43098b10e14fd1cffd02c06549cf7fdbaa0c4 Mon Sep 17 00:00:00 2001 From: Yoann Gendrey Date: Sun, 10 Nov 2024 10:18:17 +0100 Subject: [PATCH 1/4] fix: handle undici Headers and Maps --- lib/handler/redirect-handler.js | 3 +- test/redirect-request.js | 59 ++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/lib/handler/redirect-handler.js b/lib/handler/redirect-handler.js index 5121cf2263b..bb5aa1d5ffc 100644 --- a/lib/handler/redirect-handler.js +++ b/lib/handler/redirect-handler.js @@ -228,7 +228,8 @@ function cleanRequestHeaders (headers, removeContent, unknownOrigin) { } } } else if (headers && typeof headers === 'object') { - const entries = headers instanceof Headers ? headers.entries() : Object.entries(headers) + const iterableHeaderEntries = util.isIterable(headers) ? headers : Object.entries(headers) + const entries = headers instanceof Headers ? headers.entries() : iterableHeaderEntries for (const [key, value] of entries) { if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { ret.push(key, value) diff --git a/test/redirect-request.js b/test/redirect-request.js index 50c8931a5f1..4b7d114319f 100644 --- a/test/redirect-request.js +++ b/test/redirect-request.js @@ -13,6 +13,7 @@ const { startRedirectingWithQueryParams } = require('./utils/redirecting-servers') const { createReadable, createReadableStream } = require('./utils/stream') +const { Headers: UndiciHeaders } = require('..') const redirect = undici.interceptors.redirect for (const factory of [ @@ -227,7 +228,7 @@ for (const factory of [ await t.completed }) - test('should remove Host and request body related headers when following HTTP 303 (Headers)', async t => { + test('should remove Host and request body related headers when following HTTP 303 (Global Headers)', async t => { t = tspl(t, { plan: 3 }) const server = await startRedirectingServer() @@ -255,6 +256,62 @@ for (const factory of [ await t.completed }) + test('should remove Host and request body related headers when following HTTP 303 (Undici Headers)', async t => { + t = tspl(t, { plan: 3 }) + + const server = await startRedirectingServer() + + const { statusCode, headers, body: bodyStream } = await request(t, server, undefined, `http://${server}/303`, { + method: 'PATCH', + headers: new UndiciHeaders({ + 'Content-Encoding': 'gzip', + 'X-Foo1': '1', + 'X-Foo2': '2', + 'Content-Type': 'application/json', + 'X-Foo3': '3', + Host: 'localhost', + 'X-Bar': '4' + }), + maxRedirections: 10 + }) + + const body = await bodyStream.text() + + t.strictEqual(statusCode, 200) + t.ok(!headers.location) + t.strictEqual(body, `GET /5 :: host@${server} connection@keep-alive x-bar@4 x-foo1@1 x-foo2@2 x-foo3@3`) + + await t.completed + }) + + test('should remove Host and request body related headers when following HTTP 303 (Maps)', async t => { + t = tspl(t, { plan: 3 }) + + const server = await startRedirectingServer() + + const { statusCode, headers, body: bodyStream } = await request(t, server, undefined, `http://${server}/303`, { + method: 'PATCH', + headers: new Map([ + ['Content-Encoding', 'gzip'], + ['X-Foo1', '1'], + ['X-Foo2', '2'], + ['Content-Type', 'application/json'], + ['X-Foo3', '3'], + ['Host', 'localhost'], + ['X-Bar', '4'] + ]), + maxRedirections: 10 + }) + + const body = await bodyStream.text() + + t.strictEqual(statusCode, 200) + t.ok(!headers.location) + t.strictEqual(body, `GET /5 :: host@${server} connection@keep-alive x-foo1@1 x-foo2@2 x-foo3@3 x-bar@4`) + + await t.completed + }) + test('should follow redirection after a HTTP 307', async t => { t = tspl(t, { plan: 3 }) From 307cc25abaf8b767d6e7aca4bb96271143b985dc Mon Sep 17 00:00:00 2001 From: Yoann Gendrey Date: Sun, 10 Nov 2024 13:41:46 +0100 Subject: [PATCH 2/4] fix: entries def --- lib/handler/redirect-handler.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/handler/redirect-handler.js b/lib/handler/redirect-handler.js index bb5aa1d5ffc..37ac17eda77 100644 --- a/lib/handler/redirect-handler.js +++ b/lib/handler/redirect-handler.js @@ -228,8 +228,7 @@ function cleanRequestHeaders (headers, removeContent, unknownOrigin) { } } } else if (headers && typeof headers === 'object') { - const iterableHeaderEntries = util.isIterable(headers) ? headers : Object.entries(headers) - const entries = headers instanceof Headers ? headers.entries() : iterableHeaderEntries + const entries = util.isIterable(headers) ? headers.entries() : Object.entries(headers) for (const [key, value] of entries) { if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { ret.push(key, value) From 4e6a53f1637adf118184c3afab0cb5b5586134ce Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Sun, 10 Nov 2024 13:56:48 +0100 Subject: [PATCH 3/4] Update redirect-handler.js Co-authored-by: Robert Nagy --- lib/handler/redirect-handler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/handler/redirect-handler.js b/lib/handler/redirect-handler.js index 37ac17eda77..2e7f0a65839 100644 --- a/lib/handler/redirect-handler.js +++ b/lib/handler/redirect-handler.js @@ -228,7 +228,7 @@ function cleanRequestHeaders (headers, removeContent, unknownOrigin) { } } } else if (headers && typeof headers === 'object') { - const entries = util.isIterable(headers) ? headers.entries() : Object.entries(headers) + const entries = util.isIterable(headers) ? headers : Object.entries(headers) for (const [key, value] of entries) { if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { ret.push(key, value) From cbf96953a00a11ce12edae5aabe412d36a0af103 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Sun, 10 Nov 2024 15:44:00 +0100 Subject: [PATCH 4/4] Update redirect-handler.js Co-authored-by: tsctx <91457664+tsctx@users.noreply.github.com> --- lib/handler/redirect-handler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/handler/redirect-handler.js b/lib/handler/redirect-handler.js index 2e7f0a65839..2f1995e6a92 100644 --- a/lib/handler/redirect-handler.js +++ b/lib/handler/redirect-handler.js @@ -228,7 +228,7 @@ function cleanRequestHeaders (headers, removeContent, unknownOrigin) { } } } else if (headers && typeof headers === 'object') { - const entries = util.isIterable(headers) ? headers : Object.entries(headers) + const entries = typeof headers[Symbol.iterator] === 'function' ? headers : Object.entries(headers) for (const [key, value] of entries) { if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { ret.push(key, value)