Skip to content
Prev Previous commit
Next Next commit
http: added map support
  • Loading branch information
marco-ippolito committed Jan 7, 2023
commit eb7481f185c6de0a631028ae53f152f7ef20a7d5
79 changes: 42 additions & 37 deletions doc/api/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -1953,8 +1953,6 @@ non-string values. However, the non-string values will be converted to strings
for network transmission. The same response object is returned to the caller,
to enable call chaining.

> To set multiple header values at once see [`response.setHeaders()`][].

```js
response.setHeader('Content-Type', 'text/html');
```
Expand Down Expand Up @@ -1989,40 +1987,6 @@ header will not yield the expected result. If progressive population of headers
is desired with potential future retrieval and modification, use
[`response.setHeader()`][] instead of [`response.writeHead()`][].

### `response.setHeaders(headers)`

<!-- YAML
added: REPLACEME
-->

* `headers` {Headers}
* Returns: {http.ServerResponse}

Returns the response object.

Sets multiple header values for implicit headers.
`headers` must be an instance of [`Headers`][], if header already exists
in the to-be-sent headers, its value will be replaced.

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

When headers have been set with [`response.setHeaders()`][], they will be merged
with any headers passed to [`response.writeHead()`][], with the headers passed
to [`response.writeHead()`][] given precedence.

```js
// Returns content-type = text/plain
const server = http.createServer((req, res) => {
const headers = new Headers({ 'Content-Type': 'text/html' });
res.setHeaders(headers);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
});
```

### `response.setTimeout(msecs[, callback])`

<!-- YAML
Expand Down Expand Up @@ -3005,6 +2969,47 @@ Sets a single header value. If the header already exists in the to-be-sent
headers, its value will be replaced. Use an array of strings to send multiple
headers with the same name.

### `outgoingMessage.setHeaders(headers)`

<!-- YAML
added: REPLACEME
-->

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

Returns the response object.

Sets multiple header values for implicit headers.
`headers` must be an instance of [`Headers`][], if header already exists
Comment thread
marco-ippolito marked this conversation as resolved.
Outdated
in the to-be-sent headers, its value will be replaced.

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

or

```js
const headers = new Map([['foo', 'bar']]);
res.setHeaders(headers);
```

When headers have been set with [`outgoingMessage.setHeaders()`][],
they will be merged with any headers passed to [`response.writeHead()`][],
with the headers passed to [`response.writeHead()`][] given precedence.

```js
// Returns content-type = text/plain
const server = http.createServer((req, res) => {
const headers = new Headers({ 'Content-Type': 'text/html' });
res.setHeaders(headers);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('ok');
});
```

### `outgoingMessage.setTimeout(msesc[, callback])`

<!-- YAML
Expand Down Expand Up @@ -3823,6 +3828,7 @@ Set the maximum number of idle HTTP parsers. **Default:** `1000`.
[`net.createConnection()`]: net.md#netcreateconnectionoptions-connectlistener
[`new URL()`]: url.md#new-urlinput-base
[`outgoingMessage.setHeader(name, value)`]: #outgoingmessagesetheadername-value
[`outgoingMessage.setHeaders()`]: #outgoingmessagesetheadersheaders
[`outgoingMessage.socket`]: #outgoingmessagesocket
[`removeHeader(name)`]: #requestremoveheadername
[`request.destroy()`]: #requestdestroyerror
Expand All @@ -3840,7 +3846,6 @@ Set the maximum number of idle HTTP parsers. **Default:** `1000`.
[`response.end()`]: #responseenddata-encoding-callback
[`response.getHeader()`]: #responsegetheadername
[`response.setHeader()`]: #responsesetheadername-value
[`response.setHeaders()`]: #responsesetheadersheaders
[`response.socket`]: #responsesocket
[`response.writableEnded`]: #responsewritableended
[`response.writableFinished`]: #responsewritablefinished
Expand Down
10 changes: 7 additions & 3 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ 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();

Expand Down Expand Up @@ -680,8 +679,13 @@ OutgoingMessage.prototype.setHeaders = function setHeaders(headers) {
throw new ERR_HTTP_HEADERS_SENT('set');
}

if (headers instanceof Headers === false) {
throw new ERR_INVALID_ARG_TYPE('headers', 'Headers', headers);

if (
!headers ||
!typeof headers.keys === 'function' ||
!typeof headers.get === 'function'
Comment thread
marco-ippolito marked this conversation as resolved.
Outdated
) {
throw new ERR_INVALID_ARG_TYPE('headers', ['Headers', 'Map'], headers);
}

for (const key of headers.keys()) {
Comment thread
ShogunPanda marked this conversation as resolved.
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 @@ -109,3 +109,23 @@ const assert = require('assert');
});
}));
}

{
const server = http.createServer({ requireHostHeader: false }, common.mustCall((req, res) => {
const headers = new Map([['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();
}));
});
}));
}