From 9ae106730e28f89aed7987d40c9387057df4784e Mon Sep 17 00:00:00 2001 From: skokalin Date: Wed, 28 May 2025 17:47:42 +0400 Subject: [PATCH 1/2] node.js: Fixed issue with duplicate headers in response It fixes losing context in response in cases when there are 2 or more headers with the same name. The prev implementation used to use foreach function which uses local lexical environment and did not find this.headers_len locally, which causes crash of the http server module. It was replaced with a for loop in order to make access for this.headers_len variable and improve performance of calculation. Closes: https://github.com/nginx/unit/issues/1621 Signed-off-by: Andrew Clayton --- src/nodejs/unit-http/http_server.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nodejs/unit-http/http_server.js b/src/nodejs/unit-http/http_server.js index 4e1c190e1..68400b84e 100644 --- a/src/nodejs/unit-http/http_server.js +++ b/src/nodejs/unit-http/http_server.js @@ -153,9 +153,9 @@ ServerResponse.prototype._removeHeader = function _removeHeader(lc_name) { this.headers_count -= value.length; this.headers_len -= value.length * name_len; - value.forEach(function(val) { - this.headers_len -= Buffer.byteLength(val + "", 'latin1'); - }); + for (let i = 0; i < value.length; i++){ + this.headers_len -= Buffer.byteLength(value[i] + "", 'latin1'); + } return; } From a9071e11602ec73b96302c852709c16c9d55996d Mon Sep 17 00:00:00 2001 From: skokalin Date: Wed, 28 May 2025 17:50:04 +0400 Subject: [PATCH 2/2] tests: nodejs: Added test for responses with duplicate headers Signed-off-by: Andrew Clayton --- test/node/set_header_array_with_override/app.js | 6 ++++++ test/test_node_application.py | 10 ++++++++++ 2 files changed, 16 insertions(+) create mode 100644 test/node/set_header_array_with_override/app.js diff --git a/test/node/set_header_array_with_override/app.js b/test/node/set_header_array_with_override/app.js new file mode 100644 index 000000000..6b3863a4c --- /dev/null +++ b/test/node/set_header_array_with_override/app.js @@ -0,0 +1,6 @@ + +require('http').createServer(function (req, res) { + res.setHeader('Set-Cookie', ['tc=one,two,three', 'tc=four,five,six']); + res.setHeader('Set-Cookie', ['tc=one,two,three', 'tc=four,five,six', 'tc=seven,eight,nine']); + res.end(); +}).listen(8080); diff --git a/test/test_node_application.py b/test/test_node_application.py index 88ae31362..6be168558 100644 --- a/test/test_node_application.py +++ b/test/test_node_application.py @@ -234,6 +234,16 @@ def test_node_application_set_header_array(): ], 'set header array' +def test_node_application_set_header_array_with_override(): + client.load('set_header_array_with_override') + + assert client.get()['headers']['Set-Cookie'] == [ + 'tc=one,two,three', + 'tc=four,five,six', + 'tc=seven,eight,nine', + ], 'set header array with override' + + @pytest.mark.skip('not yet') def test_node_application_status_message(): client.load('status_message')