/* * kyle's nodejs server * * by default app.settings.env is set to 'development' (process.env.ENV_VARIABLE) * $ NODE_ENV=production node app.js * * ToDo: * - redis for active users * - load from db once, and refetch when necessary * - if (verbose) log; can choose to use process.env and/or app.settings.env * - jsdoc? * */ var util = require('util'); var crypto = require('crypto') var path = require('path'); var http = require('http'); var express = require('express'); var io = require('socket.io'); var RedisStore = require('connect-redis')(express); var db = require('./mydb.js'); var myplatform = require('./router/myplatform.js'); var user = require('./router/user.js'); var index = require('./router/index.js'); var app = express(); /* return function accepting req/res */ var server = http.createServer(app); /* this method takes in a function/callback that it feeds with req/res on 'request' event */ var sio = io.listen(server); function deadend(req, res, next) { util.log('[deadend] couldn\'t serve, requested path: ' + req.url); /* collect possible info here */ /* if (critical_wrong) then; throw new Error('da fuck this entity is doing!'); */ res.send(404, 'page not found\n'); } function error_handler(err, req, res, next) { /* error handling, arity of 4 */ console.error(err.stack); res.send(500, 'something broke!\n'); } /* delete req.session.user on close connection? */ function restrict(req, res, next) { if (req.session.user) { util.log('[restrict] granted ' + req.session.user); next(); } else { util.log('[restrict] blocked access'); res.send(401, 'access restricted\n'); /* res.redirect(/login); */ } } app.configure(function() { app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); /* no need to specify .jade extension */ app.set('view options', { pretty: true }); /* avoid html source all in on line or so */ app.use(express.logger('dev')); app.use(express.favicon()); app.use(express.compress()); /* gzip */ app.use(express.bodyParser()); /* creates req.body which req.param() uses */ app.use(express.cookieParser()); /* req.session.* can be populated with user defined vars */ app.use(express.session({ secret: "keyboard cat", store: new RedisStore() })); /* populates req.session */ app.use(app.router); /* when there's no match, we go static file handling below */ app.use(require('stylus').middleware(__dirname + '/public')); app.use(express.static(path.join(__dirname, 'public'))); /* GET /stylesheets/style.css */ app.use(deadend); /* we get here if we couldn't serve */ app.use(error_handler); /* is this correct? */ }); app.get('/', index.root); app.get('/create', user.create_get); app.post('/create', user.create_post); app.get('/login', user.login_get); app.post('/login', user.login_post); //app.all('*', auth.check); /* not applicable, I want router list to hit the end in case auth fails */ app.get('/sys/:id([a-z]+)', restrict, myplatform.system); server.listen(8081, function() { util.log(util.format('[server] listening on port %d in %s mode', this.address().port, app.settings.env)); }) .on('error', function(e) { util.log('[server] failed creating server, errno: ' + e.errno); }) .on('close', function() { util.log('[server] server shutdown'); }) .on('clientError', function(exception) { util.log('[server] ' + exception); }) .on('connection', function(socket) { /* socket.myid = crypto.createHash('md5').update(socket.remoteAddress + ':' + socket.remotePort).digest('hex'); */ socket.myip = socket.remoteAddress; socket.myport = socket.remotePort; util.log('[server] new node connection from ' + socket.remoteAddress + ':' + socket.remotePort); socket.on('close', function() { /* delete connected_clients */ util.log('[server] client ' + this.myip + ':' + this.myport + ' closed node connection\n'); }); }); sio.sockets.on('connection', function(socket) { var endpoint = socket.manager.handshaken[socket.id].address; /* socket.myid = crypto.createHash('md5').update(socket.remoteAddress + ':' + socket.remotePort).digest('hex'); */ /* user defined fields */ socket.myip = endpoint.address; socket.myport = endpoint.port; util.log('[server] new socket.io connection from ' + endpoint.address + ':' + endpoint.port); /* after client logs in, expect him to emit 'login' event, emit should contain tag name and 'logged in' check should be done */ socket.on('login', function(tag) { var client = null; if ((client = get_connected_client(tag)) != undefined) { util.log('[socket.io] ' + tag + ' is active'); client.tag.iosocket = socket; } }); socket.on('disconnect', function() { /* delete connected_clients */ util.log('[server] client ' + this.myip + ':' + this.myport + ' disconnected from socket.io connection\n'); }); });