mirror of
https://github.com/http-party/node-http-proxy.git
synced 2025-12-08 20:59:18 +00:00
cookieDomainRewrite option (#1009)
This commit is contained in:
parent
9d06ca99d3
commit
1e52f660f0
12
README.md
12
README.md
@ -337,6 +337,18 @@ proxyServer.listen(8015);
|
||||
* **hostRewrite**: rewrites the location hostname on (201/301/302/307/308) redirects.
|
||||
* **autoRewrite**: rewrites the location host/port on (201/301/302/307/308) redirects based on requested host/port. Default: false.
|
||||
* **protocolRewrite**: rewrites the location protocol on (201/301/302/307/308) redirects to 'http' or 'https'. Default: null.
|
||||
* **cookieDomainRewrite**: rewrites domain of `set-cookie` headers. Possible values:
|
||||
* `false` (default): disable cookie rewriting
|
||||
* String: new domain, for example `cookieDomainRewrite: "new.domain"`. To remove the domain, use `cookieDomainRewrite: ""`.
|
||||
* Object: mapping of domains to new domains, use `"*"` to match all domains.
|
||||
For example keep one domain unchanged, rewrite one domain and remove other domains:
|
||||
```
|
||||
cookieDomainRewrite: {
|
||||
"unchanged.domain": "unchanged.domain",
|
||||
"old.domain": "new.domain",
|
||||
"*": ""
|
||||
}
|
||||
```
|
||||
* **headers**: object with extra headers to be added to target requests.
|
||||
|
||||
**NOTE:**
|
||||
|
||||
@ -4,7 +4,8 @@ var common = exports,
|
||||
required = require('requires-port');
|
||||
|
||||
var upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i,
|
||||
isSSL = /^https|wss/;
|
||||
isSSL = /^https|wss/,
|
||||
cookieDomainRegex = /(;\s*domain=)([^;]+)/i;
|
||||
|
||||
/**
|
||||
* Simple Regex for testing if protocol is https
|
||||
@ -201,6 +202,41 @@ common.urlJoin = function() {
|
||||
return retSegs.join('?')
|
||||
};
|
||||
|
||||
/**
|
||||
* Rewrites or removes the domain of a cookie header
|
||||
*
|
||||
* @param {String|Array} Header
|
||||
* @param {Object} Config, mapping of domain to rewritten domain.
|
||||
* '*' key to match any domain, null value to remove the domain.
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
common.rewriteCookieDomain = function rewriteCookieDomain(header, config) {
|
||||
if (Array.isArray(header)) {
|
||||
return header.map(function (headerElement) {
|
||||
return rewriteCookieDomain(headerElement, config);
|
||||
});
|
||||
}
|
||||
return header.replace(cookieDomainRegex, function(match, prefix, previousDomain) {
|
||||
var newDomain;
|
||||
if (previousDomain in config) {
|
||||
newDomain = config[previousDomain];
|
||||
} else if ('*' in config) {
|
||||
newDomain = config['*'];
|
||||
} else {
|
||||
//no match, return previous domain
|
||||
return match;
|
||||
}
|
||||
if (newDomain) {
|
||||
//replace domain
|
||||
return prefix + newDomain;
|
||||
} else {
|
||||
//remove domain
|
||||
return '';
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Check the host and see if it potentially has a port in it (keep it simple)
|
||||
*
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
var url = require('url'),
|
||||
common = require('../common'),
|
||||
passes = exports;
|
||||
|
||||
var redirectRegex = /^201|30(1|2|7|8)$/;
|
||||
@ -77,13 +78,22 @@ var redirectRegex = /^201|30(1|2|7|8)$/;
|
||||
* @param {ClientRequest} Req Request object
|
||||
* @param {IncomingMessage} Res Response object
|
||||
* @param {proxyResponse} Res Response object from the proxy request
|
||||
* @param {Object} Options options.cookieDomainRewrite: Config to rewrite cookie domain
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
function writeHeaders(req, res, proxyRes) {
|
||||
function writeHeaders(req, res, proxyRes, options) {
|
||||
var rewriteCookieDomainConfig = options.cookieDomainRewrite;
|
||||
if (typeof rewriteCookieDomainConfig === 'string') { //also test for ''
|
||||
rewriteCookieDomainConfig = { '*': rewriteCookieDomainConfig };
|
||||
}
|
||||
Object.keys(proxyRes.headers).forEach(function(key) {
|
||||
if(proxyRes.headers[key] != undefined){
|
||||
res.setHeader(String(key).trim(), proxyRes.headers[key]);
|
||||
var header = proxyRes.headers[key];
|
||||
if (header != undefined) {
|
||||
if (rewriteCookieDomainConfig && key.toLowerCase() === 'set-cookie') {
|
||||
header = common.rewriteCookieDomain(header, rewriteCookieDomainConfig);
|
||||
}
|
||||
res.setHeader(String(key).trim(), header);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@ -6,23 +6,23 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
|
||||
beforeEach(function() {
|
||||
this.req = {
|
||||
headers: {
|
||||
host: "ext-auto.com"
|
||||
host: 'ext-auto.com'
|
||||
}
|
||||
};
|
||||
this.proxyRes = {
|
||||
statusCode: 301,
|
||||
headers: {
|
||||
location: "http://backend.com/"
|
||||
location: 'http://backend.com/'
|
||||
}
|
||||
};
|
||||
this.options = {
|
||||
target: "http://backend.com"
|
||||
target: 'http://backend.com'
|
||||
};
|
||||
});
|
||||
|
||||
context('rewrites location host with hostRewrite', function() {
|
||||
beforeEach(function() {
|
||||
this.options.hostRewrite = "ext-manual.com";
|
||||
this.options.hostRewrite = 'ext-manual.com';
|
||||
});
|
||||
[201, 301, 302, 307, 308].forEach(function(code) {
|
||||
it('on ' + code, function() {
|
||||
@ -52,14 +52,14 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
|
||||
|
||||
it('not when the redirected location does not match target host', function() {
|
||||
this.proxyRes.statusCode = 302;
|
||||
this.proxyRes.headers.location = "http://some-other/";
|
||||
this.proxyRes.headers.location = 'http://some-other/';
|
||||
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
|
||||
expect(this.proxyRes.headers.location).to.eql('http://some-other/');
|
||||
});
|
||||
|
||||
it('not when the redirected location does not match target port', function() {
|
||||
this.proxyRes.statusCode = 302;
|
||||
this.proxyRes.headers.location = "http://backend.com:8080/";
|
||||
this.proxyRes.headers.location = 'http://backend.com:8080/';
|
||||
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
|
||||
expect(this.proxyRes.headers.location).to.eql('http://backend.com:8080/');
|
||||
});
|
||||
@ -91,14 +91,14 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
|
||||
|
||||
it('not when the redirected location does not match target host', function() {
|
||||
this.proxyRes.statusCode = 302;
|
||||
this.proxyRes.headers.location = "http://some-other/";
|
||||
this.proxyRes.headers.location = 'http://some-other/';
|
||||
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
|
||||
expect(this.proxyRes.headers.location).to.eql('http://some-other/');
|
||||
});
|
||||
|
||||
it('not when the redirected location does not match target port', function() {
|
||||
this.proxyRes.statusCode = 302;
|
||||
this.proxyRes.headers.location = "http://backend.com:8080/";
|
||||
this.proxyRes.headers.location = 'http://backend.com:8080/';
|
||||
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
|
||||
expect(this.proxyRes.headers.location).to.eql('http://backend.com:8080/');
|
||||
});
|
||||
@ -129,13 +129,13 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
|
||||
});
|
||||
|
||||
it('works together with hostRewrite', function() {
|
||||
this.options.hostRewrite = 'ext-manual.com'
|
||||
this.options.hostRewrite = 'ext-manual.com';
|
||||
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
|
||||
expect(this.proxyRes.headers.location).to.eql('https://ext-manual.com/');
|
||||
});
|
||||
|
||||
it('works together with autoRewrite', function() {
|
||||
this.options.autoRewrite = true
|
||||
this.options.autoRewrite = true;
|
||||
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
|
||||
expect(this.proxyRes.headers.location).to.eql('https://ext-auto.com/');
|
||||
});
|
||||
@ -199,31 +199,89 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
|
||||
writeHead: function(n) {
|
||||
expect(n).to.eql(200);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
httpProxy.writeStatusCode({}, res, { statusCode: 200 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('#writeHeaders', function() {
|
||||
var proxyRes = {
|
||||
headers: {
|
||||
hey: 'hello',
|
||||
how: 'are you?'
|
||||
}
|
||||
};
|
||||
beforeEach(function() {
|
||||
this.proxyRes = {
|
||||
headers: {
|
||||
hey: 'hello',
|
||||
how: 'are you?',
|
||||
'set-cookie': 'hello; domain=my.domain; path=/'
|
||||
}
|
||||
};
|
||||
this.res = {
|
||||
setHeader: function(k, v) {
|
||||
this.headers[k] = v;
|
||||
},
|
||||
headers: {}
|
||||
};
|
||||
});
|
||||
|
||||
var res = {
|
||||
setHeader: function(k, v) {
|
||||
this.headers[k] = v;
|
||||
},
|
||||
headers: {}
|
||||
};
|
||||
it('writes headers', function() {
|
||||
var options = {};
|
||||
|
||||
httpProxy.writeHeaders({}, res, proxyRes);
|
||||
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
|
||||
|
||||
expect(res.headers.hey).to.eql('hello');
|
||||
expect(res.headers.how).to.eql('are you?');
|
||||
expect(this.res.headers.hey).to.eql('hello');
|
||||
expect(this.res.headers.how).to.eql('are you?');
|
||||
});
|
||||
|
||||
it('does not rewrite domain', function() {
|
||||
var options = {};
|
||||
|
||||
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
|
||||
|
||||
expect(this.res.headers['set-cookie']).to.eql('hello; domain=my.domain; path=/');
|
||||
});
|
||||
|
||||
it('rewrites domain', function() {
|
||||
var options = {
|
||||
cookieDomainRewrite: 'my.new.domain'
|
||||
};
|
||||
|
||||
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
|
||||
|
||||
expect(this.res.headers['set-cookie']).to.eql('hello; domain=my.new.domain; path=/');
|
||||
});
|
||||
|
||||
it('removes domain', function() {
|
||||
var options = {
|
||||
cookieDomainRewrite: ''
|
||||
};
|
||||
|
||||
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
|
||||
|
||||
expect(this.res.headers['set-cookie']).to.eql('hello; path=/');
|
||||
});
|
||||
|
||||
it('rewrites headers with advanced configuration', function() {
|
||||
var options = {
|
||||
cookieDomainRewrite: {
|
||||
'*': '',
|
||||
'my.old.domain': 'my.new.domain',
|
||||
'my.special.domain': 'my.special.domain'
|
||||
}
|
||||
};
|
||||
this.proxyRes.headers['set-cookie'] = [
|
||||
'hello-on-my.domain; domain=my.domain; path=/',
|
||||
'hello-on-my.old.domain; domain=my.old.domain; path=/',
|
||||
'hello-on-my.special.domain; domain=my.special.domain; path=/'
|
||||
];
|
||||
|
||||
httpProxy.writeHeaders({}, this.res, this.proxyRes, options);
|
||||
|
||||
expect(this.res.headers['set-cookie'])
|
||||
.to.contain('hello-on-my.domain; path=/');
|
||||
expect(this.res.headers['set-cookie'])
|
||||
.to.contain('hello-on-my.old.domain; domain=my.new.domain; path=/');
|
||||
expect(this.res.headers['set-cookie'])
|
||||
.to.contain('hello-on-my.special.domain; domain=my.special.domain; path=/');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user