UNPKG

gracenode-server

Version:
154 lines (125 loc) 3.81 kB
var uuid = require('node-uuid'); var gracenode = require('gracenode'); var log = gracenode.log.create('server'); var async = require('async'); var http = require('./http'); var https = require('./https'); var router = require('./lib/router'); var controller = require('./lib/controller'); var resource = require('./lib/resource'); var serverError = require('./lib/error'); var reqHook = require('./hooks/request'); var resHook = require('./hooks/response'); var EventEmitter = require('events').EventEmitter; var config = null; var serverEngine = null; var server = null; module.exports = new EventEmitter(); module.exports.readConfig = function (configIn) { config = configIn; if (config.protocol === 'https') { serverEngine = https; } else { serverEngine = http; } serverEngine.readConfig(config); router.readConfig(config); controller.readConfig(config); serverError.readConfig(config); }; module.exports.setup = function (cb) { var list = []; if (config.protocol === 'https') { list.push(serverEngine.setup); } log.info('server protocol: ' + config.protocol); list.push(router.setup); async.series(list, cb); }; module.exports.getControllerMap = function () { return router.getControllerMap(); }; module.exports.getEndPointList = function () { return getEndPointListFromControllerMap(router.getControllerMap()); }; module.exports.addRequestHooks = function (hooks) { log.verbose('add request hooks:', hooks); reqHook.addHooks(hooks); }; module.exports.addResponseHooks = function (hooks) { log.verbose('add reseponse hooks:', hooks); resHook.addHooks(hooks); }; /* Deprecated hooks: { "<controller name>": { "<method name>": <hook function> } } */ // if set, controller.exec will not be invoked until requestHook is successfully executed // use case example: session check etc module.exports.setupRequestHooks = function (hooks) { log.verbose('setting up request hooks:', hooks); reqHook.setupRequestHooks(hooks); }; module.exports.setupResponseHooks = function (hooks) { log.verbose('setting up response hooks:', hooks); resHook.setupResponseHooks(hooks); }; module.exports.start = function () { log.verbose('starting server...'); try { server = serverEngine.start(requestHandler); } catch (exception) { log.fatal(exception); } }; function getEndPointListFromControllerMap(map, prefix) { if (!prefix) { prefix = ''; } var list = []; for (var key in map) { if (typeof map[key] === 'object') { list = list.concat(getEndPointListFromControllerMap(map[key], prefix + '/' + key)); } else { list.push(prefix + '/' + key + '/'); } } return list; } function requestHandler(request, response) { if (config.trailingSlash) { var uriComponents = request.url.split('?'); var uri = uriComponents[0]; var queries = uriComponents[1] ? '?' + uriComponents[1] : ''; var trailing = uri.substring(uri.length - 1); if (trailing !== '/') { log.verbose('enforcing trailing slash on', request.url); response.writeHeader(301, { location: uri + '/' + queries }); return response.end(); } } // assign a unique id to each request request.uniqueId = uuid.v4(); // listen for unexpected termination of connection response.on('close', function () { log.error( 'connection closed unexpectedly: (url:' + request.url + ') (request-id:' + request.uniqueId + ')', request.headers ); }); module.exports.emit('requestStart', request.url); // response module emits server.emit('requestEnd', request.url) // if parsedUrl returns as null, the request has been ignored var parsedUrl = router.handle(request.url, response); if (parsedUrl) { // create resource var resc = resource.create(module.exports, request, response, parsedUrl, Date.now()); // execute controller controller.exec(resc); } }