Skip to content

Commit e4a7498

Browse files
author
Kris Williams
committed
Enable proxy response to have multiple Set-Cookie raw headers http-party#1101
1 parent c252b32 commit e4a7498

File tree

5 files changed

+73
-20
lines changed

5 files changed

+73
-20
lines changed

examples/http/proxy-https-to-http.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ var https = require('https'),
3939
http.createServer(function (req, res) {
4040
res.writeHead(200, { 'Content-Type': 'text/plain' });
4141
res.write('hello http over https\n');
42-
res.end();
42+
res.end();
4343
}).listen(9009);
4444

4545
//

examples/http/proxy-https-to-https.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ var https = require('https'),
4343
https.createServer(httpsOpts, function (req, res) {
4444
res.writeHead(200, { 'Content-Type': 'text/plain' });
4545
res.write('hello https\n');
46-
res.end();
46+
res.end();
4747
}).listen(9010);
4848

4949
//

lib/http-proxy/passes/web-outgoing.js

+15-5
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,19 @@ module.exports = { // <--
8484
*/
8585
writeHeaders: function writeHeaders(req, res, proxyRes, options) {
8686
var rewriteCookieDomainConfig = options.cookieDomainRewrite,
87+
// In proxyRes.rawHeaders Set-Cookie headers are sparse.
88+
// so, we'll collect Set-Cookie headers, and set them in the response as an array.
89+
set_cookies = [],
8790
setHeader = function(key, header) {
8891
if (header != undefined) {
89-
if (rewriteCookieDomainConfig && key.toLowerCase() === 'set-cookie') {
90-
header = common.rewriteCookieDomain(header, rewriteCookieDomainConfig);
92+
if (key === 'Set-Cookie' || key === 'set-cookie') {
93+
if (rewriteCookieDomainConfig) {
94+
header = common.rewriteCookieDomain(header, rewriteCookieDomainConfig);
95+
}
96+
set_cookies.push(header); // defer
97+
} else {
98+
res.setHeader(String(key).trim(), header);
9199
}
92-
res.setHeader(String(key).trim(), header);
93100
}
94101
};
95102

@@ -99,18 +106,21 @@ module.exports = { // <--
99106

100107
// message.rawHeaders is added in: v0.11.6
101108
// https://nodejs.org/api/http.html#http_message_rawheaders
102-
if (proxyRes.rawHeaders != undefined) {
109+
if (proxyRes.rawHeaders !== undefined) {
103110
for (var i = 0; i < proxyRes.rawHeaders.length; i += 2) {
104111
var key = proxyRes.rawHeaders[i];
105112
var header = proxyRes.rawHeaders[i + 1];
106113
setHeader(key, header);
107-
};
114+
}
108115
} else {
109116
Object.keys(proxyRes.headers).forEach(function(key) {
110117
var header = proxyRes.headers[key];
111118
setHeader(key, header);
112119
});
113120
}
121+
if (set_cookies.length) {
122+
res.setHeader('Set-Cookie', set_cookies.length === 1 ? set_cookies[0] : set_cookies);
123+
}
114124
},
115125

116126
/**

test/lib-http-proxy-passes-web-outgoing-test.js

+55-12
Original file line numberDiff line numberDiff line change
@@ -233,12 +233,18 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
233233
headers: {
234234
hey: 'hello',
235235
how: 'are you?',
236-
'set-cookie': 'hello; domain=my.domain; path=/'
237-
},
236+
'set-cookie': [
237+
'hello; domain=my.domain; path=/',
238+
'there; domain=my.domain; path=/'
239+
]
240+
}
241+
};
242+
this.rawProxyRes = {
238243
rawHeaders: [
239244
'Hey', 'hello',
240245
'How', 'are you?',
241-
'Set-Cookie', 'hello; domain=my.domain; path=/'
246+
'Set-Cookie', 'hello; domain=my.domain; path=/',
247+
'Set-Cookie', 'there; domain=my.domain; path=/'
242248
]
243249
};
244250
this.res = {
@@ -253,19 +259,35 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
253259

254260
it('writes headers', function() {
255261
var options = {};
256-
257262
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
258263

259264
expect(this.res.headers.hey).to.eql('hello');
260265
expect(this.res.headers.how).to.eql('are you?');
266+
267+
expect(this.res.headers).to.have.key('set-cookie');
268+
expect(this.res.headers['set-cookie']).to.be.an(Array);
269+
expect(this.res.headers['set-cookie']).to.have.length(2);
270+
});
271+
272+
it('writes raw headers', function() {
273+
var options = {};
274+
httpProxy.writeHeaders({}, this.res, this.rawProxyRes, options);
275+
276+
expect(this.res.headers.hey).to.eql('hello');
277+
expect(this.res.headers.how).to.eql('are you?');
278+
279+
expect(this.res.headers).to.have.key('set-cookie');
280+
expect(this.res.headers['set-cookie']).to.be.an(Array);
281+
expect(this.res.headers['set-cookie']).to.have.length(2);
261282
});
262283

263284
it('does not rewrite domain', function() {
264285
var options = {};
265286

266287
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
267288

268-
expect(this.res.headers['set-cookie']).to.eql('hello; domain=my.domain; path=/');
289+
expect(this.res.headers['set-cookie'])
290+
.to.contain('hello; domain=my.domain; path=/');
269291
});
270292

271293
it('rewrites domain', function() {
@@ -275,7 +297,8 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
275297

276298
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
277299

278-
expect(this.res.headers['set-cookie']).to.eql('hello; domain=my.new.domain; path=/');
300+
expect(this.res.headers['set-cookie'])
301+
.to.contain('hello; domain=my.new.domain; path=/');
279302
});
280303

281304
it('removes domain', function() {
@@ -285,7 +308,8 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
285308

286309
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
287310

288-
expect(this.res.headers['set-cookie']).to.eql('hello; path=/');
311+
expect(this.res.headers['set-cookie'])
312+
.to.contain('hello; path=/');
289313
});
290314

291315
it('rewrites headers with advanced configuration', function() {
@@ -301,14 +325,33 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
301325
'hello-on-my.old.domain; domain=my.old.domain; path=/',
302326
'hello-on-my.special.domain; domain=my.special.domain; path=/'
303327
];
304-
var setCookieValueIndex = this.proxyRes.rawHeaders.indexOf('Set-Cookie') + 1;
305-
this.proxyRes.rawHeaders[setCookieValueIndex] = [
328+
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
329+
330+
expect(this.res.headers['set-cookie'])
331+
.to.contain('hello-on-my.domain; path=/');
332+
expect(this.res.headers['set-cookie'])
333+
.to.contain('hello-on-my.old.domain; domain=my.new.domain; path=/');
334+
expect(this.res.headers['set-cookie'])
335+
.to.contain('hello-on-my.special.domain; domain=my.special.domain; path=/');
336+
});
337+
338+
it('rewrites raw headers with advanced configuration', function() {
339+
var options = {
340+
cookieDomainRewrite: {
341+
'*': '',
342+
'my.old.domain': 'my.new.domain',
343+
'my.special.domain': 'my.special.domain'
344+
}
345+
};
346+
this.rawProxyRes.rawHeaders = this.rawProxyRes.rawHeaders.concat([
347+
'Set-Cookie',
306348
'hello-on-my.domain; domain=my.domain; path=/',
349+
'Set-Cookie',
307350
'hello-on-my.old.domain; domain=my.old.domain; path=/',
351+
'Set-Cookie',
308352
'hello-on-my.special.domain; domain=my.special.domain; path=/'
309-
];
310-
311-
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
353+
]);
354+
httpProxy.writeHeaders({}, this.res, this.rawProxyRes, options);
312355

313356
expect(this.res.headers['set-cookie'])
314357
.to.contain('hello-on-my.domain; path=/');

test/lib-https-proxy-test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Object.defineProperty(gen, 'port', {
1919

2020
describe('lib/http-proxy.js', function() {
2121
describe('HTTPS #createProxyServer', function() {
22-
describe('HTTPS to HTTP', function () {
22+
describe('HTTPS to HTTP', function () {
2323
it('should proxy the request en send back the response', function (done) {
2424
var ports = { source: gen.port, proxy: gen.port };
2525
var source = http.createServer(function(req, res) {

0 commit comments

Comments
 (0)