"use strict"; var httpProxy = require('http-proxy'), http = require('http'), accesslog = require('access-log'), addresses; var LISTENPORT = 80; //port we're listening to the outside world var METEORPORT = 3000; //port meteor is run on the guests var MINIP = 10; //Minimum IP address we can use. Smaller numbers are for admin purposes var MYDOMAIN = 'devwik.com'; var LOCAL_SUBNET = '10.0.3.'; var currentMaxNumber = MINIP; var devwikCollection; var proxyServer = null; var devwikDb = null // routing hash addresses = { /* 'foo.devwik.com:3180': { host: '10.0.3.3', port: METEORPORT }, */ 'www.devwik.com': { host: 'localhost', port: 3000 }, //This is our testing server 'test.devwik.com': { host: 'localhost', port: 4000 }, 'default': { host: 'localhost',//by default go the devwik's main page if we don't match something we know. port: METEORPORT //TODO: do we want to send them to a 404 Not found.? } }; var mongo = require('mongodb'), Server = mongo.Server, Db = mongo.Db; //var server = new Server('localhost', 27017, {safe:true}); var server = new Server('localhost', 27017); //var db = new Db('devwik', server, {safe:true}); var db = new Db('devwik', server); var devwikUsersHash; db.open(function(err, db) { if(err) { throw(err); } else { devwikDb = db; loadUsers(); } }); //load the devwik Users first. function loadUsers(callBack) { //load the Devwik Users first and insert them into a hash devwikUsersHash = new Object(); devwikDb.collection('DevwikUsers', function(err, devwikUsers) { if(err) { throw(err); } else { devwikCollection = devwikUsers; var stream = devwikUsers.find({}).stream(); stream.on("data", function(devwikUser) { var userNumber = devwikUser.userNumber; //console.log(" id:" + devwikUser.meteorId + " userNumber:" + userNumber + " port:" + devwikUser.port + " app:" + devwikUser.currentApp + " editor:" + devwikUser.editorType); if(userNumber && (userNumber > currentMaxNumber)) { //find out what's the current highest number used currentMaxNumber = userNumber; } devwikUsersHash[devwikUser.meteorId] = devwikUser; //set it up for each lookup by id }); stream.on("end", function() { loadMeteorUsers(); if (callBack) { callBack(); } }); } }); } //load the Meteor Users next. function loadMeteorUsers() { devwikDb.collection('users', function(err, users) { if(err) { throw(err); } else { var stream = users.find({},{sort: {createdAt: 1}}).stream(); stream.on("data", function(user) { /*construct something like: 'foo.devwik.com': { host: '10.0.3.23', port: METEORPORT }, */ var devwikUser = devwikUsersHash[user._id]; if (!devwikUser) { console.log('###Error. User:' + user.username + ' does not exist in devwikUser'); return; } var userNumber = devwikUser.userNumber; if (!userNumber) { //user doesn't currently have a number assigned currentMaxNumber++; userNumber = currentMaxNumber;//give them the next number console.log('Setting:' + user.username + " to:" + userNumber); //And update it in the db for future use an also to inform the app //TODO: race condition. Need to make sure that this is single threaded devwikCollection.update({meteorId:user._id},{$set: {userNumber: userNumber}}); } var vhost = new Object(); var subDomain = user.username + '.' + MYDOMAIN; vhost.host = LOCAL_SUBNET + (userNumber); vhost.port = METEORPORT; addresses[subDomain] = vhost; //console.log(" name:" + user.username + " id" + user._id); //console.log(vhost); }); stream.on("end", function() { if (!proxyServer) { runProxy();//first time } }); } }); } console.log('Starting, pid:' + process.pid); function runProxy() { proxyServer = httpProxy.createServer(function (request, response, proxy) { var target; // accesslog(request, response); // var buffer = httpProxy.buffer(request); // if we have a host in the routing hash we proxy to it // otherwise we proxy to default host target = (addresses[request.headers.host]) ? addresses[request.headers.host] : addresses.default; target.buffer = buffer; proxy.proxyRequest(request, response, target); }).listen(LISTENPORT); console.log(addresses); proxyServer.proxy.on('proxyError', function (err, req, res) { res.writeHead(500, { 'Content-Type': 'text/html' }); res.write('\n'); res.write('
\n'); res.end("