"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("

Not available

Sorry, it looks like you've reached a site that is currently unavailable.
Try later or check out our home page at http://www.devwik.com'."); res.end(" "); }); } http.createServer(function (request, response) { request.on("end", function () { //Called after the user is handled var callBack = function() { response.writeHead(200, { 'Content-Type': 'text/plain' }); response.end('OK'); console.log('reload'); console.log(addresses); }; // Send data and end response. }); loadUsers(callback); }).listen(9999); ----------------------------------------------------------------- /* * Contact the prox to let it know to check for a new user. * 1. It will: find the user in the db * 2. Assign them a unique ID TODO: you need to create a unique index * 3. Update the db with the unique ID * 4. Associate the IP address with the user name/sub domain such as joe.devwik.com */ Devwik.notifyProxy = function notifyProxy(callback) { var options = { host: 'localhost', port: 9999, path: '/', method: 'GET' }; var req = http.request(options, function(res) { console.log('STATUS: ' + res.statusCode); console.log('HEADERS: ' + JSON.stringify(res.headers)); res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('BODY: ' + chunk); callback(chunk); }); }); req.on('error', function(e) { console.log('problem with request: ' + e.message); }); // write data to request body req.write('data\n'); req.write('data\n'); req.end(); }