Skip to content

Commit

Permalink
[test] Simplified tests. Added tests for experimental websocket support
Browse files Browse the repository at this point in the history
  • Loading branch information
indexzero committed Nov 21, 2010
1 parent f84880f commit 8c3e993
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 339 deletions.
148 changes: 67 additions & 81 deletions lib/node-http-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ var sys = require('sys'),
http = require('http'),
events = require('events'),
pool = require('./../vendor/pool/main'),
eyes = require('eyes'),
min = 0,
max = 100;

Expand All @@ -44,13 +43,9 @@ exports.createServer = function () {
if (args[0]) port = args[0];
if (args[1]) host = args[1];

var server = http.createServer(function (req, res){
var server = http.createServer(function (req, res) {
var proxy = new HttpProxy(req, res);

proxy.emitter.on('proxy', function (err, body) {
server.emit('proxy', err, body);
});

// If we were passed a callback to process the request
// or response in some way, then call it.
if(callback) {
Expand All @@ -61,15 +56,14 @@ exports.createServer = function () {
}
});

// If callback is empty - tunnel websocket request automatically
if (!callback) {
// WebSocket support
// WebSocket support: if callback is empty tunnel
// websocket request automatically
server.on('upgrade', function(req, socket, head) {
var proxy = new HttpProxy(req, socket, head);

// Tunnel websocket requests too
proxy.proxyWebSocketRequest(port, host);

});
}

Expand All @@ -87,7 +81,6 @@ exports.setMax = function (value) {
};

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

Expand Down Expand Up @@ -145,96 +138,90 @@ HttpProxy.prototype = {
self.body = '';

// Open new HTTP request to internal resource with will act as a reverse proxy pass
//var p = manager.getPool(port, server);
//sys.puts('Current pool count for ' + req.headers.host + ":" + port + ' ' + p.clients.length + ', Busy: ' + p.getBusy() + ', Free: ' + p.getFree());
var p = manager.getPool(port, server);

//p.on('error', function (err) {
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.
//});
});

var client = http.createClient(port, server);
var reverse_proxy = client.request(req.method, req.url, req.headers);

//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));
}
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();
};
// Response end may never come so removeListener here
obj.removeListener('error', fn);
res.end();
};

return fn;
};
return fn;
};

// Add a listener for the connection timeout event
var reverseProxyError = error(reverse_proxy),
clientError = error(client);
// Add a listener for the connection timeout event
var reverseProxyError = error(reverse_proxy),
clientError = error(client);

reverse_proxy.addListener('error', reverseProxyError);
client.addListener('error', clientError);
reverse_proxy.addListener('error', reverseProxyError);
client.addListener('error', clientError);

// 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);
// 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';
}

// 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 () {
// Remark: Emit the end event for testability
self.emitter.emit('proxy', null, self.body);
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;
}
});

// Add event listener for end of proxied response
response.addListener('end', function () {
reverse_proxy.removeListener('error', reverseProxyError);
res.end();
});
});
});

// Chunk the client request body as chunks from the proxied request come in
req.addListener('data', function (chunk) {
reverse_proxy.write(chunk, 'binary');
})
// 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();
});
// At the end of the client request, we are going to stop the proxied request
req.addListener('end', function () {
reverse_proxy.end();
});

// On 'close' event remove 'error' listener
client.addListener('close', function() {
client.removeListener('error', clientError);
});
// On 'close' event remove 'error' listener
client.addListener('close', function() {
client.removeListener('error', clientError);
});

self.unwatch(req);
self.unwatch(req);

//});
});
},

proxyWebSocketRequest: function (port, server, host) {
Expand All @@ -251,8 +238,7 @@ HttpProxy.prototype = {
return h;
}

// WebSocket requests has
// method = GET
// WebSocket requests has method = GET
if (req.method !== 'GET' || headers.upgrade.toLowerCase() !== 'websocket') {
// This request is not WebSocket request
return;
Expand Down
140 changes: 0 additions & 140 deletions test/node-http-proxy-notarget.js

This file was deleted.

Loading

0 comments on commit 8c3e993

Please sign in to comment.