Skip to content

Instantly share code, notes, and snippets.

@apage43
Created February 26, 2011 20:57
Show Gist options
  • Save apage43/845615 to your computer and use it in GitHub Desktop.
Save apage43/845615 to your computer and use it in GitHub Desktop.
var http = require('http'),
httpProxy = require('http-proxy'),
url = require('url');
var doproxy = false; //use true if we want to place this in front of another server
//could be worth it if we're sitting in front of apache instead of an evented server?
var lport = 4881;
var rport = 81;
var rhost = '127.0.0.1';
var targetuid = 'www-data';
var targetgid = targetuid;
var waiters = {};
function doCleanup()
{
for(var channel in waiters)
{
waiters[channel] = waiters[channel].filter(function(rq) { return !rq.dead; });
}
}
function doTrigger(channel) {
if(waiters[channel])
{
waiters[channel].forEach(function(rq) {
if(!rq.dead) {
console.log("Finishing wait for " + channel);
rq.response.writeHead(303,
{'Location': 'http://' + rq.request.headers['host'] + rq.dest});
rq.response.end();
rq.dead = true;
}
});
}
doCleanup();
}
var server = http.createServer(function(req, resp) {
if(req.url.substring(0,6) == "/poll/")
{
//It's a longpoll rq, probably.
var rqurl = url.parse(req.url, true);
var timeout = 60; //Default timeout 1min.
var errorout = false;
var destination = false;
var channel = rqurl.pathname.substring(6);
if(rqurl.query['timeout'])
timeout = rqurl.query['timeout'];
if(rqurl.query['dest'])
destination = rqurl.query['dest'];
if(rqurl.query['errorout'])
errorout = true;
var rqrecord = {
request: req,
response: resp,
dead: false,
error: errorout,
dest: destination};
if(!waiters[channel]) waiters[channel] = [];
console.log("Adding waiter for " + channel);
waiters[channel].push(rqrecord);
setTimeout(function() {
console.log("Wait for " + channel + " timed out");
rqrecord.dead = true;
if(rqrecord.response.connection) {
if(rqrecord.error) {
rqrecord.response.writeHead(504);
rqrecord.response.end();
} else {
rqrecord.response.writeHead(303,
{'Location': 'http://' + rqrecord.request.headers['host'] + rqrecord.dest});
rqrecord.response.end();
rqrecord.dead = true;
}
}
doCleanup();
}, timeout * 1000);
return;
}
if(req.url.substring(0,6) == "/trig/" && req.connection.remoteAddress == '127.0.0.1')
{
var rqurl = url.parse(req.url, true);
var channel = rqurl.pathname.substring(6);
var after = 0;
if(rqurl.query['after'])
after = 1000 * rqurl.query['after'];
setTimeout(function() { doTrigger(channel); }, after);
resp.writeHead(400, {'Content-Type': 'application/json'});
resp.end('{"ok": true}');
return;
}
if(doproxy) {
var proxy = new httpProxy.HttpProxy(req, resp);
proxy.proxyRequest(rport, rhost, req, resp);
}
});
console.log("Listening...");
server.listen(lport);
if(process.getuid() == 0) { // oh hell, we're root. DROP PRIVS!
process.setgid(targetgid);
process.setuid(targetuid);
console.log("dropped privs");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment