Skip to content

Commit 95a5887

Browse files
committed
Merge pull request #741 from samccone/sjs/redirect-host-rewrite
Allow optional redirect host rewriting.
2 parents 3194d81 + add8133 commit 95a5887

File tree

5 files changed

+65
-3
lines changed

5 files changed

+65
-3
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ proxyServer.listen(8015);
325325
* **secure**: true/false, if you want to verify the SSL Certs
326326
* **xfwd**: true/false, adds x-forward headers
327327
* **toProxy**: passes the absolute URL as the `path` (useful for proxying to proxies)
328+
* **hostRewrite**: rewrites the location hostname on (301/302/307/308) redirects.
328329

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

Diff for: lib/http-proxy.js

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ module.exports.createProxyServer =
4141
* prependPath: <true/false, Default: true - specify whether you want to prepend the target's path to the proxy path>
4242
* localAddress : <Local interface string to bind for outgoing connections>
4343
* changeOrigin: <true/false, Default: false - changes the origin of the host header to the target URL>
44+
* hostRewrite: rewrites the location hostname on (301/302/307/308) redirects, Default: null.
4445
* }
4546
*
4647
* NOTE: `options.ws` and `options.ssl` are optional.

Diff for: lib/http-proxy/passes/web-incoming.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ web_o = Object.keys(web_o).map(function(pass) {
145145
proxyReq.on('response', function(proxyRes) {
146146
if(server) { server.emit('proxyRes', proxyRes, req, res); }
147147
for(var i=0; i < web_o.length; i++) {
148-
if(web_o[i](req, res, proxyRes)) { break; }
148+
if(web_o[i](req, res, proxyRes, options)) { break; }
149149
}
150150

151151
// Allow us to listen when the proxy has completed

Diff for: lib/http-proxy/passes/web-outgoing.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
var passes = exports;
2-
1+
var url = require('url')
2+
var passes = exports;
3+
var redirectRegex = /^30(1|2|7|8)$/;
34
/*!
45
* Array of passes.
56
*
@@ -43,6 +44,13 @@ var passes = exports;
4344
}
4445
},
4546

47+
function setRedirectHostRewrite(req, res, proxyRes, options) {
48+
if (options.hostRewrite && redirectRegex.test(proxyRes.statusCode)) {
49+
var u = url.parse(proxyRes.headers['location']);
50+
u.host = options.hostRewrite;
51+
proxyRes.headers['location'] = u.format();
52+
}
53+
},
4654
/**
4755
* Copy headers from proxyResponse to response
4856
* set each header in response object.

Diff for: test/lib-http-proxy-passes-web-outgoing-test.js

+52
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,58 @@ var httpProxy = require('../lib/http-proxy/passes/web-outgoing'),
22
expect = require('expect.js');
33

44
describe('lib/http-proxy/passes/web-outgoing.js', function () {
5+
describe('#setRedirectHostRewrite', function () {
6+
context('rewrites location host to option', function() {
7+
beforeEach(function() {
8+
this.proxyRes = {
9+
statusCode: 301,
10+
headers: {
11+
location: "http://f.com/"
12+
}
13+
};
14+
15+
this.options = {
16+
hostRewrite: "x.com"
17+
};
18+
});
19+
20+
it('on 301', function() {
21+
this.proxyRes.statusCode = 301;
22+
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
23+
expect(this.proxyRes.headers.location).to.eql('http://'+this.options.hostRewrite+'/');
24+
});
25+
26+
it('on 302', function() {
27+
this.proxyRes.statusCode = 302;
28+
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
29+
expect(this.proxyRes.headers.location).to.eql('http://'+this.options.hostRewrite+'/');
30+
});
31+
32+
it('on 307', function() {
33+
this.proxyRes.statusCode = 307;
34+
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
35+
expect(this.proxyRes.headers.location).to.eql('http://'+this.options.hostRewrite+'/');
36+
});
37+
38+
it('on 308', function() {
39+
this.proxyRes.statusCode = 308;
40+
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
41+
expect(this.proxyRes.headers.location).to.eql('http://'+this.options.hostRewrite+'/');
42+
});
43+
44+
it('not on 200', function() {
45+
this.proxyRes.statusCode = 200;
46+
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
47+
expect(this.proxyRes.headers.location).to.eql('http://f.com/');
48+
});
49+
50+
it('not when hostRewrite is unset', function() {
51+
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, {});
52+
expect(this.proxyRes.headers.location).to.eql('http://f.com/');
53+
});
54+
});
55+
});
56+
557
describe('#setConnection', function () {
658
it('set the right connection with 1.0 - `close`', function() {
759
var proxyRes = { headers: {} };

0 commit comments

Comments
 (0)