mirror of
https://github.com/zhigang1992/deployd.git
synced 2026-05-13 04:00:35 +08:00
174 lines
4.6 KiB
JavaScript
174 lines
4.6 KiB
JavaScript
var http = require('http')
|
|
, Router = require('./router')
|
|
, db = require('./db')
|
|
, util = require('util')
|
|
, resources = require('./resources')
|
|
, Resource = require('./resource')
|
|
, Keys = require('./keys')
|
|
, SessionStore = require('./session').SessionStore
|
|
, fs = require('fs')
|
|
, io = require('socket.io')
|
|
, setupReqRes = require('./util/http').setup
|
|
, debug = require('debug')('server')
|
|
, config = require('./config-loader');
|
|
|
|
|
|
function extend(origin, add) {
|
|
// don't do anything if add isn't an object
|
|
if (!add || typeof add !== 'object') return origin;
|
|
|
|
var keys = Object.keys(add);
|
|
var i = keys.length;
|
|
while (i--) {
|
|
if(add[keys[i]]) origin[keys[i]] = add[keys[i]];
|
|
}
|
|
return origin;
|
|
};
|
|
|
|
/**
|
|
* Create an http server with the given options and create a `Router` to handle its requests.
|
|
*
|
|
* Options:
|
|
*
|
|
* - `db` the database connection info
|
|
* - `host` the server's hostname
|
|
* - `port` the server's port
|
|
*
|
|
* Example:
|
|
*
|
|
* var server = new Server({port: 3000, db: {host: 'localhost', port: 27015, name: 'my-db'}});
|
|
*
|
|
* server.listen();
|
|
*
|
|
* @param {Object} options
|
|
* @return {HttpServer}
|
|
*/
|
|
|
|
function Server(options) {
|
|
var server = this;
|
|
http.Server.call(this);
|
|
|
|
// defaults
|
|
this.options = options = extend({
|
|
port: 2403,
|
|
// host: 'localhost',
|
|
db: {port: 27017, host: '127.0.0.1', name: 'deployd'}
|
|
}, options);
|
|
|
|
debug('started with options %j', options);
|
|
|
|
// an object to map a server to its stores
|
|
this.stores = {};
|
|
|
|
// back all memory stores with a db
|
|
this.db = db.connect(options.db);
|
|
|
|
// use socket io for a session based realtime channel
|
|
|
|
// socket io
|
|
this.sockets = io.listen(this, {
|
|
'log level': 0
|
|
}).sockets;
|
|
|
|
|
|
// persist sessions in a store
|
|
var sessionStore = this.sessions = new SessionStore('sessions', this.db, this.sockets);
|
|
|
|
// persist keys in a store
|
|
var keys = this.keys = new Keys('./.dpd');
|
|
|
|
this.on('request', function (req, res) {
|
|
if(req.url.indexOf('/socket.io/') === 0) return;
|
|
|
|
debug('%s %s', req.method, req.url);
|
|
|
|
// add utilites to req and res
|
|
setupReqRes(req, res, function(err, next) {
|
|
if(err) return res.end(err.message);
|
|
sessionStore.createSession(req.cookies.get('sid'), function(err, session) {
|
|
if(err) {
|
|
debug('session error', err, session);
|
|
res.statusCode = 500;
|
|
res.end('error when creating session ' + err);
|
|
} else {
|
|
// (re)set the session id
|
|
req.cookies.set('sid', session.sid);
|
|
req.session = session;
|
|
|
|
function route() {
|
|
config.loadConfig('./', function(err, resourceConfig) {
|
|
resources.build(resourceConfig, server, function(err, resourcesInstances) {
|
|
var router = new Router(resourcesInstances, server);
|
|
server.router = router;
|
|
|
|
server.resources = resourcesInstances;
|
|
router.route(req, res);
|
|
});
|
|
});
|
|
}
|
|
|
|
var root = req.headers['dpd-ssh-key'];
|
|
|
|
if(root && options.env !== 'development') {
|
|
// all root requests
|
|
// must be authenticated
|
|
keys.get(root, function(err, key) {
|
|
if(err) throw err;
|
|
if(key) session.isRoot = true;
|
|
route();
|
|
});
|
|
} else {
|
|
// normal route
|
|
route();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
});
|
|
}
|
|
util.inherits(Server, http.Server);
|
|
|
|
|
|
/**
|
|
* Start listening for incoming connections.
|
|
*
|
|
* @return {Server} for chaining
|
|
*/
|
|
|
|
Server.prototype.listen = function(port, host) {
|
|
var server = this;
|
|
config.loadConfig('./', function(err, resourceConfig) {
|
|
resources.build(resourceConfig, server, function(err, resourcesInstances) {
|
|
server.resources = resourcesInstances;
|
|
http.Server.prototype.listen.call(server, port || server.options.port, host || server.options.host);
|
|
});
|
|
});
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Create a new `Store` for persisting data using the database info that was passed to the server when it was created.
|
|
*
|
|
* Example:
|
|
*
|
|
* // Create a new server
|
|
* var server = new Server({port: 3000, db: {host: 'localhost', port: 27015, name: 'my-db'}});
|
|
*
|
|
* // Attach a store to the server
|
|
* var todos = server.createStore('todos');
|
|
*
|
|
* // Use the store to CRUD data
|
|
* todos.insert({name: 'go to the store', done: true}, ...); // see `Store` for more info
|
|
*
|
|
* @param {String} namespace
|
|
* @return {Store}
|
|
*/
|
|
|
|
Server.prototype.createStore = function(namespace) {
|
|
return (this.stores[namespace] = this.db.createStore(namespace));
|
|
};
|
|
|
|
module.exports = Server;
|