Skip to content

Commit 8cb451f

Browse files
Kris Williamsjcrugzz
Kris Williams
authored andcommitted
Enable proxy response to have multiple Set-Cookie raw headers #1101
1 parent c252b32 commit 8cb451f

File tree

5 files changed

+72
-21
lines changed

5 files changed

+72
-21
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

+14-6
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,18 @@ 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+
setCookies = [],
8790
setHeader = function(key, header) {
88-
if (header != undefined) {
89-
if (rewriteCookieDomainConfig && key.toLowerCase() === 'set-cookie') {
90-
header = common.rewriteCookieDomain(header, rewriteCookieDomainConfig);
91-
}
92-
res.setHeader(String(key).trim(), header);
91+
if (header == undefined) return;
92+
if (key.toLowerCase() !== 'set-cookie') {
93+
return res.setHeader(String(key).trim(), header);
9394
}
95+
if (rewriteCookieDomainConfig) {
96+
header = common.rewriteCookieDomain(header, rewriteCookieDomainConfig);
97+
}
98+
setCookies.push(header); // defer to the end when we have all of them
9499
};
95100

96101
if (typeof rewriteCookieDomainConfig === 'string') { //also test for ''
@@ -104,13 +109,16 @@ module.exports = { // <--
104109
var key = proxyRes.rawHeaders[i];
105110
var header = proxyRes.rawHeaders[i + 1];
106111
setHeader(key, header);
107-
};
112+
}
108113
} else {
109114
Object.keys(proxyRes.headers).forEach(function(key) {
110115
var header = proxyRes.headers[key];
111116
setHeader(key, header);
112117
});
113118
}
119+
if (setCookies.length) {
120+
res.setHeader('Set-Cookie', setCookies.length === 1 ? setCookies[0] : setCookies);
121+
}
114122
},
115123

116124
/**

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)