diff --git a/lib/server.js b/lib/server.js index 35d4a27..e0ba6b8 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,5 +1,114 @@ -var server = function(settings){ +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){ + console.log("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;