Skip to content

Commit 961f457

Browse files
pachireljcrugzz
authored andcommitted
[WIP] Revert default behavior of writeHeaders method (#1104)
* Replace header key only * Add preserveHeaderKeyCase Option
1 parent ac1a01b commit 961f457

File tree

5 files changed

+32
-20
lines changed

5 files changed

+32
-20
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ proxyServer.listen(8015);
333333
* **ignorePath**: true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request (note: you will have to append / manually if required).
334334
* **localAddress**: Local interface string to bind for outgoing connections
335335
* **changeOrigin**: true/false, Default: false - changes the origin of the host header to the target URL
336+
* **preserveHeaderKeyCase**: true/false, Default: false - specify whether you want to keep letter case of response header key
336337
* **auth**: Basic authentication i.e. 'user:password' to compute an Authorization header.
337338
* **hostRewrite**: rewrites the location hostname on (201/301/302/307/308) redirects.
338339
* **autoRewrite**: rewrites the location host/port on (201/301/302/307/308) redirects based on requested host/port. Default: false.

lib/http-proxy.js

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ function createProxyServer(options) {
3535
* ignorePath: <true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request>
3636
* localAddress : <Local interface string to bind for outgoing connections>
3737
* changeOrigin: <true/false, Default: false - changes the origin of the host header to the target URL>
38+
* preserveHeaderKeyCase: <true/false, Default: false - specify whether you want to keep letter case of response header key >
3839
* auth : Basic authentication i.e. 'user:password' to compute an Authorization header.
3940
* hostRewrite: rewrites the location hostname on (301/302/307/308) redirects, Default: null.
4041
* autoRewrite: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.

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

+15-19
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,14 @@ 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 = [],
87+
preserveHeaderKeyCase = options.preserveHeaderKeyCase,
88+
rawHeaderKeyMap,
9089
setHeader = function(key, header) {
9190
if (header == undefined) return;
92-
if (key.toLowerCase() !== 'set-cookie') {
93-
return res.setHeader(String(key).trim(), header);
94-
}
95-
if (rewriteCookieDomainConfig) {
91+
if (rewriteCookieDomainConfig && key.toLowerCase() === 'set-cookie') {
9692
header = common.rewriteCookieDomain(header, rewriteCookieDomainConfig);
9793
}
98-
setCookies.push(header); // defer to the end when we have all of them
94+
res.setHeader(String(key).trim(), header);
9995
};
10096

10197
if (typeof rewriteCookieDomainConfig === 'string') { //also test for ''
@@ -104,21 +100,21 @@ module.exports = { // <--
104100

105101
// message.rawHeaders is added in: v0.11.6
106102
// https://nodejs.org/api/http.html#http_message_rawheaders
107-
if (proxyRes.rawHeaders != undefined) {
103+
if (preserveHeaderKeyCase && proxyRes.rawHeaders != undefined) {
104+
rawHeaderKeyMap = {};
108105
for (var i = 0; i < proxyRes.rawHeaders.length; i += 2) {
109106
var key = proxyRes.rawHeaders[i];
110-
var header = proxyRes.rawHeaders[i + 1];
111-
setHeader(key, header);
107+
rawHeaderKeyMap[key.toLowerCase()] = key;
112108
}
113-
} else {
114-
Object.keys(proxyRes.headers).forEach(function(key) {
115-
var header = proxyRes.headers[key];
116-
setHeader(key, header);
117-
});
118-
}
119-
if (setCookies.length) {
120-
res.setHeader('Set-Cookie', setCookies.length === 1 ? setCookies[0] : setCookies);
121109
}
110+
111+
Object.keys(proxyRes.headers).forEach(function(key) {
112+
var header = proxyRes.headers[key];
113+
if (preserveHeaderKeyCase && rawHeaderKeyMap) {
114+
key = rawHeaderKeyMap[key] || key;
115+
}
116+
setHeader(key, header);
117+
});
122118
},
123119

124120
/**

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

+13
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,14 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
240240
}
241241
};
242242
this.rawProxyRes = {
243+
headers: {
244+
hey: 'hello',
245+
how: 'are you?',
246+
'set-cookie': [
247+
'hello; domain=my.domain; path=/',
248+
'there; domain=my.domain; path=/'
249+
]
250+
},
243251
rawHeaders: [
244252
'Hey', 'hello',
245253
'How', 'are you?',
@@ -343,6 +351,11 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
343351
'my.special.domain': 'my.special.domain'
344352
}
345353
};
354+
this.rawProxyRes.headers['set-cookie'] = [
355+
'hello-on-my.domain; domain=my.domain; path=/',
356+
'hello-on-my.old.domain; domain=my.old.domain; path=/',
357+
'hello-on-my.special.domain; domain=my.special.domain; path=/'
358+
];
346359
this.rawProxyRes.rawHeaders = this.rawProxyRes.rawHeaders.concat([
347360
'Set-Cookie',
348361
'hello-on-my.domain; domain=my.domain; path=/',

test/lib-http-proxy-test.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ describe('lib/http-proxy.js', function() {
130130
it('should make the request, handle response and finish it', function(done) {
131131
var ports = { source: gen.port, proxy: gen.port };
132132
var proxy = httpProxy.createProxyServer({
133-
target: 'http://127.0.0.1:' + ports.source
133+
target: 'http://127.0.0.1:' + ports.source,
134+
preserveHeaderKeyCase: true
134135
}).listen(ports.proxy);
135136

136137
var source = http.createServer(function(req, res) {

0 commit comments

Comments
 (0)