Created
December 4, 2012 20:07
-
-
Save drorm/4208144 to your computer and use it in GitHub Desktop.
Meteor Proxy server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"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('<html>\n'); | |
res.write('<body>\n'); | |
res.end("<h1> Not available </h1> Sorry, it looks like you've reached a site that is currently unavailable. <br/> Try later or check out <a href='http://www.devwik.com'>our home page at http://www.devwik.com'</a>.</body></html>"); | |
res.end("</body> </html>"); | |
}); | |
} | |
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(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment