Commit f765f90e authored by indexzero's avatar indexzero

[api] Finalized the RoutingProxy API

parent 598fe2e3
......@@ -80,7 +80,7 @@ var HttpProxy = exports.HttpProxy = function (options) {
self[key].base = httpProxy._getBase(self[key]);
}
setupProxy('target')
setupProxy('target');
if (this.forward) {
setupProxy('forward');
}
......
......@@ -37,31 +37,34 @@ var util = require('util'),
// locations of proxy targets based on ServerRequest headers; specifically
// the HTTP host header.
//
var ProxyTable = exports.ProxyTable = function (router, silent, hostnameOnly) {
var ProxyTable = exports.ProxyTable = function (options) {
events.EventEmitter.call(this);
this.silent = typeof silent !== 'undefined' ? silent : true;
this.hostnameOnly = typeof hostnameOnly !== 'undefined' ? hostnameOnly : false;
this.silent = options.silent || options.silent !== true;
this.hostnameOnly = options.hostnameOnly === true;
if (typeof router === 'object') {
if (typeof options.router === 'object') {
//
// If we are passed an object literal setup
// the routes with RegExps from the router
//
this.setRoutes(router);
this.setRoutes(options.router);
}
else if (typeof router === 'string') {
else if (typeof options.router === 'string') {
//
// If we are passed a string then assume it is a
// file path, parse that file and watch it for changes
//
var self = this;
this.routeFile = router;
this.setRoutes(JSON.parse(fs.readFileSync(router)).router);
this.routeFile = options.router;
this.setRoutes(JSON.parse(fs.readFileSync(options.router)).router);
fs.watchFile(this.routeFile, function () {
fs.readFile(self.routeFile, function (err, data) {
if (err) throw err;
if (err) {
self.emit('error', err);
}
self.setRoutes(JSON.parse(data).router);
self.emit('routes', self.hostnameOnly === false ? self.routes : self.router);
});
......@@ -131,7 +134,9 @@ ProxyTable.prototype.getProxyLocation = function (req) {
else {
target += req.url;
for (var i in this.routes) {
var match, route = this.routes[i];
var route = this.routes[i],
match;
if (match = target.match(route.route)) {
var location = route.target.split(':'),
host = location[0],
......
/*
* routing-proxy.js: A routing proxy consuming a RoutingTable and multiple HttpProxy instances
*
* (C) 2011 Nodejitsu Inc.
* MIT LICENCE
*
*/
var events = require('events'),
util = require('util'),
HttpProxy = require('./http-proxy').HttpProxy,
......@@ -13,10 +21,14 @@ var events = require('events'),
var RoutingProxy = exports.RoutingProxy = function (options) {
events.EventEmitter.call(this);
var self = this;
options = options || {};
if (options.router) {
//
// TODO: Consume the RoutingTable for various things: `this.proxyTable`
//
this.proxyTable = new ProxyTable(options);
this.proxyTable.on('routes', function (routes) {
self.emit('routes', routes);
});
}
//
......@@ -24,6 +36,21 @@ var RoutingProxy = exports.RoutingProxy = function (options) {
// to `.proxyRequest()` and `.proxyWebSocketRequest()`.
//
this.proxies = {};
//
// Setup default target options (such as `https`).
//
this.target  = {};
this.target.https = options.target && options.target.https;
//
// Setup other default options to be used for instances of
// `HttpProxy` created by this `RoutingProxy` instance.
//
this.source = options.source || { host: 'localhost', port: 8000 };
this.https = this.source.https || options.https;
this.enable = options.enable;
this.forward = options.forward;
};
......@@ -39,7 +66,30 @@ util.inherits(RoutingProxy, events.EventEmitter);
// for the specified `options.host` and `options.port`.
//
RoutingProxy.prototype.add = function (options) {
var self = this,
key = this._getKey(options);
//
// TODO: Consume properties in `options` related to the `ProxyTable`.
//
options.target = options.target || {};
options.target.host = options.target.host || options.host;
options.target.port = options.target.port || options.port;
options.target.https = this.target && this.target.https ||
options.target && options.target.https ||
options.https;
//
// Setup options to pass-thru to the new `HttpProxy` instance
// for the specified `options.host` and `options.port` pair.
//
['https', 'enable', 'forward'].forEach(function (key) {
if (options[key] !== false && self[key]) {
options[key] = self[key];
}
});
this.proxies[key] = new HttpProxy(options);
};
//
......@@ -49,7 +99,7 @@ RoutingProxy.prototype.add = function (options) {
// for the specified `options.host` and `options.port` (if they exist).
//
RoutingProxy.prototype.remove = function (options) {
var key = this._getKey(options);
};
//
......@@ -129,8 +179,13 @@ RoutingProxy.prototype.proxyRequest = function (req, res, options) {
}
var key = options.host + ':' + options.port,
proxy = this.proxies[key] || this._addTarget(options);
proxy;
if (!this.proxies[key]) {
this.add(options);
}
proxy = this.proxies[key];
proxy.proxyRequest(req, res, options.buffer);
};
......@@ -161,7 +216,32 @@ RoutingProxy.prototype.proxyWebSocketRequest = function (req, socket, head, opti
}
var key = options.host + ':' + options.port,
proxy = this.proxies[key] || this._addTarget(options);
proxy;
if (!this.proxies[key]) {
this.add(options);
}
proxy = this.proxies[key];
proxy.proxyWebSocketRequest(req, socket, head, options.buffer);
};
//
// ### @private function _getKey (options)
// #### @options {Object} Options to extract the key from
// Ensures that the appropriate options are present in the `options`
// provided and responds with a string key representing the `host`, `port`
// combination contained within.
//
RoutingProxy.prototype._getKey = function (options) {
if (!options || ((!options.host || !options.port)
&& (!options.target || !options.target.host || !options.target.port))) {
throw new Error('options.host and options.port or options.target are required.');
return;
}
return [
options.host || options.target.host,
options.port || options.target.port
].join(':');
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment