Skip to content

Instantly share code, notes, and snippets.

@juandopazo
Created August 19, 2012 15:04
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 juandopazo/3395359 to your computer and use it in GitHub Desktop.
Save juandopazo/3395359 to your computer and use it in GitHub Desktop.
localtunnel in Node
var http = require('http');
module.exports = function (config) {
console.log("Starting client");
var client = http.request({
host: config.remoteHost,
port: config.remotePort,
method: 'CONNECT',
path: 'new'
});
client.end();
client.on('connect', function (res, socket, head) {
var id = res.headers['host-id'];
console.log('connected with id: ' + id);
socket.on('data', function (data) {
var proxy = http.request({
host: config.remoteHost,
port: config.remotePort,
method: 'CONNECT',
path: id,
headers: {
foo: 'bar'
}
});
proxy.end();
proxy.on('connect', function (proxyRes, proxySocket, proxyHead) {
var headers = proxyRes.headers;
console.log(headers['proxy-method'] + ' http://localhost:80/' + headers['proxy-path']);
var localReq = http.request({
port: config.localPort,
path: '/' + headers['proxy-path'],
method: headers['proxy-method']
}, function (localRes) {
localRes.pipe(proxySocket);
});
proxyRes.pipe(localReq);
});
});
});
};
exports.createServer = require('./server');
exports.connect = require('./client');
var http = require('http');
function guid() {
var id = (++guid.counter).toString(16);
return id == 'new' ? guid() : id;
}
guid.counter = 1;
var hosts = {};
module.exports = function (PORT) {
var server = http.createServer();
server.on('request', function (req, res) {
var id, host;
if (req.url == '/') {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('hello world\n');
} else {
id = req.url.split('/')[1];
host = hosts[id];
if (host) {
host.fns.push(function (proxyReq, socket, head) {
var headers = 'HTTP/1.1 200 Connection Established\r\n';
for (var x in req.headers) {
if (req.headers.hasOwnProperty(x)) {
headers += x + ': ' + req.headers[x] + '\r\n';
}
}
headers += 'Proxy-path: ' + req.url.split('/').slice(2).join('/') + '\r\n';
headers += 'Proxy-method: ' + req.method + '\r\n';
headers += '\r\n';
socket.write(headers);
res.writeHead(proxyReq.statusCode || 200, proxyReq.headers);
socket.pipe(res);
console.log(Object.keys(req).map(function (key) {
return key + ':' + req[key];
}));
req.on('data', function (data) {
console.log('request data ' + data);
});
});
host.socket.write('open');
} else {
res.writeHead(404, {'Content-type': 'text/plain'});
res.end('No such host\n');
}
}
});
server.on('connect', function (req, socket, head) {
var id, host;
if (req.url == 'new') {
id = guid();
hosts[id] = {
socket: socket,
fns: []
};
console.log('creating host with id: ' + id);
socket.write('HTTP/1.1 200 Connection Established\r\n' +
'Proxy-agent: Node-Proxy\r\n' +
'Host-id: ' + id + '\r\n' +
'\r\n');
} else {
id = req.url;
host = hosts[id];
if (host.fns.length > 0) {
host.fns.shift()(req, socket, head);
}
}
});
server.listen(PORT, function () {
console.log('listening');
});
};
var tunnel = require('./localtunnel'),
argv = require('optimist').default({
localPort: 80,
remoteHost: 'localhost',
remotePort: 3000
}).argv;
if (argv.server) {
tunnel.createServer(argv.removePort);
} else {
tunnel.connect({
localPort : argv.localPort,
remoteHost: argv.remoteHost,
remotePort: argv.remotePort
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment