Skip to content

Commit

Permalink
Merge pull request #741 from samccone/sjs/redirect-host-rewrite
Browse files Browse the repository at this point in the history
Allow optional redirect host rewriting.
  • Loading branch information
jcrugzz committed Nov 25, 2014
2 parents 3194d81 + add8133 commit 95a5887
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,7 @@ proxyServer.listen(8015);
* **secure**: true/false, if you want to verify the SSL Certs
* **xfwd**: true/false, adds x-forward headers
* **toProxy**: passes the absolute URL as the `path` (useful for proxying to proxies)
* **hostRewrite**: rewrites the location hostname on (301/302/307/308) redirects.

If you are using the `proxyServer.listen` method, the following options are also applicable:

Expand Down
1 change: 1 addition & 0 deletions lib/http-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ module.exports.createProxyServer =
* prependPath: <true/false, Default: true - specify whether you want to prepend the target's path to the proxy path>
* localAddress : <Local interface string to bind for outgoing connections>
* changeOrigin: <true/false, Default: false - changes the origin of the host header to the target URL>
* hostRewrite: rewrites the location hostname on (301/302/307/308) redirects, Default: null.
* }
*
* NOTE: `options.ws` and `options.ssl` are optional.
Expand Down
2 changes: 1 addition & 1 deletion lib/http-proxy/passes/web-incoming.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ web_o = Object.keys(web_o).map(function(pass) {
proxyReq.on('response', function(proxyRes) {
if(server) { server.emit('proxyRes', proxyRes, req, res); }
for(var i=0; i < web_o.length; i++) {
if(web_o[i](req, res, proxyRes)) { break; }
if(web_o[i](req, res, proxyRes, options)) { break; }
}

// Allow us to listen when the proxy has completed
Expand Down
12 changes: 10 additions & 2 deletions lib/http-proxy/passes/web-outgoing.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var passes = exports;

var url = require('url')
var passes = exports;
var redirectRegex = /^30(1|2|7|8)$/;
/*!
* Array of passes.
*
Expand Down Expand Up @@ -43,6 +44,13 @@ var passes = exports;
}
},

function setRedirectHostRewrite(req, res, proxyRes, options) {
if (options.hostRewrite && redirectRegex.test(proxyRes.statusCode)) {
var u = url.parse(proxyRes.headers['location']);
u.host = options.hostRewrite;
proxyRes.headers['location'] = u.format();
}
},
/**
* Copy headers from proxyResponse to response
* set each header in response object.
Expand Down
52 changes: 52 additions & 0 deletions test/lib-http-proxy-passes-web-outgoing-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,58 @@ var httpProxy = require('../lib/http-proxy/passes/web-outgoing'),
expect = require('expect.js');

describe('lib/http-proxy/passes/web-outgoing.js', function () {
describe('#setRedirectHostRewrite', function () {
context('rewrites location host to option', function() {
beforeEach(function() {
this.proxyRes = {
statusCode: 301,
headers: {
location: "http://f.com/"
}
};

this.options = {
hostRewrite: "x.com"
};
});

it('on 301', function() {
this.proxyRes.statusCode = 301;
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://'+this.options.hostRewrite+'/');
});

it('on 302', function() {
this.proxyRes.statusCode = 302;
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://'+this.options.hostRewrite+'/');
});

it('on 307', function() {
this.proxyRes.statusCode = 307;
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://'+this.options.hostRewrite+'/');
});

it('on 308', function() {
this.proxyRes.statusCode = 308;
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://'+this.options.hostRewrite+'/');
});

it('not on 200', function() {
this.proxyRes.statusCode = 200;
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
expect(this.proxyRes.headers.location).to.eql('http://f.com/');
});

it('not when hostRewrite is unset', function() {
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, {});
expect(this.proxyRes.headers.location).to.eql('http://f.com/');
});
});
});

describe('#setConnection', function () {
it('set the right connection with 1.0 - `close`', function() {
var proxyRes = { headers: {} };
Expand Down

0 comments on commit 95a5887

Please sign in to comment.