mirror of
https://github.com/http-party/node-http-proxy.git
synced 2025-12-08 20:59:18 +00:00
Merge pull request #216 from CodeRarity/master
Re-emit 'start', 'forward' and 'end' events in RoutingProxy, and fix some hanging issues.
This commit is contained in:
commit
f223ce8b4e
26
README.md
26
README.md
@ -217,6 +217,32 @@ proxyServerWithForwarding.listen(80);
|
|||||||
|
|
||||||
The forwarding option can be used in conjunction with the proxy table options by simply including both the 'forward' and 'router' properties in the options passed to 'createServer'.
|
The forwarding option can be used in conjunction with the proxy table options by simply including both the 'forward' and 'router' properties in the options passed to 'createServer'.
|
||||||
|
|
||||||
|
### Listening for proxy events
|
||||||
|
Sometimes you want to listen to an event on a proxy. For example, you may want to listen to the 'end' event, which represents when the proxy has finished proxying a request.
|
||||||
|
|
||||||
|
``` js
|
||||||
|
var httpProxy = require('http-proxy');
|
||||||
|
|
||||||
|
var server = httpProxy.createServer(function (req, res, proxy) {
|
||||||
|
|
||||||
|
var buffer = httpProxy.buffer(req);
|
||||||
|
|
||||||
|
proxy.proxyRequest(req, res, {
|
||||||
|
host: '127.0.0.1',
|
||||||
|
port: 9000,
|
||||||
|
buffer: buffer
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
server.proxy.on('end', function() {
|
||||||
|
console.log("The request was proxied.");
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(8000);
|
||||||
|
```
|
||||||
|
|
||||||
|
It's important to remember not to listen for events on the proxy object in the function passed to `httpProxy.createServer`. Doing so would add a new listener on every request, which would end up being a disaster.
|
||||||
|
|
||||||
## Using HTTPS
|
## Using HTTPS
|
||||||
You have all the full flexibility of node-http-proxy offers in HTTPS as well as HTTP. The two basic scenarios are: with a stand-alone proxy server or in conjunction with another HTTPS server.
|
You have all the full flexibility of node-http-proxy offers in HTTPS as well as HTTP. The two basic scenarios are: with a stand-alone proxy server or in conjunction with another HTTPS server.
|
||||||
|
|||||||
@ -23,26 +23,26 @@ var RoutingProxy = exports.RoutingProxy = function (options) {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (options.router) {
|
if (options.router) {
|
||||||
this.proxyTable = new ProxyTable(options);
|
this.proxyTable = new ProxyTable(options);
|
||||||
this.proxyTable.on('routes', function (routes) {
|
this.proxyTable.on('routes', function (routes) {
|
||||||
self.emit('routes', routes);
|
self.emit('routes', routes);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create a set of `HttpProxy` objects to be used later on calls
|
// Create a set of `HttpProxy` objects to be used later on calls
|
||||||
// to `.proxyRequest()` and `.proxyWebSocketRequest()`.
|
// to `.proxyRequest()` and `.proxyWebSocketRequest()`.
|
||||||
//
|
//
|
||||||
this.proxies = {};
|
this.proxies = {};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setup default target options (such as `https`).
|
// Setup default target options (such as `https`).
|
||||||
//
|
//
|
||||||
this.target = {};
|
this.target = {};
|
||||||
this.target.https = options.target && options.target.https;
|
this.target.https = options.target && options.target.https;
|
||||||
|
|
||||||
//
|
//
|
||||||
// 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.
|
||||||
@ -51,6 +51,18 @@ var RoutingProxy = exports.RoutingProxy = function (options) {
|
|||||||
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;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Listen for 'newListener' events so that we can bind 'proxyError'
|
||||||
|
// listeners to each HttpProxy's 'proxyError' event.
|
||||||
|
//
|
||||||
|
this.on('newListener', function (evt) {
|
||||||
|
if (evt === 'proxyError' || evt === 'webSocketProxyError') {
|
||||||
|
Object.keys(self.proxies).forEach(function (key) {
|
||||||
|
self.proxies[key].on(evt, this.emit.bind(this, evt));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -68,30 +80,37 @@ util.inherits(RoutingProxy, events.EventEmitter);
|
|||||||
RoutingProxy.prototype.add = function (options) {
|
RoutingProxy.prototype.add = function (options) {
|
||||||
var self = this,
|
var self = this,
|
||||||
key = this._getKey(options);
|
key = this._getKey(options);
|
||||||
|
|
||||||
//
|
//
|
||||||
// TODO: Consume properties in `options` related to the `ProxyTable`.
|
// TODO: Consume properties in `options` related to the `ProxyTable`.
|
||||||
//
|
//
|
||||||
options.target = options.target || {};
|
options.target = options.target || {};
|
||||||
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;
|
options.https;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setup options to pass-thru to the new `HttpProxy` instance
|
// Setup options to pass-thru to the new `HttpProxy` instance
|
||||||
// for the specified `options.host` and `options.port` pair.
|
// for the specified `options.host` and `options.port` pair.
|
||||||
//
|
//
|
||||||
['https', 'enable', 'forward'].forEach(function (key) {
|
['https', 'enable', 'forward'].forEach(function (key) {
|
||||||
if (options[key] !== false && self[key]) {
|
if (options[key] !== false && self[key]) {
|
||||||
options[key] = self[key];
|
options[key] = self[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.proxies[key] = new HttpProxy(options);
|
this.proxies[key] = new HttpProxy(options);
|
||||||
this.proxies[key].on('proxyError', this.emit.bind(this, 'proxyError'));
|
if (this.listeners('proxyError').length > 0) {
|
||||||
this.proxies[key].on('webSocketProxyError', this.emit.bind(this, 'webSocketProxyError'));
|
this.proxies[key].on('proxyError', this.emit.bind(this, 'proxyError'));
|
||||||
|
}
|
||||||
|
if (this.listeners('webSocketProxyError').length > 0) {
|
||||||
|
this.proxies[key].on('webSocketProxyError', this.emit.bind(this, 'webSocketProxyError'));
|
||||||
|
}
|
||||||
|
this.proxies[key].on('start', this.emit.bind(this, 'start'));
|
||||||
|
this.proxies[key].on('forward', this.emit.bind(this, 'forward'));
|
||||||
|
this.proxies[key].on('end', this.emit.bind(this, 'end'));
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -111,18 +130,18 @@ RoutingProxy.prototype.remove = function (options) {
|
|||||||
//
|
//
|
||||||
RoutingProxy.prototype.close = function () {
|
RoutingProxy.prototype.close = function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (this.proxyTable) {
|
if (this.proxyTable) {
|
||||||
//
|
//
|
||||||
// Close the `RoutingTable` associated with
|
// Close the `RoutingTable` associated with
|
||||||
// this instance (if any).
|
// this instance (if any).
|
||||||
//
|
//
|
||||||
this.proxyTable.close();
|
this.proxyTable.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Close all sockets for all `HttpProxy` object(s)
|
// Close all sockets for all `HttpProxy` object(s)
|
||||||
// associated with this instance.
|
// associated with this instance.
|
||||||
//
|
//
|
||||||
Object.keys(this.proxies).forEach(function (key) {
|
Object.keys(this.proxies).forEach(function (key) {
|
||||||
self.proxies[key].close();
|
self.proxies[key].close();
|
||||||
@ -160,11 +179,11 @@ RoutingProxy.prototype.proxyRequest = function (req, res, options) {
|
|||||||
try {
|
try {
|
||||||
res.writeHead(404);
|
res.writeHead(404);
|
||||||
res.end();
|
res.end();
|
||||||
}
|
}
|
||||||
catch (er) {
|
catch (er) {
|
||||||
console.error("res.writeHead/res.end error: %s", er.message);
|
console.error("res.writeHead/res.end error: %s", er.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,15 +198,14 @@ RoutingProxy.prototype.proxyRequest = function (req, res, options) {
|
|||||||
options.port = location.port;
|
options.port = location.port;
|
||||||
options.host = location.host;
|
options.host = location.host;
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = this._getKey(options),
|
var key = this._getKey(options),
|
||||||
proxy;
|
proxy;
|
||||||
|
|
||||||
if (!this.proxies[key]) {
|
if (!this.proxies[key]) {
|
||||||
this.add(options);
|
this.add(options);
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
||||||
proxy = this.proxies[key];
|
proxy = this.proxies[key];
|
||||||
proxy.proxyRequest(req, res, options.buffer);
|
proxy.proxyRequest(req, res, options.buffer);
|
||||||
};
|
};
|
||||||
@ -206,7 +224,7 @@ RoutingProxy.prototype.proxyRequest = function (req, res, options) {
|
|||||||
//
|
//
|
||||||
RoutingProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options) {
|
RoutingProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
if (this.proxyTable && !options.host) {
|
if (this.proxyTable && !options.host) {
|
||||||
location = this.proxyTable.getProxyLocation(req);
|
location = this.proxyTable.getProxyLocation(req);
|
||||||
|
|
||||||
@ -217,7 +235,7 @@ RoutingProxy.prototype.proxyWebSocketRequest = function (req, socket, head, opti
|
|||||||
options.port = location.port;
|
options.port = location.port;
|
||||||
options.host = location.host;
|
options.host = location.host;
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = this._getKey(options),
|
var key = this._getKey(options),
|
||||||
proxy;
|
proxy;
|
||||||
|
|
||||||
@ -225,7 +243,7 @@ RoutingProxy.prototype.proxyWebSocketRequest = function (req, socket, head, opti
|
|||||||
this.add(options);
|
this.add(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy = this.proxies[key];
|
proxy = this.proxies[key];
|
||||||
proxy.proxyWebSocketRequest(req, socket, head, options.buffer);
|
proxy.proxyWebSocketRequest(req, socket, head, options.buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -237,14 +255,14 @@ RoutingProxy.prototype.proxyWebSocketRequest = function (req, socket, head, opti
|
|||||||
// combination contained within.
|
// combination contained within.
|
||||||
//
|
//
|
||||||
RoutingProxy.prototype._getKey = function (options) {
|
RoutingProxy.prototype._getKey = function (options) {
|
||||||
if (!options || ((!options.host || !options.port)
|
if (!options || ((!options.host || !options.port)
|
||||||
&& (!options.target || !options.target.host || !options.target.port))) {
|
&& (!options.target || !options.target.host || !options.target.port))) {
|
||||||
throw new Error('options.host and options.port or options.target are required.');
|
throw new Error('options.host and options.port or options.target are required.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
options.host || options.target.host,
|
options.host || options.target.host,
|
||||||
options.port || options.target.port
|
options.port || options.target.port
|
||||||
].join(':');
|
].join(':');
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user