Skip to content

Instantly share code, notes, and snippets.

@creationix
Forked from pgriess/router.js
Created July 9, 2010 21:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creationix/470080 to your computer and use it in GitHub Desktop.
Save creationix/470080 to your computer and use it in GitHub Desktop.
var HTTPParser = process.binding('http_parser').HTTPParser;
var net = require('net');
var path = require('path');
var sys = require('sys');
var Worker = require('webworker/webworker').Worker;
var VHOSTS = ['foo.bar.com', 'baz.bizzle.com'];
var WORKERS = {};
VHOSTS.forEach(function(vh) {
WORKERS[vh] = new Worker(path.join(__dirname, 'worker.js'));
});
net.createServer(function(s) {
var hp = new HTTPParser('request');
hp.data = {
'headers' : {
},
'partial' : {
'field' : '',
'value' : ''
}
};
var seenData = '';
hp.onURL = function(buf, start, len) {
var str = buf.toString('ascii', start, start + len);
if (hp.data.url) {
hp.data.url += str;
} else {
hp.data.url = str;
}
};
hp.onHeaderField = function(buf, start, len) {
if (hp.data.partial.value) {
hp.data.headers[hp.data.partial.field] = hp.data.partial.value;
hp.data.partial = {
'field' : '',
'value' : ''
};
}
hp.data.partial.field += buf.toString(
'ascii', start, start + len
).toLowerCase();
};
hp.onHeaderValue = function(buf, start, len) {
hp.data.partial.value += buf.toString(
'ascii', start, start + len
).toLowerCase();
};
hp.onHeadersComplete = function(info) {
// Clean up partial state
if (hp.data.partial.field.length > 0 &&
hp.data.partial.value.length > 0) {
hp.data.headers[hp.data.partial.field] = hp.data.partial.value;
}
delete hp.data.partial;
hp.data.version = {
'major' : info.versionMajor,
'minor' : info.versionMinor
};
hp.data.method = info.method;
hp.data.upgrade = info.upgrade;
if ('host' in hp.data.headers &&
hp.data.headers.host in WORKERS) {
s.pause();
WORKERS[hp.data.headers.host].postMessage(
seenData, s.fd
);
} else {
s.write(
'HTTP/' + info.versionMajor + '.' + info.versionMinor + ' ' +
'400 Host not found\r\n'
);
s.write('\r\n');
s.end();
}
};
s.ondata = function(buf, start, end) {
seenData += buf.toString('ascii', start, end);
var ret = hp.execute(buf, start, end - start);
if (ret instanceof Error) {
s.destroy(ret);
return;
}
};
}).listen(8080);
var Buffer = require('buffer').Buffer;
var http = require('http');
var net = require('net');
var sys = require('sys');
var srv = http.createServer(function(req, resp) {
resp.writeHead(200, {'Content-Type' : 'text/plain'});
resp.write('Hello, vhost world!\n');
resp.end();
});
onmessage = function(msg) {
var s = new net.Stream(msg.fd);
s.type = srv.type;
s.server = srv;
s.resume();
srv.emit('connection', s);
s.emit('data', msg.data);
s.ondata(new Buffer(msg.data, 'ascii'), 0, msg.data.length);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment