Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion doc/api/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -1805,14 +1805,18 @@ 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
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
Expand Down
10 changes: 8 additions & 2 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
8 changes: 7 additions & 1 deletion lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
'use strict';

const {
ArrayIsArray,
Error,
ObjectKeys,
ObjectSetPrototypeOf,
Expand Down Expand Up @@ -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
Expand Down
41 changes: 41 additions & 0 deletions test/parallel/test-http-write-head-2.js
Original file line number Diff line number Diff line change
@@ -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();
});
}));
}));
}