Skip to content
Next Next commit
http: res.setHeaders first implementation
  • Loading branch information
marco-ippolito committed Jan 5, 2023
commit a27f9e5f44e90071f75b2a24fce168c3778c3135
28 changes: 28 additions & 0 deletions lib/_http_outgoing.js
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,34 @@ OutgoingMessage.prototype.setHeader = function setHeader(name, value) {
return this;
};

OutgoingMessage.prototype.setHeaders = function setHeaders(obj) {
Comment thread
marco-ippolito marked this conversation as resolved.
Outdated
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);
}

for (let n = 0; n < obj.length; n += 2) {
k = obj[n + 0];
if (k) this.setHeader(k, obj[n + 1]);
}
} else if (obj) {
Comment thread
marco-ippolito marked this conversation as resolved.
Outdated
const keys = ObjectKeys(obj);
// 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]);
}
}

return this;
};

OutgoingMessage.prototype.appendHeader = function appendHeader(name, value) {
if (this._header) {
throw new ERR_HTTP_HEADERS_SENT('append');
Expand Down
23 changes: 1 addition & 22 deletions lib/_http_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,28 +359,7 @@ function writeHead(statusCode, reason, obj) {
let headers;
if (this[kOutHeaders]) {
// Slow-case: when progressive API and header fields are passed.
let k;
if (ArrayIsArray(obj)) {
if (obj.length % 2 !== 0) {
throw new ERR_INVALID_ARG_VALUE('headers', 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
for (let i = 0; i < keys.length; i++) {
k = keys[i];
if (k) this.setHeader(k, obj[k]);
}
}
if (k === undefined && this._header) {
Comment thread
ShogunPanda marked this conversation as resolved.
throw new ERR_HTTP_HEADERS_SENT('render');
}
this.setHeaders(obj);
Comment thread
marco-ippolito marked this conversation as resolved.
Outdated
// Only progressive api is used
headers = this[kOutHeaders];
} else {
Expand Down
69 changes: 69 additions & 0 deletions test/parallel/test-http-response-setheaders.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
'use strict';
const common = require('../common');
const http = require('http');
const assert = require('assert');


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

server.listen(0, common.mustCall(() => {
http.get({ port: server.address().port, headers: [] }, (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();
}));
});
}));
}

{
const server = http.createServer({ requireHostHeader: false }, common.mustCall((req, res) => {
res.setHeaders({
foo: '1',
bar: '2'
});
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();
}));
});
}));
}

{
const server = http.createServer({ requireHostHeader: false }, common.mustCall((req, res) => {
res.writeHead(200); // headers already sent
assert.throws(() => {
res.setHeaders({
foo: 'bar',
});
}, {
code: 'ERR_HTTP_HEADERS_SENT'
});
res.end();
}));

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