Skip to content

Commit 55286a7

Browse files
committed
[fix api] Optimize lookups in the ProxyTable. Ensure that RoutingProxy can proxy to https by default.
1 parent e2dc7f9 commit 55286a7

File tree

2 files changed

+84
-24
lines changed

2 files changed

+84
-24
lines changed

Diff for: lib/node-http-proxy/proxy-table.js

+71-19
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ var ProxyTable = exports.ProxyTable = function (options) {
4242
events.EventEmitter.call(this);
4343

4444
this.silent = options.silent || options.silent !== true;
45+
this.target = options.target || {};
4546
this.hostnameOnly = options.hostnameOnly === true;
4647

4748
if (typeof options.router === 'object') {
@@ -91,19 +92,62 @@ ProxyTable.prototype.setRoutes = function (router) {
9192
throw new Error('Cannot update ProxyTable routes without router.');
9293
}
9394

95+
var self = this;
9496
this.router = router;
9597

9698
if (this.hostnameOnly === false) {
97-
var self = this;
9899
this.routes = [];
99100

100101
Object.keys(router).forEach(function (path) {
101-
var route = new RegExp('^' + path, 'i');
102+
if (!/http[s]?/.test(router[path])) {
103+
router[path] = (self.target.https ? 'https://' : 'http://')
104+
+ router[path];
105+
}
102106

107+
var target = url.parse(router[path]),
108+
defaultPort = self.target.https ? 443 : 80;
109+
110+
//
111+
// Setup a robust lookup table for the route:
112+
//
113+
// {
114+
// source: {
115+
// regexp: /^foo.com/i,
116+
// sref: 'foo.com',
117+
// url: {
118+
// protocol: 'http:',
119+
// slashes: true,
120+
// host: 'foo.com',
121+
// hostname: 'foo.com',
122+
// href: 'http://foo.com/',
123+
// pathname: '/',
124+
// path: '/'
125+
// }
126+
// },
127+
// {
128+
// target: {
129+
// sref: '127.0.0.1:8000/',
130+
// url: {
131+
// protocol: 'http:',
132+
// slashes: true,
133+
// host: '127.0.0.1:8000',
134+
// hostname: '127.0.0.1',
135+
// href: 'http://127.0.0.1:8000/',
136+
// pathname: '/',
137+
// path: '/'
138+
// }
139+
// },
140+
//
103141
self.routes.push({
104-
route: route,
105-
target: router[path],
106-
path: path
142+
source: {
143+
regexp: new RegExp('^' + path, 'i'),
144+
sref: path,
145+
url: url.parse('http://' + path)
146+
},
147+
target: {
148+
sref: target.hostname + ':' + (target.port || defaultPort) + target.path,
149+
url: target
150+
}
107151
});
108152
});
109153
}
@@ -137,22 +181,30 @@ ProxyTable.prototype.getProxyLocation = function (req) {
137181
target += req.url;
138182
for (var i in this.routes) {
139183
var route = this.routes[i];
140-
if (target.match(route.route)) {
141-
var requrl = url.parse(req.url);
142-
//add the 'http://'' to get around a url.parse bug, it won't actually be used.
143-
var targeturl = url.parse('http://'+route.target);
144-
var pathurl = url.parse('http://'+route.path);
145-
146-
//This replaces the path's part of the URL to the target's part of the URL.
147-
requrl.pathname = requrl.pathname.replace(pathurl.pathname, targeturl.pathname);
148-
req.url = url.format(requrl);
149-
150-
var host = targeturl.hostname,
151-
port = targeturl.port || 80;
184+
if (target.match(route.source.regexp)) {
185+
//
186+
// Attempt to perform any path replacement for differences
187+
// between the source path and the target path. This replaces the
188+
// path's part of the URL to the target's part of the URL.
189+
//
190+
// 1. Parse the request URL
191+
// 2. Replace any portions of the source path with the target path
192+
// 3. Set the request URL to the formatted URL with replacements.
193+
//
194+
var parsed = url.parse(req.url);
195+
196+
parsed.pathname = parsed.pathname.replace(
197+
route.source.url.pathname,
198+
route.target.url.pathname
199+
);
200+
201+
req.url = url.format(parsed);
152202

153203
return {
154-
port: port,
155-
host: host
204+
protocol: route.target.url.protocol.replace(':', ''),
205+
host: route.target.url.hostname,
206+
port: route.target.url.port
207+
|| (this.target.https ? 443 : 80)
156208
};
157209
}
158210
}

Diff for: lib/node-http-proxy/routing-proxy.js

+13-5
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ var RoutingProxy = exports.RoutingProxy = function (options) {
4747
// Setup other default options to be used for instances of
4848
// `HttpProxy` created by this `RoutingProxy` instance.
4949
//
50-
this.source = options.source || { host: 'localhost', port: 8000 };
51-
this.https = this.source.https || options.https;
50+
this.source = options.source || { host: 'localhost', port: 8000 };
51+
this.https = this.source.https || options.https;
5252
this.enable = options.enable;
5353
this.forward = options.forward;
5454

@@ -88,8 +88,7 @@ RoutingProxy.prototype.add = function (options) {
8888
options.target.host = options.target.host || options.host;
8989
options.target.port = options.target.port || options.port;
9090
options.target.https = this.target && this.target.https ||
91-
options.target && options.target.https ||
92-
options.https;
91+
options.target && options.target.https;
9392

9493
//
9594
// Setup options to pass-thru to the new `HttpProxy` instance
@@ -102,12 +101,15 @@ RoutingProxy.prototype.add = function (options) {
102101
});
103102

104103
this.proxies[key] = new HttpProxy(options);
104+
105105
if (this.listeners('proxyError').length > 0) {
106106
this.proxies[key].on('proxyError', this.emit.bind(this, 'proxyError'));
107107
}
108+
108109
if (this.listeners('webSocketProxyError').length > 0) {
109110
this.proxies[key].on('webSocketProxyError', this.emit.bind(this, 'webSocketProxyError'));
110111
}
112+
111113
this.proxies[key].on('start', this.emit.bind(this, 'start'));
112114
this.proxies[key].on('forward', this.emit.bind(this, 'forward'));
113115
this.proxies[key].on('end', this.emit.bind(this, 'end'));
@@ -200,7 +202,13 @@ RoutingProxy.prototype.proxyRequest = function (req, res, options) {
200202
}
201203

202204
var key = this._getKey(options),
203-
proxy;
205+
proxy;
206+
207+
if ((this.target && this.target.https)
208+
|| (location && location.protocol === 'https')) {
209+
options.target = options.target || {};
210+
options.target.https = true;
211+
}
204212

205213
if (!this.proxies[key]) {
206214
this.add(options);

0 commit comments

Comments
 (0)