From 7c3bcf5ef5effe0c3238c8f1a8de1afec52bb9c4 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Sun, 20 Sep 2020 09:32:06 +0200 Subject: [PATCH 1/6] http: allow passing array of key/val into writeHead Enables an optimization when the user already has the headers in an array form, e.g. when proxying. --- lib/_http_outgoing.js | 10 ++++-- lib/_http_server.js | 8 ++++- test/parallel/test-http-write-head-2.js | 41 +++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 test/parallel/test-http-write-head-2.js diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index e683b61e94a927..37edb035afc8be 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -381,8 +381,14 @@ function _storeHeader(firstLine, headers) { processHeader(this, state, entry[0], entry[1], false); } } else if (ArrayIsArray(headers)) { - for (const entry of headers) { - processHeader(this, state, entry[0], entry[1], true); + if (headers.length && ArrayIsArray(headers[0])) { + for (const entry of headers) { + processHeader(this, state, entry[0], entry[1], true); + } + } else { + for (let n = 0; n < headers.length; n += 2) { + processHeader(this, state, headers[n + 0], headers[n + 1], true); + } } } else { for (const key in headers) { diff --git a/lib/_http_server.js b/lib/_http_server.js index 21eb68d463e94a..a34a00f302b890 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -22,6 +22,7 @@ 'use strict'; const { + ArrayIsArray, Error, ObjectKeys, ObjectSetPrototypeOf, @@ -278,7 +279,12 @@ function writeHead(statusCode, reason, obj) { if (this[kOutHeaders]) { // Slow-case: when progressive API and header fields are passed. let k; - if (obj) { + if (ArrayIsArray(obj)) { + for (let n = 0; n < obj.length; n += 2) { + k = obj[n + 0]; + if (k) this.setHeader(k, obj[n + 1]); + } + } else if (obj) { const keys = ObjectKeys(obj); // Retain for(;;) loop for performance reasons // Refs: https://github.com/nodejs/node/pull/30958 diff --git a/test/parallel/test-http-write-head-2.js b/test/parallel/test-http-write-head-2.js new file mode 100644 index 00000000000000..3ffa23b0dc19e8 --- /dev/null +++ b/test/parallel/test-http-write-head-2.js @@ -0,0 +1,41 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +// Verify that ServerResponse.writeHead() works with arrays. + +{ + const server = http.createServer(common.mustCall((req, res) => { + res.setHeader('test', '1'); + res.writeHead(200, [ 'test', '2', 'test2', '2' ]); + res.end(); + })); + + server.listen(0, common.mustCall(() => { + http.get({ port: server.address().port }, common.mustCall((res) => { + assert.strictEqual(res.headers.test, '2'); + assert.strictEqual(res.headers.test2, '2'); + res.resume().on('end', () => { + server.close(); + }); + })); + })); +} + +{ + const server = http.createServer(common.mustCall((req, res) => { + res.writeHead(200, [ 'test', '1', 'test2', '2' ]); + res.end(); + })); + + server.listen(0, common.mustCall(function() { + http.get({ port: server.address().port }, common.mustCall((res) => { + assert.strictEqual(res.headers.test, '1'); + assert.strictEqual(res.headers.test2, '2'); + res.resume().on('end', () => { + server.close(); + }); + })); + })); +} From 9c94f5b158e56d329ee4c95b3921a3b8c3211e57 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Sun, 20 Sep 2020 22:24:07 +0200 Subject: [PATCH 2/6] fixup: docs --- doc/api/http.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/api/http.md b/doc/api/http.md index b4348f4dfddc0c..887aaeadc8c090 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -1805,7 +1805,7 @@ changes: * `statusCode` {number} * `statusMessage` {string} -* `headers` {Object} +* `headers` {Object|Array} * Returns: {http.ServerResponse} Sends a response header to the request. The status code is a 3-digit HTTP @@ -1813,6 +1813,10 @@ status code, like `404`. The last argument, `headers`, are the response headers. Optionally one can give a human-readable `statusMessage` as the second argument. +`headers` may be an `Array` where the keys and values are in the same list. +It is *not* a list of tuples. So, the even-numbered offsets are key values, +and the odd-numbered offsets are the associated values. + Returns a reference to the `ServerResponse`, so that calls can be chained. ```js From f8f3e051041d3a4fa13c484fcc5091e7437b0820 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Mon, 21 Sep 2020 09:26:22 +0200 Subject: [PATCH 3/6] fixup --- doc/api/http.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/api/http.md b/doc/api/http.md index 887aaeadc8c090..54cea2c1a4cd46 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -1791,6 +1791,9 @@ the request body should be sent. See the [`'checkContinue'`][] event on