Skip to content

Commit 62e4b75

Browse files
committed
Merge pull request #1 from matthauck/master
Add support for auto host rewriting and protocol rewriting
2 parents 9ece52f + 7f2f3ac commit 62e4b75

File tree

3 files changed

+106
-33
lines changed

3 files changed

+106
-33
lines changed

lib/http-proxy.js

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ module.exports.createProxyServer =
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>
4444
* hostRewrite: rewrites the location hostname on (301/302/307/308) redirects, Default: null.
45+
* autoRewrite: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.
46+
* protocolRewrite: rewrites the location protocol on (301/302/307/308) redirects to 'http' or 'https'. Default: null.
4547
* }
4648
*
4749
* NOTE: `options.ws` and `options.ssl` are optional.

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,19 @@ var redirectRegex = /^30(1|2|7|8)$/;
4747
},
4848

4949
function setRedirectHostRewrite(req, res, proxyRes, options) {
50-
if (options.hostRewrite
50+
if ((options.hostRewrite || options.autoRewrite || options.protocolRewrite)
5151
&& proxyRes.headers['location']
5252
&& redirectRegex.test(proxyRes.statusCode)) {
5353
var u = url.parse(proxyRes.headers['location']);
54-
u.host = options.hostRewrite;
54+
if (options.hostRewrite) {
55+
u.host = options.hostRewrite;
56+
} else if (options.autoRewrite) {
57+
u.host = req.headers['host'];
58+
}
59+
if (options.protocolRewrite) {
60+
u.protocol = options.protocolRewrite;
61+
}
62+
5563
proxyRes.headers['location'] = u.format();
5664
}
5765
},

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

+94-31
Original file line numberDiff line numberDiff line change
@@ -3,55 +3,118 @@ var httpProxy = require('../lib/http-proxy/passes/web-outgoing'),
33

44
describe('lib/http-proxy/passes/web-outgoing.js', function () {
55
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-
};
6+
beforeEach(function() {
7+
this.req = {
8+
headers: {
9+
host: "x2.com"
10+
}
11+
};
12+
this.proxyRes = {
13+
statusCode: 301,
14+
headers: {
15+
location: "http://f.com/"
16+
}
17+
};
18+
});
1419

20+
context('rewrites location host with hostRewrite', function() {
21+
beforeEach(function() {
1522
this.options = {
1623
hostRewrite: "x.com"
1724
};
1825
});
26+
[301, 302, 307, 308].forEach(function(code) {
27+
it('on ' + code, function() {
28+
this.proxyRes.statusCode = code;
29+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
30+
expect(this.proxyRes.headers.location).to.eql('http://'+this.options.hostRewrite+'/');
31+
});
32+
});
1933

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+'/');
34+
it('not on 200', function() {
35+
this.proxyRes.statusCode = 200;
36+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
37+
expect(this.proxyRes.headers.location).to.eql('http://f.com/');
2438
});
2539

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+'/');
40+
it('not when hostRewrite is unset', function() {
41+
delete this.options.hostRewrite;
42+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
43+
expect(this.proxyRes.headers.location).to.eql('http://f.com/');
3044
});
3145

32-
it('on 307', function() {
33-
this.proxyRes.statusCode = 307;
34-
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
46+
it('takes precedence over autoRewrite', function() {
47+
this.options.autoRewrite = true;
48+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
3549
expect(this.proxyRes.headers.location).to.eql('http://'+this.options.hostRewrite+'/');
3650
});
51+
});
3752

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+'/');
53+
context('rewrites location host with autoRewrite', function() {
54+
beforeEach(function() {
55+
this.options = {
56+
autoRewrite: true,
57+
};
58+
});
59+
[301, 302, 307, 308].forEach(function(code) {
60+
it('on ' + code, function() {
61+
this.proxyRes.statusCode = code;
62+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
63+
expect(this.proxyRes.headers.location).to.eql('http://'+this.req.headers.host+'/');
64+
});
4265
});
4366

4467
it('not on 200', function() {
4568
this.proxyRes.statusCode = 200;
46-
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, this.options);
69+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
4770
expect(this.proxyRes.headers.location).to.eql('http://f.com/');
4871
});
4972

50-
it('not when hostRewrite is unset', function() {
51-
httpProxy.setRedirectHostRewrite({}, {}, this.proxyRes, {});
73+
it('not when autoRewrite is unset', function() {
74+
delete this.options.autoRewrite;
75+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
5276
expect(this.proxyRes.headers.location).to.eql('http://f.com/');
5377
});
5478
});
79+
80+
context('rewrites location protocol with protocolRewrite', function() {
81+
beforeEach(function() {
82+
this.options = {
83+
protocolRewrite: 'https',
84+
};
85+
});
86+
[301, 302, 307, 308].forEach(function(code) {
87+
it('on ' + code, function() {
88+
this.proxyRes.statusCode = code;
89+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
90+
expect(this.proxyRes.headers.location).to.eql('https://f.com/');
91+
});
92+
});
93+
94+
it('not on 200', function() {
95+
this.proxyRes.statusCode = 200;
96+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
97+
expect(this.proxyRes.headers.location).to.eql('http://f.com/');
98+
});
99+
100+
it('not when protocolRewrite is unset', function() {
101+
delete this.options.protocolRewrite;
102+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
103+
expect(this.proxyRes.headers.location).to.eql('http://f.com/');
104+
});
105+
106+
it('works together with hostRewrite', function() {
107+
this.options.hostRewrite = 'x.com'
108+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
109+
expect(this.proxyRes.headers.location).to.eql('https://x.com/');
110+
});
111+
112+
it('works together with autoRewrite', function() {
113+
this.options.autoRewrite = true
114+
httpProxy.setRedirectHostRewrite(this.req, {}, this.proxyRes, this.options);
115+
expect(this.proxyRes.headers.location).to.eql('https://x2.com/');
116+
});
117+
});
55118
});
56119

57120
describe('#setConnection', function () {
@@ -64,7 +127,7 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
64127
}
65128
}, {}, proxyRes);
66129

67-
expect(proxyRes.headers.connection).to.eql('close');
130+
expect(proxyRes.headers.connection).to.eql('close');
68131
});
69132

70133
it('set the right connection with 1.0 - req.connection', function() {
@@ -76,7 +139,7 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
76139
}
77140
}, {}, proxyRes);
78141

79-
expect(proxyRes.headers.connection).to.eql('hey');
142+
expect(proxyRes.headers.connection).to.eql('hey');
80143
});
81144

82145
it('set the right connection - req.connection', function() {
@@ -88,7 +151,7 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
88151
}
89152
}, {}, proxyRes);
90153

91-
expect(proxyRes.headers.connection).to.eql('hola');
154+
expect(proxyRes.headers.connection).to.eql('hola');
92155
});
93156

94157
it('set the right connection - `keep-alive`', function() {
@@ -100,7 +163,7 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
100163
}
101164
}, {}, proxyRes);
102165

103-
expect(proxyRes.headers.connection).to.eql('keep-alive');
166+
expect(proxyRes.headers.connection).to.eql('keep-alive');
104167
});
105168

106169
});
@@ -153,4 +216,4 @@ describe('lib/http-proxy/passes/web-outgoing.js', function () {
153216
});
154217

155218
});
156-
219+

0 commit comments

Comments
 (0)