Skip to content

Commit

Permalink
[api] First pass at removing pool and working with node v0.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
indexzero committed Feb 21, 2011
1 parent 34cba38 commit 9faa924
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 119 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test/config.json
204 changes: 95 additions & 109 deletions lib/node-http-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,8 @@
var util = require('util'),
http = require('http'),
events = require('events'),
pool = require('pool'),
ProxyTable = require('./proxy-table').ProxyTable,
min = 0,
max = 100;

// Setup the PoolManager
var manager = pool.createPoolManager();
manager.setMinClients(min);
manager.setMaxClients(max);
maxSockets = 100;

exports.createServer = function () {
var args, callback, port, host, forward,
Expand Down Expand Up @@ -114,17 +107,13 @@ exports.createServer = function () {
return server;
};

exports.setMin = function (value) {
min = value;
manager.setMinClients(min);
exports.setMaxSockets = function (value) {
maxSockets = value;
};

exports.setMax = function (value) {
max = value;
manager.setMaxClients(max);
};
exports.ProxyTable = ProxyTable;

var HttpProxy = function (req, res, head) {
var HttpProxy = exports.HttpProxy = function (req, res, head) {
this.events = {};
this.req = req;

Expand Down Expand Up @@ -177,116 +166,116 @@ HttpProxy.prototype = {
},

proxyRequest: function (port, server) {
var self = this, req = this.req, res = this.res;
var self = this, req = this.req, res = this.res, reverseProxy;

// Open new HTTP request to internal resource with will act as a reverse proxy pass
var p = manager.getPool(port, server);
// Create an error handler so we can use it temporarily
function error (obj) {
var fn = function (err) {
res.writeHead(500, {'Content-Type': 'text/plain'});

p.on('error', function (err) {
// Remark: We should probably do something here
// but this is a hot-fix because I don't think 'pool'
// should be emitting this event.
});

p.request(req.method, req.url, req.headers, function (reverse_proxy) {
// Create an error handler so we can use it temporarily
function error (obj) {
var fn = function (err) {
res.writeHead(500, {'Content-Type': 'text/plain'});

if (req.method !== 'HEAD') {
res.write('An error has occurred: ' + JSON.stringify(err));
}

// Response end may never come so removeListener here
obj.removeListener('error', fn);
res.end();
};
if (req.method !== 'HEAD') {
res.write('An error has occurred: ' + JSON.stringify(err));
}

return fn;
// Response end may never come so removeListener here
obj.removeListener('error', fn);
res.end();
};

// Add a listener for the connection timeout event
var reverseProxyError = error(reverse_proxy);
reverse_proxy.addListener('error', reverseProxyError);

// Add a listener for the reverse_proxy response event
reverse_proxy.addListener('response', function (response) {
if (response.headers.connection) {
if (req.headers.connection) response.headers.connection = req.headers.connection;
else response.headers.connection = 'close';
}

// Set the response headers of the client response
res.writeHead(response.statusCode, response.headers);
return fn;
};

// Open new HTTP request to internal resource with will act as a reverse proxy pass
reverseProxy = http.request({
host: server,
port: port,
method: req.method,
path: req.url,
headers: req.headers
}, function (response) {

// Process the reverse_proxy response when it's received.
if (response.headers.connection) {
if (req.headers.connection) response.headers.connection = req.headers.connection;
else response.headers.connection = 'close';
}

// Status code = 304
// No 'data' event and no 'end'
if (response.statusCode === 304) {
res.end();
return;
}
// Set the response headers of the client response
res.writeHead(response.statusCode, response.headers);

// Add event handler for the proxied response in chunks
response.addListener('data', function (chunk) {
if (req.method !== 'HEAD') {
res.write(chunk, 'binary');
self.body += chunk;
}
});
// Status code = 304
// No 'data' event and no 'end'
if (response.statusCode === 304) {
res.end();
return;
}

// Add event listener for end of proxied response
response.addListener('end', function () {
reverse_proxy.removeListener('error', reverseProxyError);
res.end();
});
// Add event handler for the proxied response in chunks
response.addListener('data', function (chunk) {
if (req.method !== 'HEAD') {
res.write(chunk, 'binary');
self.body += chunk;
}
});

// Chunk the client request body as chunks from the proxied request come in
req.addListener('data', function (chunk) {
reverse_proxy.write(chunk, 'binary');
})

// At the end of the client request, we are going to stop the proxied request
req.addListener('end', function () {
reverse_proxy.end();
// Add event listener for end of proxied response
response.addListener('end', function () {
reverseProxy.removeListener('error', reverseProxyError);
res.end();
});
});

self.unwatch(req);
// Add a listener for the connection timeout event
var reverseProxyError = error(reverseProxy);
reverseProxy.addListener('error', reverseProxyError);

// Chunk the client request body as chunks from the proxied request come in
req.addListener('data', function (chunk) {
reverseProxy.write(chunk, 'binary');
})

// At the end of the client request, we are going to stop the proxied request
req.addListener('end', function () {
reverseProxy.end();
});

self.unwatch(req);
},

forwardRequest: function (port, server) {
var self = this, req = this.req;
var self = this, req = this.req, forwardProxy;

// Open new HTTP request to internal resource with will act as a reverse proxy pass
var p = manager.getPool(port, server);

p.on('error', function (err) {
// Remark: We should probably do something here
// but this is a hot-fix because I don't think 'pool'
// should be emitting this event.
forwardProxy = http.request({
host: server,
port: port,
method: req.method,
path: req.url,
headers: req.headers
}, function (response) {
//
// Ignore the response from the forward proxy since this is a 'fire-and-forget' proxy.
// Remark (indexzero): We will eventually emit a 'forward' event here for performance tuning.
//
});

p.request(req.method, req.url, req.headers, function (forward_proxy) {
// Add a listener for the connection timeout event
forward_proxy.addListener('error', function (err) {
// Remark: Ignoring this error in the event
// forward target doesn't exist.
});

// Chunk the client request body as chunks from the proxied request come in
req.addListener('data', function (chunk) {
forward_proxy.write(chunk, 'binary');
})

// At the end of the client request, we are going to stop the proxied request
req.addListener('end', function () {
forward_proxy.end();
});

self.unwatch(req);
// Add a listener for the connection timeout event
forwardProxy.addListener('error', function (err) {
// Remark: Ignoring this error in the event
// forward target doesn't exist.
});

// Chunk the client request body as chunks from the proxied request come in
req.addListener('data', function (chunk) {
forwardProxy.write(chunk, 'binary');
})

// At the end of the client request, we are going to stop the proxied request
req.addListener('end', function () {
forwardProxy.end();
});

self.unwatch(req);
},

proxyWebSocketRequest: function (port, server, host) {
Expand Down Expand Up @@ -477,7 +466,4 @@ HttpProxy.prototype = {
});
};
}
};

exports.HttpProxy = HttpProxy;
exports.ProxyTable = ProxyTable;
};
5 changes: 2 additions & 3 deletions test/forward-proxy-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ var fs = require('fs'),
path = require('path'),
request = require('request'),
assert = require('assert'),
helpers = require('./helpers'),
TestRunner = helpers.TestRunner;
helpers = require('./helpers');

var runner = new TestRunner(),
var runner = new helpers.TestRunner(),
assertProxiedWithTarget = helpers.assertProxiedWithTarget,
assertProxiedWithNoTarget = helpers.assertProxiedWithNoTarget;

Expand Down
6 changes: 2 additions & 4 deletions test/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ exports.assertProxiedWithNoTarget = function (runner, proxyPort, statusCode, cre
return test;
}

var TestRunner = function () {
var TestRunner = exports.TestRunner = function () {
this.testServers = [];
}

Expand Down Expand Up @@ -159,6 +159,4 @@ TestRunner.prototype.closeServers = function () {
});

return this.testServers;
};

exports.TestRunner = TestRunner;
};
5 changes: 2 additions & 3 deletions test/node-http-proxy-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@ var vows = require('vows'),
util = require('util'),
request = require('request'),
assert = require('assert'),
helpers = require('./helpers'),
TestRunner = helpers.TestRunner;
helpers = require('./helpers');

var runner = new TestRunner(),
var runner = new helpers.TestRunner(),
assertProxiedWithTarget = helpers.assertProxiedWithTarget,
assertProxiedWithNoTarget = helpers.assertProxiedWithNoTarget;

Expand Down

0 comments on commit 9faa924

Please sign in to comment.