Skip to content

Commit

Permalink
[api test doc] Updated tests. Added ProxyTable functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
indexzero committed Nov 21, 2010
1 parent 8c3e993 commit bedc7a3
Show file tree
Hide file tree
Showing 8 changed files with 502 additions and 109 deletions.
52 changes: 39 additions & 13 deletions README.md
Expand Up @@ -29,14 +29,25 @@ Let's suppose you were running multiple http application servers, but you only w
npm install http-proxy
</pre>

### How to setup a basic proxy server
## Using node-http-proxy

There are several ways to use node-http-proxy; the library is designed to be flexible so that it can be used by itself, or in conjunction with other node.js libraries / tools:

1. Standalone HTTP Proxy server
2. Inside of another HTTP server (like Connect)
3. From the command-line as a proxy daemon
4. In conjunction with a Proxy Routing Table

### Setup a basic stand-alone proxy server
<pre>
var http = require('http'),
httpProxy = require('http-proxy');

// Create your proxy server
httpProxy.createServer(9000, 'localhost').listen(8000);

http.createServer(function (req, res){
// Create your target server
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('request successfully proxied!' + '\n' + JSON.stringify(req.headers, true, 2));
res.end();
Expand All @@ -45,7 +56,7 @@ Let's suppose you were running multiple http application servers, but you only w

See the [demo](http://github.com/nodejitsu/node-http-proxy/blob/master/demo.js) for further examples.

### How to setup a proxy server with custom server logic
### Setup a stand-alone proxy server with custom server logic
<pre>
var http = require('http'),
httpProxy = require('http-proxy');
Expand All @@ -56,58 +67,73 @@ See the [demo](http://github.com/nodejitsu/node-http-proxy/blob/master/demo.js)
proxy.proxyRequest(9000, 'localhost');
}).listen(8000);

http.createServer(function (req, res){
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('request successfully proxied: ' + req.url +'\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
</pre>

### How to setup a proxy server with latency (e.g. IO, etc)
### Setup a stand-alone proxy server with latency (e.g. IO, etc)
<pre>
var http = require('http'),
httpProxy = require('http-proxy');

// create a proxy server with custom application logic
httpProxy.createServer(function (req, res, proxy) {
// Wait for two seconds then respond
// Wait for two seconds then respond: this simulates
// performing async actions before proxying a request
setTimeout(function () {
proxy.proxyRequest(9000, 'localhost');
}, 2000);
}).listen(8000);

http.createServer(function (req, res){
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('request successfully proxied: ' + req.url +'\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
</pre>

### How to proxy requests with a regular http server
### Proxy requests within another http server
<pre>
var http = require('http'),
httpProxy = require('http-proxy');

// create a regular http server and proxy its handler
http.createServer(function (req, res){
http.createServer(function (req, res) {
// Create a new instance of HttProxy for this request
// each instance is only valid for serving one request
//
// Don't worry benchmarks show the object
// creation is lightning fast
var proxy = new httpProxy.HttpProxy(req, res);

// Put your custom server logic here, then proxy
proxy.proxyRequest(9000, 'localhost', req, res);
}).listen(8001);

http.createServer(function (req, res){
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('request successfully proxied: ' + req.url +'\n' + JSON.stringify(req.headers, true, 2));
res.end();
}).listen(9000);
</pre>

### Proxy requests using a ProxyTable
A Proxy Table is a simple lookup table that maps incoming requests to proxy target locations. Take a look at an example of the options you need to pass to httpProxy.createServer:
<pre>
var options = {
router: {
'foo.com': '127.0.0.1:8001',
'bar.com': '127.0.0.1:8002'
}
};
</pre>

The above route table will take incoming requests to 'foo.com' and forward them to '127.0.0.1:8001'. Likewise it will take incoming requests to 'bar.com' and forward them to '127.0.0.1:8002'. The routes themselves are later converted to regular expressions to enable more complex matching functionality. We can create a proxy server with these options by using the following code:
<pre>
var proxyServer = httpProxy.createServer(options);
proxyServer.listen(80);
</pre>

### Why doesn't node-http-proxy have more advanced features like x, y, or z?

If you have a suggestion for a feature currently not supported, feel free to open a [support issue](http://github.com/nodejitsu/node-http-proxy/issues). node-http-proxy is designed to just proxy http requests from one server to another, but we will be soon releasing many other complimentary projects that can be used in conjunction with node-http-proxy.
Expand Down
44 changes: 31 additions & 13 deletions demo.js
Expand Up @@ -40,30 +40,48 @@ var welcome = '\
sys.puts(welcome.rainbow.bold);


/****** basic http proxy server ******/
//
// Basic Http Proxy Server
//
httpProxy.createServer(9000, 'localhost').listen(8000);
sys.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8000'.yellow);

/****** http proxy server with latency******/
httpProxy.createServer(function (req, res, proxy){
setTimeout(function(){
//
// Http Proxy Server with Proxy Table
//
httpProxy.createServer({
router: {
'127.0.0.1': 'localhost:9000'
}
}).listen(8001);
sys.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8001 '.yellow + 'with proxy table'.magenta.underline)

//
// Http Proxy Server with Latency
//
httpProxy.createServer(function (req, res, proxy) {
setTimeout(function() {
proxy.proxyRequest(9000, 'localhost');
}, 200)
}).listen(8001);
sys.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8001 '.yellow + 'with latency'.magenta.underline );
}).listen(8002);
sys.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8002 '.yellow + 'with latency'.magenta.underline);

/****** http server with proxyRequest handler and latency******/
http.createServer(function (req, res){
//
// Http Server with proxyRequest Handler and Latency
//
http.createServer(function (req, res) {
var proxy = new httpProxy.HttpProxy(req, res);

setTimeout(function(){
setTimeout(function() {
proxy.proxyRequest(9000, 'localhost');
}, 200);
}).listen(8002);
sys.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '8002 '.yellow + 'with proxyRequest handler'.cyan.underline + ' and latency'.magenta);
}).listen(8003);
sys.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '8003 '.yellow + 'with proxyRequest handler'.cyan.underline + ' and latency'.magenta);

/****** regular http server ******/
http.createServer(function (req, res){
//
// Target Http Server
//
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();
Expand Down
49 changes: 35 additions & 14 deletions lib/node-http-proxy.js
Expand Up @@ -28,6 +28,7 @@ var sys = require('sys'),
http = require('http'),
events = require('events'),
pool = require('./../vendor/pool/main'),
ProxyTable = require('./proxy-table').ProxyTable,
min = 0,
max = 100;

Expand All @@ -37,23 +38,43 @@ manager.setMinClients(min);
manager.setMaxClients(max);

exports.createServer = function () {
var args, callback, port, host;
var args, callback, port, host, options, proxyTable;
args = Array.prototype.slice.call(arguments);
callback = typeof args[args.length - 1] === 'function' && args.pop();
if (args[0]) port = args[0];
if (args[1]) host = args[1];

if (args.length >= 2) {
port = args[0];
host = args[1];
if (args[2]) options = args[2];
} else if (args.length === 1) {
options = args[0];
}

if (options && options.router) {
proxyTable = new ProxyTable(options.router);
proxyTable.on('updateRoutes', function (routes) {
server.emit('updateRoutes', routes);
});
}

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

// If we were passed a callback to process the request
// or response in some way, then call it.
if(callback) {
if (callback) {
callback(req, res, proxy);
} else if (port && host) {
proxy.proxyRequest(port, host);
} else if (proxyTable) {
proxyTable.proxyRequest(proxy);
} else {
throw new Error('Cannot proxy without port, host, or router.')
}
else {
proxy.proxyRequest(port, server);
}
});

server.on('close', function () {
if (proxyTable) proxyTable.close();
});

if (!callback) {
Expand Down Expand Up @@ -98,7 +119,7 @@ var HttpProxy = function (req, res, head) {
};

HttpProxy.prototype = {
toArray: function (obj){
toArray: function (obj) {
var len = obj.length,
arr = new Array(len);
for (var i = 0; i < len; ++i) {
Expand Down Expand Up @@ -149,11 +170,11 @@ HttpProxy.prototype = {
var client = http.createClient(port, server);
p.request(req.method, req.url, req.headers, function (reverse_proxy) {
// Create an error handler so we can use it temporarily
function error(obj) {
function error (obj) {
var fn = function (err) {
res.writeHead(500, {'Content-Type': 'text/plain'});

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

Expand Down Expand Up @@ -191,7 +212,7 @@ HttpProxy.prototype = {

// Add event handler for the proxied response in chunks
response.addListener('data', function (chunk) {
if(req.method !== 'HEAD') {
if (req.method !== 'HEAD') {
res.write(chunk, 'binary');
self.body += chunk;
}
Expand Down Expand Up @@ -220,7 +241,6 @@ HttpProxy.prototype = {
});

self.unwatch(req);

});
},

Expand Down Expand Up @@ -381,7 +401,7 @@ HttpProxy.prototype = {
}
});

socket.on('data', listeners._data = function(data){
socket.on('data', listeners._data = function(data) {
// Pass data from client to server
try {
reverse_proxy.write(data);
Expand Down Expand Up @@ -414,4 +434,5 @@ HttpProxy.prototype = {
}
};

exports.HttpProxy = HttpProxy;
exports.HttpProxy = HttpProxy;
exports.ProxyTable = ProxyTable;

0 comments on commit bedc7a3

Please sign in to comment.