Skip to content

Instantly share code, notes, and snippets.

@tim-smart
Created September 6, 2010 10:14
Show Gist options
  • Save tim-smart/566872 to your computer and use it in GitHub Desktop.
Save tim-smart/566872 to your computer and use it in GitHub Desktop.
var proxy = require('./http-proxy'),
http = require('http');
http.createServer(function (req, res){
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
proxy.createServer(9000, 'localhost').listen(8000);
var http = require('http'),
sys = require('sys');
exports.createServer = function createServer (port, host) {
return new HttpProxy({
port: +port,
host: host || '0.0.0.0'
});
};
var ClientPool = function ClientPool (port, host, max_clients) {
this.port = +port;
this.host = host;
this.max_clients = max_clients || 200;
this.clients = [];
this.free = [];
var pointer = 0;
Object.defineProperty(this, 'pointer', {
enumerable: false,
get: function () {
var ret = pointer;
++pointer;
if (pointer >= this.clients.length) pointer = 0;
return ret;
}
});
return this;
};
ClientPool.prototype.request = function allocRequest (method, path, headers) {
var client, request, $ = this;
if (this.clients.length >= this.max_clients) {
request = this.clients[this.pointer].request(method, path, headers);
} else if (!(client = this.free.pop())) {
client = http.createClient(this.port, this.host);
this.clients.push(client);
request = client.request(method, path, headers);
client.on('close', function () {
if (~$.free.indexOf(client)) return;
$.free.push(client);
});
} else {
request = client.request(method, path, headers);
}
return request;
};
var HttpProxy = exports.HttpProxy = function HttpProxy (options) {
this.client_pool = new ClientPool(options.port, options.host);
http.Server.call(this);
this.on('request', this.onRequest);
return this;
};
HttpProxy.prototype = Object.create(http.Server.prototype);
HttpProxy.prototype.onRequest = function onRequest (e_request, e_response) {
var i_request = this.client_pool.request(e_request.method,
e_request.url, e_request.headers);
i_request.connection.on('error', function (error) {
error = 'An error occurred: ' + sys.inspect(error);
e_response.writeHead(200, {
'Content-Type': 'text/plain',
'Content-Length': error.length
});
if (e_request.method === 'HEAD') error = null;
e_response.end(error);
});
i_request.on('response', function (i_response) {
// Pump response
e_response.writeHead(i_response.statusCode, i_response.headers);
sys.pump(i_response, e_response);
});
sys.pump(e_request, i_request);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment