mirror of
https://github.com/http-party/node-http-proxy.git
synced 2025-12-08 20:59:18 +00:00
[fix api] Optimize lookups in the ProxyTable. Ensure that RoutingProxy can proxy to https by default.
This commit is contained in:
parent
e2dc7f9693
commit
55286a7c49
@ -42,6 +42,7 @@ var ProxyTable = exports.ProxyTable = function (options) {
|
|||||||
events.EventEmitter.call(this);
|
events.EventEmitter.call(this);
|
||||||
|
|
||||||
this.silent = options.silent || options.silent !== true;
|
this.silent = options.silent || options.silent !== true;
|
||||||
|
this.target = options.target || {};
|
||||||
this.hostnameOnly = options.hostnameOnly === true;
|
this.hostnameOnly = options.hostnameOnly === true;
|
||||||
|
|
||||||
if (typeof options.router === 'object') {
|
if (typeof options.router === 'object') {
|
||||||
@ -91,19 +92,62 @@ ProxyTable.prototype.setRoutes = function (router) {
|
|||||||
throw new Error('Cannot update ProxyTable routes without router.');
|
throw new Error('Cannot update ProxyTable routes without router.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var self = this;
|
||||||
this.router = router;
|
this.router = router;
|
||||||
|
|
||||||
if (this.hostnameOnly === false) {
|
if (this.hostnameOnly === false) {
|
||||||
var self = this;
|
|
||||||
this.routes = [];
|
this.routes = [];
|
||||||
|
|
||||||
Object.keys(router).forEach(function (path) {
|
Object.keys(router).forEach(function (path) {
|
||||||
var route = new RegExp('^' + path, 'i');
|
if (!/http[s]?/.test(router[path])) {
|
||||||
|
router[path] = (self.target.https ? 'https://' : 'http://')
|
||||||
|
+ router[path];
|
||||||
|
}
|
||||||
|
|
||||||
|
var target = url.parse(router[path]),
|
||||||
|
defaultPort = self.target.https ? 443 : 80;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Setup a robust lookup table for the route:
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// source: {
|
||||||
|
// regexp: /^foo.com/i,
|
||||||
|
// sref: 'foo.com',
|
||||||
|
// url: {
|
||||||
|
// protocol: 'http:',
|
||||||
|
// slashes: true,
|
||||||
|
// host: 'foo.com',
|
||||||
|
// hostname: 'foo.com',
|
||||||
|
// href: 'http://foo.com/',
|
||||||
|
// pathname: '/',
|
||||||
|
// path: '/'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// target: {
|
||||||
|
// sref: '127.0.0.1:8000/',
|
||||||
|
// url: {
|
||||||
|
// protocol: 'http:',
|
||||||
|
// slashes: true,
|
||||||
|
// host: '127.0.0.1:8000',
|
||||||
|
// hostname: '127.0.0.1',
|
||||||
|
// href: 'http://127.0.0.1:8000/',
|
||||||
|
// pathname: '/',
|
||||||
|
// path: '/'
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
//
|
||||||
self.routes.push({
|
self.routes.push({
|
||||||
route: route,
|
source: {
|
||||||
target: router[path],
|
regexp: new RegExp('^' + path, 'i'),
|
||||||
path: path
|
sref: path,
|
||||||
|
url: url.parse('http://' + path)
|
||||||
|
},
|
||||||
|
target: {
|
||||||
|
sref: target.hostname + ':' + (target.port || defaultPort) + target.path,
|
||||||
|
url: target
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -137,22 +181,30 @@ ProxyTable.prototype.getProxyLocation = function (req) {
|
|||||||
target += req.url;
|
target += req.url;
|
||||||
for (var i in this.routes) {
|
for (var i in this.routes) {
|
||||||
var route = this.routes[i];
|
var route = this.routes[i];
|
||||||
if (target.match(route.route)) {
|
if (target.match(route.source.regexp)) {
|
||||||
var requrl = url.parse(req.url);
|
//
|
||||||
//add the 'http://'' to get around a url.parse bug, it won't actually be used.
|
// Attempt to perform any path replacement for differences
|
||||||
var targeturl = url.parse('http://'+route.target);
|
// between the source path and the target path. This replaces the
|
||||||
var pathurl = url.parse('http://'+route.path);
|
// path's part of the URL to the target's part of the URL.
|
||||||
|
//
|
||||||
|
// 1. Parse the request URL
|
||||||
|
// 2. Replace any portions of the source path with the target path
|
||||||
|
// 3. Set the request URL to the formatted URL with replacements.
|
||||||
|
//
|
||||||
|
var parsed = url.parse(req.url);
|
||||||
|
|
||||||
//This replaces the path's part of the URL to the target's part of the URL.
|
parsed.pathname = parsed.pathname.replace(
|
||||||
requrl.pathname = requrl.pathname.replace(pathurl.pathname, targeturl.pathname);
|
route.source.url.pathname,
|
||||||
req.url = url.format(requrl);
|
route.target.url.pathname
|
||||||
|
);
|
||||||
|
|
||||||
var host = targeturl.hostname,
|
req.url = url.format(parsed);
|
||||||
port = targeturl.port || 80;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
port: port,
|
protocol: route.target.url.protocol.replace(':', ''),
|
||||||
host: host
|
host: route.target.url.hostname,
|
||||||
|
port: route.target.url.port
|
||||||
|
|| (this.target.https ? 443 : 80)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,8 +47,8 @@ var RoutingProxy = exports.RoutingProxy = function (options) {
|
|||||||
// Setup other default options to be used for instances of
|
// Setup other default options to be used for instances of
|
||||||
// `HttpProxy` created by this `RoutingProxy` instance.
|
// `HttpProxy` created by this `RoutingProxy` instance.
|
||||||
//
|
//
|
||||||
this.source = options.source || { host: 'localhost', port: 8000 };
|
this.source = options.source || { host: 'localhost', port: 8000 };
|
||||||
this.https = this.source.https || options.https;
|
this.https = this.source.https || options.https;
|
||||||
this.enable = options.enable;
|
this.enable = options.enable;
|
||||||
this.forward = options.forward;
|
this.forward = options.forward;
|
||||||
|
|
||||||
@ -88,8 +88,7 @@ RoutingProxy.prototype.add = function (options) {
|
|||||||
options.target.host = options.target.host || options.host;
|
options.target.host = options.target.host || options.host;
|
||||||
options.target.port = options.target.port || options.port;
|
options.target.port = options.target.port || options.port;
|
||||||
options.target.https = this.target && this.target.https ||
|
options.target.https = this.target && this.target.https ||
|
||||||
options.target && options.target.https ||
|
options.target && options.target.https;
|
||||||
options.https;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setup options to pass-thru to the new `HttpProxy` instance
|
// Setup options to pass-thru to the new `HttpProxy` instance
|
||||||
@ -102,12 +101,15 @@ RoutingProxy.prototype.add = function (options) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.proxies[key] = new HttpProxy(options);
|
this.proxies[key] = new HttpProxy(options);
|
||||||
|
|
||||||
if (this.listeners('proxyError').length > 0) {
|
if (this.listeners('proxyError').length > 0) {
|
||||||
this.proxies[key].on('proxyError', this.emit.bind(this, 'proxyError'));
|
this.proxies[key].on('proxyError', this.emit.bind(this, 'proxyError'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.listeners('webSocketProxyError').length > 0) {
|
if (this.listeners('webSocketProxyError').length > 0) {
|
||||||
this.proxies[key].on('webSocketProxyError', this.emit.bind(this, 'webSocketProxyError'));
|
this.proxies[key].on('webSocketProxyError', this.emit.bind(this, 'webSocketProxyError'));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.proxies[key].on('start', this.emit.bind(this, 'start'));
|
this.proxies[key].on('start', this.emit.bind(this, 'start'));
|
||||||
this.proxies[key].on('forward', this.emit.bind(this, 'forward'));
|
this.proxies[key].on('forward', this.emit.bind(this, 'forward'));
|
||||||
this.proxies[key].on('end', this.emit.bind(this, 'end'));
|
this.proxies[key].on('end', this.emit.bind(this, 'end'));
|
||||||
@ -200,7 +202,13 @@ RoutingProxy.prototype.proxyRequest = function (req, res, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var key = this._getKey(options),
|
var key = this._getKey(options),
|
||||||
proxy;
|
proxy;
|
||||||
|
|
||||||
|
if ((this.target && this.target.https)
|
||||||
|
|| (location && location.protocol === 'https')) {
|
||||||
|
options.target = options.target || {};
|
||||||
|
options.target.https = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.proxies[key]) {
|
if (!this.proxies[key]) {
|
||||||
this.add(options);
|
this.add(options);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user