From 7c3bcf5ef5effe0c3238c8f1a8de1afec52bb9c4 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Sun, 20 Sep 2020 09:32:06 +0200 Subject: [PATCH] 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(); + }); + })); + })); +}