var http = require("http");
|
|
var util = require("util");
|
|
|
|
var yaps_plugin = require("./plugin.js");
|
|
|
|
var handler_chain = function(handlers, request, server, response, not_found){
|
|
if(handlers.length){
|
|
handlers[0](request, server, function(status, body, headers){
|
|
if(status == null || status == undefined){
|
|
handler_chain(handlers.slice(1), request, server, response, not_found);
|
|
} else{
|
|
response.writeHead(status, headers);
|
|
response.end(body);
|
|
}
|
|
});
|
|
} else{
|
|
not_found();
|
|
}
|
|
};
|
|
|
|
var server = function(settings, http_server){
|
|
this.settings = settings || {};
|
|
this.bind = this.settings["bind"] || "0.0.0.0:8000";
|
|
this.enabledPlugins = [];
|
|
this.routes = {};
|
|
this.notFound = [];
|
|
this.setup = [];
|
|
|
|
// they gave us an http server, lets use that
|
|
if(http_server != null || http_server != undefined){
|
|
this.server = http_server;
|
|
} else{
|
|
this.server = new http.Server();
|
|
}
|
|
this.server.yaps = this;
|
|
};
|
|
|
|
server.prototype.rootHandler = function(request, response){
|
|
var self = this.yaps;
|
|
var handlers = [];
|
|
var method = request.method.toUpperCase();
|
|
for(var route in self.routes[method]){
|
|
if(!self.routes[method][route].length){
|
|
continue;
|
|
}
|
|
var pattern = new RegExp(route);
|
|
if(pattern.test(request.url)){
|
|
handlers = handlers.concat(self.routes[method][route]);
|
|
}
|
|
}
|
|
|
|
handlers = self.setup.concat(handlers);
|
|
|
|
if(handlers.length){
|
|
handler_chain(handlers, request, self, response, function(){
|
|
handler_chain(self.notFound, request, self, response, function(){
|
|
response.writeHead(404);
|
|
response.end("Not Found");
|
|
});
|
|
});
|
|
} else{
|
|
handler_chain(self.notFound, request, self, response, function(){
|
|
response.writeHead(404);
|
|
response.end("Not Found");
|
|
});
|
|
}
|
|
};
|
|
|
|
server.prototype.errorHandler = function(error){
|
|
throw Error("YAPS, HTTP Server Error:", error);
|
|
};
|
|
|
|
server.prototype.registerPlugin = function(plugin_constructor){
|
|
util.inherits(plugin_constructor, yaps_plugin);
|
|
var plugin = new plugin_constructor(this.settings);
|
|
this.enabledPlugins.push(plugin);
|
|
for(var method in plugin.routes){
|
|
this.routes[method] = this.routes[method] || {};
|
|
for(var route in plugin.routes[method]){
|
|
this.routes[method][route] = this.routes[method][route] || [];
|
|
this.routes[method][route] = this.routes[method][route].concat(plugin.routes[method][route]);
|
|
}
|
|
}
|
|
if(plugin.notFound){
|
|
this.notFound.push(plugin.notFound);
|
|
}
|
|
if(plugin.setup && plugin.setup.length){
|
|
this.setup = this.setup.concat(plugin.setup);
|
|
}
|
|
};
|
|
|
|
server.prototype.start = function(){
|
|
this.server.on("error", this.errorHandler);
|
|
this.server.on("request", this.rootHandler);
|
|
|
|
var bind_parts = [undefined, undefined];
|
|
if(this.bind.indexOf("unix://") == 0){
|
|
bind_parts[1] = this.bind;
|
|
} else{
|
|
if(!~this.bind.indexOf(":")){
|
|
bind_parts = [this.bind, "0.0.0.0"];
|
|
} else{
|
|
bind_parts = this.bind.split(":");
|
|
}
|
|
}
|
|
|
|
this.server.listen(bind_parts[1], bind_parts[0]);
|
|
};
|
|
|
|
server.prototype.stop = function(){
|
|
this.server.close();
|
|
};
|
|
|
|
module.exports = server;
|