Skip to content
Prev Previous commit
Next Next commit
http: setheaders accepts headers class
  • Loading branch information
marco-ippolito committed Jan 5, 2023
commit 4dceea00418ad65d6400fa3aaffb3a9a4aec4ac5
9 changes: 8 additions & 1 deletion doc/api/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -1995,7 +1995,7 @@ is desired with potential future retrieval and modification, use
added: REPLACEME
-->

* `headers` {Object|Array}
* `headers` {Headers|Object|Array}
* Returns: {http.ServerResponse}

Returns the response object.
Expand All @@ -2006,6 +2006,13 @@ It is _not_ a list of tuples. So, the even-numbered offsets are key values,
and the odd-numbered offsets are the associated values. The array is in the same
format as `request.rawHeaders`.

```js
const headers = new Headers({ foo: 'bar' });
response.setHeaders(headers);
```

or

```js
response.setHeaders(['foo', 'bar', 'fizz', 'buzz']);
```
Expand Down
30 changes: 19 additions & 11 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ let debug = require('internal/util/debuglog').debuglog('http', (fn) => {
debug = fn;
});

const { Headers } = require('internal/deps/undici/undici');

Comment thread
marco-ippolito marked this conversation as resolved.
Outdated
const HIGH_WATER_MARK = getDefaultHighWaterMark();

const kCorked = Symbol('corked');
Expand Down Expand Up @@ -673,28 +675,34 @@ OutgoingMessage.prototype.setHeader = function setHeader(name, value) {
return this;
};

OutgoingMessage.prototype.setHeaders = function setHeaders(obj) {
OutgoingMessage.prototype.setHeaders = function setHeaders(headers) {
if (this._header) {
throw new ERR_HTTP_HEADERS_SENT('set');
}

let k;
if (ArrayIsArray(obj)) {
if (obj.length % 2 !== 0) {
throw new ERR_INVALID_ARG_VALUE('headers', obj);

if (headers instanceof Headers) {
const keys = [...headers.keys()];
Comment thread
marco-ippolito marked this conversation as resolved.
Outdated
for (let i = 0; i < keys.length; i++) {
k = keys[i];
if (k) this.setHeader(k, headers.get(k));
}
} else if (ArrayIsArray(headers)) {
if (headers.length % 2 !== 0) {
throw new ERR_INVALID_ARG_VALUE('headers', headers);
}

for (let n = 0; n < obj.length; n += 2) {
k = obj[n + 0];
if (k) this.setHeader(k, obj[n + 1]);
for (let n = 0; n < headers.length; n += 2) {
k = headers[n + 0];
if (k) this.setHeader(k, headers[n + 1]);
}
} else if (obj) {
const keys = ObjectKeys(obj);
} else if (headers) {
const keys = ObjectKeys(headers);
// Retain for(;;) loop for performance reasons
// Refs: https://github.com/nodejs/node/pull/30958
for (let i = 0; i < keys.length; i++) {
k = keys[i];
if (k) this.setHeader(k, obj[k]);
if (k) this.setHeader(k, headers[k]);
}
}

Expand Down
20 changes: 20 additions & 0 deletions test/parallel/test-http-response-setheaders.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,23 @@ const assert = require('assert');
});
}));
}

{
const server = http.createServer({ requireHostHeader: false }, common.mustCall((req, res) => {
const headers = new globalThis.Headers({ foo: '1', bar: '2' });
res.setHeaders(headers);
res.writeHead(200);
res.end();
}));

server.listen(0, common.mustCall(() => {
http.get({ port: server.address().port }, (res) => {
assert.strictEqual(res.statusCode, 200);
assert.strictEqual(res.headers.foo, '1');
assert.strictEqual(res.headers.bar, '2');
res.resume().on('end', common.mustCall(() => {
server.close();
}));
});
}));
}