Skip to content

Commit

Permalink
Manual proxy routes are now persistent and proxies will fail graceful…
Browse files Browse the repository at this point in the history
…ly if port is in use
  • Loading branch information
Hadrien Jouet committed Jan 27, 2013
1 parent d889e89 commit b054cdb
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 18 deletions.
3 changes: 3 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ var http_proxy = require('./lib/proxy').Proxy,
//start default proxy
proxy.start(app.config.get('public-port'));

//load persistent proxy routes
proxy.autoload();

//define routes
require('./lib/ishiki')(app, haibu, path, fs, drone, proxy);

Expand Down
69 changes: 55 additions & 14 deletions lib/proxy.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var http_proxy = require('http-proxy');
var http_proxy = require('http-proxy'),
proxyModel = require('../models/proxy');

var Proxy = exports.Proxy = function(app, haibu) {
var self = this;
Expand Down Expand Up @@ -44,7 +45,7 @@ var Proxy = exports.Proxy = function(app, haibu) {

var route_message = this.req.body.domain + ':' + port + ' > ' + pkg.host + ':' + pkg.port;

if (self.set(port, pkg, this.req.body.domain))
if (self.set(port, pkg, this.req.body.domain, true))
haibu.sendResponse(this.res, 200, {message: 'Proxy route added: ' + route_message});
else
haibu.sendResponse(this.res, 500, {message: 'Could not create route: ' + route_message});
Expand Down Expand Up @@ -130,7 +131,15 @@ Proxy.prototype.start = function(port) {
//forward request to target
proxy.proxyRequest(req, res, self.proxies[port].routes[host]);
}
}).listen(port);
});

this.proxies[port].proxy.on('error', function(err) {
//if proxy failed to start, remove it
console.log('Could not start proxy on ' + port, err);
delete self.proxies[port];
});

this.proxies[port].proxy.listen(port);

return true;
}
Expand All @@ -141,7 +150,7 @@ Proxy.prototype.start = function(port) {
//stops proxy on given port
Proxy.prototype.stop = function(port) {
if (this.proxies[port]) {
this.proxies[port].close();
this.proxies[port].proxy.close();

return true;
}
Expand All @@ -161,16 +170,25 @@ Proxy.prototype.clean = function(port) {
};

//sets domain target
Proxy.prototype.set = function(port, pkg, domain) {
if (domain.trim() != '' && this.proxies[port] && pkg.host && pkg.port) {
this.proxies[port].routes[domain] = {
host: pkg.host,
port: (pkg.env.PORT),
user: pkg.user,
appid: pkg.name
};

return true;
Proxy.prototype.set = function(port, pkg, domain, persist) {
if (domain.trim() != '' && this.proxies[port] && pkg.host) {
var target_port = (pkg.env ? pkg.env.PORT : null) || pkg.port;

if (target_port) {
this.proxies[port].routes[domain] = {
host: pkg.host,
port: target_port,
user: pkg.user,
appid: pkg.name,
persist: persist
};

//save to db if persistent
if (persist)
proxyModel.createOrUpdate({host: domain, port: port}, this.proxies[port].routes[domain], function(){});

return true;
}
}

return false;
Expand Down Expand Up @@ -213,6 +231,10 @@ Proxy.prototype.getBy = function(port, match) {
//delete domain target
Proxy.prototype.delete = function(port, domain) {
if (this.proxies[port] && this.proxies[port].routes[domain]) {
//remove from db if persistent
if (this.proxies[port].routes[domain].persist)
proxyModel.deleteBy({source: {host: domain, port: port}}, console.log);

delete this.proxies[port].routes[domain];

return true;
Expand Down Expand Up @@ -260,3 +282,22 @@ Proxy.prototype.load = function(port, pkg) {
return false;
};

//load all persistent routes from db
Proxy.prototype.autoload = function() {
var self = this;

proxyModel.get(function(err, routes) {
if (err)
return console.log(err);

if (routes.length > 0) {
routes.forEach(function(route) {
//create proxy if it doesn't exist
if (!self.proxies[route.source.port])
self.start(route.source.port);

self.set(route.source.port, route.target, route.source.host, true);
});
}
});
};
14 changes: 10 additions & 4 deletions models/drone.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@ var BaseModel = require('./_base').BaseModel,
var illegal_chars = ['/', '\\', '.', ' ', '"', '*', '<', '>', ':', '|', '?'],
escape_with = '__';

var DroneModel = function() {
DroneModel.super_.apply(this, arguments);
};

util.inherits(DroneModel, BaseModel);

//processes mongodb illegal characters in keys
//pre to true preprocesses, otherwise postprocesses
BaseModel.prototype.process = function(data, pre) {
DroneModel.prototype.process = function(data, pre) {
var self = this;

Object.keys(data).forEach(function(key) {
Expand Down Expand Up @@ -35,7 +41,7 @@ BaseModel.prototype.process = function(data, pre) {
return data;
};

BaseModel.prototype.getProcessed = function(filter, callback) {
DroneModel.prototype.getProcessed = function(filter, callback) {
var self = this;

this.get(filter, function(err, result) {
Expand All @@ -50,7 +56,7 @@ BaseModel.prototype.getProcessed = function(filter, callback) {
});
};

BaseModel.prototype.createOrUpdate = function(pkg, callback) {
DroneModel.prototype.createOrUpdate = function(pkg, callback) {
var self = this;

if (pkg._id) delete pkg._id;
Expand Down Expand Up @@ -79,4 +85,4 @@ BaseModel.prototype.createOrUpdate = function(pkg, callback) {
});
};

module.exports = new BaseModel({collection: 'drone'});
module.exports = new DroneModel({collection: 'drone'});
41 changes: 41 additions & 0 deletions models/proxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
var BaseModel = require('./_base').BaseModel,
util = require('util');

var ProxyModel = function() {
ProxyModel.super_.apply(this, arguments);
};

util.inherits(ProxyModel, BaseModel);

ProxyModel.prototype.createOrUpdate = function(source, target, callback) {
var self = this;

this.get({source: source}, function(err, result) {
if (err)
return callback(err);

if (result.length == 1)
self.edit(result[0]._id.toString(), {$set: {target: target}}, callback);
else
self.add({source: source, target: target}, callback);
});
};

ProxyModel.prototype.deleteBy = function(filter, callback) {
var self = this;

this.get(filter, function(err, result) {
if (err)
return callback(err);

if (result.length > 0) {
result.forEach(function(route) {
self.delete(route._id.toString(), function() {});
});

callback(null);
}
});
};

module.exports = new ProxyModel({collection: 'proxy'});

0 comments on commit b054cdb

Please sign in to comment.