Skip to content

Commit 6631860

Browse files
marco-ippolitorichardlau
authored andcommitted
http: split set-cookie when using setHeaders
PR-URL: #51649 Fixes: #51599 Reviewed-By: Paolo Insogna <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Akhil Marsonya <[email protected]> Reviewed-By: Minwoo Jung <[email protected]>
1 parent 491f9f9 commit 6631860

File tree

2 files changed

+64
-2
lines changed

2 files changed

+64
-2
lines changed

lib/_http_outgoing.js

+21-2
Original file line numberDiff line numberDiff line change
@@ -684,8 +684,27 @@ OutgoingMessage.prototype.setHeaders = function setHeaders(headers) {
684684
throw new ERR_INVALID_ARG_TYPE('headers', ['Headers', 'Map'], headers);
685685
}
686686

687-
for (const key of headers.keys()) {
688-
this.setHeader(key, headers.get(key));
687+
// Headers object joins multiple cookies with a comma when using
688+
// the getter to retrieve the value,
689+
// unless iterating over the headers directly.
690+
// We also cannot safely split by comma.
691+
// To avoid setHeader overwriting the previous value we push
692+
// set-cookie values in array and set them all at once.
693+
const cookies = [];
694+
695+
for (const { 0: key, 1: value } of headers) {
696+
if (key === 'set-cookie') {
697+
if (ArrayIsArray(value)) {
698+
cookies.push(...value);
699+
} else {
700+
cookies.push(value);
701+
}
702+
continue;
703+
}
704+
this.setHeader(key, value);
705+
}
706+
if (cookies.length) {
707+
this.setHeader('set-cookie', cookies);
689708
}
690709

691710
return this;

test/parallel/test-http-response-setheaders.js

+43
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,46 @@ const assert = require('assert');
129129
});
130130
}));
131131
}
132+
133+
{
134+
const server = http.createServer({ requireHostHeader: false }, common.mustCall((req, res) => {
135+
const headers = new Headers();
136+
headers.append('Set-Cookie', 'a=b');
137+
headers.append('Set-Cookie', 'c=d');
138+
res.setHeaders(headers);
139+
res.end();
140+
}));
141+
142+
server.listen(0, common.mustCall(() => {
143+
http.get({ port: server.address().port }, (res) => {
144+
assert(Array.isArray(res.headers['set-cookie']));
145+
assert.strictEqual(res.headers['set-cookie'].length, 2);
146+
assert.strictEqual(res.headers['set-cookie'][0], 'a=b');
147+
assert.strictEqual(res.headers['set-cookie'][1], 'c=d');
148+
res.resume().on('end', common.mustCall(() => {
149+
server.close();
150+
}));
151+
});
152+
}));
153+
}
154+
155+
{
156+
const server = http.createServer({ requireHostHeader: false }, common.mustCall((req, res) => {
157+
const headers = new Map();
158+
headers.set('Set-Cookie', ['a=b', 'c=d']);
159+
res.setHeaders(headers);
160+
res.end();
161+
}));
162+
163+
server.listen(0, common.mustCall(() => {
164+
http.get({ port: server.address().port }, (res) => {
165+
assert(Array.isArray(res.headers['set-cookie']));
166+
assert.strictEqual(res.headers['set-cookie'].length, 2);
167+
assert.strictEqual(res.headers['set-cookie'][0], 'a=b');
168+
assert.strictEqual(res.headers['set-cookie'][1], 'c=d');
169+
res.resume().on('end', common.mustCall(() => {
170+
server.close();
171+
}));
172+
});
173+
}));
174+
}

0 commit comments

Comments
 (0)