Skip to content

Commit bedc7a3

Browse files
committed
[api test doc] Updated tests. Added ProxyTable functionality
1 parent 8c3e993 commit bedc7a3

8 files changed

+502
-109
lines changed

README.md

+39-13
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,25 @@ Let's suppose you were running multiple http application servers, but you only w
2929
npm install http-proxy
3030
</pre>
3131

32-
### How to setup a basic proxy server
32+
## Using node-http-proxy
33+
34+
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:
35+
36+
1. Standalone HTTP Proxy server
37+
2. Inside of another HTTP server (like Connect)
38+
3. From the command-line as a proxy daemon
39+
4. In conjunction with a Proxy Routing Table
40+
41+
### Setup a basic stand-alone proxy server
3342
<pre>
3443
var http = require('http'),
3544
httpProxy = require('http-proxy');
3645

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

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

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

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

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

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

7182
// create a proxy server with custom application logic
7283
httpProxy.createServer(function (req, res, proxy) {
73-
// Wait for two seconds then respond
84+
// Wait for two seconds then respond: this simulates
85+
// performing async actions before proxying a request
7486
setTimeout(function () {
7587
proxy.proxyRequest(9000, 'localhost');
7688
}, 2000);
7789
}).listen(8000);
7890

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

86-
### How to proxy requests with a regular http server
98+
### Proxy requests within another http server
8799
<pre>
88100
var http = require('http'),
89101
httpProxy = require('http-proxy');
90102

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

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

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

120+
### Proxy requests using a ProxyTable
121+
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:
122+
<pre>
123+
var options = {
124+
router: {
125+
'foo.com': '127.0.0.1:8001',
126+
'bar.com': '127.0.0.1:8002'
127+
}
128+
};
129+
</pre>
130+
131+
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:
132+
<pre>
133+
var proxyServer = httpProxy.createServer(options);
134+
proxyServer.listen(80);
135+
</pre>
136+
111137
### Why doesn't node-http-proxy have more advanced features like x, y, or z?
112138

113139
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.

demo.js

+31-13
Original file line numberDiff line numberDiff line change
@@ -40,30 +40,48 @@ var welcome = '\
4040
sys.puts(welcome.rainbow.bold);
4141

4242

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

47-
/****** http proxy server with latency******/
48-
httpProxy.createServer(function (req, res, proxy){
49-
setTimeout(function(){
49+
//
50+
// Http Proxy Server with Proxy Table
51+
//
52+
httpProxy.createServer({
53+
router: {
54+
'127.0.0.1': 'localhost:9000'
55+
}
56+
}).listen(8001);
57+
sys.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8001 '.yellow + 'with proxy table'.magenta.underline)
58+
59+
//
60+
// Http Proxy Server with Latency
61+
//
62+
httpProxy.createServer(function (req, res, proxy) {
63+
setTimeout(function() {
5064
proxy.proxyRequest(9000, 'localhost');
5165
}, 200)
52-
}).listen(8001);
53-
sys.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8001 '.yellow + 'with latency'.magenta.underline );
66+
}).listen(8002);
67+
sys.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8002 '.yellow + 'with latency'.magenta.underline);
5468

55-
/****** http server with proxyRequest handler and latency******/
56-
http.createServer(function (req, res){
69+
//
70+
// Http Server with proxyRequest Handler and Latency
71+
//
72+
http.createServer(function (req, res) {
5773
var proxy = new httpProxy.HttpProxy(req, res);
5874

59-
setTimeout(function(){
75+
setTimeout(function() {
6076
proxy.proxyRequest(9000, 'localhost');
6177
}, 200);
62-
}).listen(8002);
63-
sys.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '8002 '.yellow + 'with proxyRequest handler'.cyan.underline + ' and latency'.magenta);
78+
}).listen(8003);
79+
sys.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '8003 '.yellow + 'with proxyRequest handler'.cyan.underline + ' and latency'.magenta);
6480

65-
/****** regular http server ******/
66-
http.createServer(function (req, res){
81+
//
82+
// Target Http Server
83+
//
84+
http.createServer(function (req, res) {
6785
res.writeHead(200, {'Content-Type': 'text/plain'});
6886
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
6987
res.end();

lib/node-http-proxy.js

+35-14
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ var sys = require('sys'),
2828
http = require('http'),
2929
events = require('events'),
3030
pool = require('./../vendor/pool/main'),
31+
ProxyTable = require('./proxy-table').ProxyTable,
3132
min = 0,
3233
max = 100;
3334

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

3940
exports.createServer = function () {
40-
var args, callback, port, host;
41+
var args, callback, port, host, options, proxyTable;
4142
args = Array.prototype.slice.call(arguments);
4243
callback = typeof args[args.length - 1] === 'function' && args.pop();
43-
if (args[0]) port = args[0];
44-
if (args[1]) host = args[1];
44+
45+
if (args.length >= 2) {
46+
port = args[0];
47+
host = args[1];
48+
if (args[2]) options = args[2];
49+
} else if (args.length === 1) {
50+
options = args[0];
51+
}
52+
53+
if (options && options.router) {
54+
proxyTable = new ProxyTable(options.router);
55+
proxyTable.on('updateRoutes', function (routes) {
56+
server.emit('updateRoutes', routes);
57+
});
58+
}
4559

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

4963
// If we were passed a callback to process the request
5064
// or response in some way, then call it.
51-
if(callback) {
65+
if (callback) {
5266
callback(req, res, proxy);
67+
} else if (port && host) {
68+
proxy.proxyRequest(port, host);
69+
} else if (proxyTable) {
70+
proxyTable.proxyRequest(proxy);
71+
} else {
72+
throw new Error('Cannot proxy without port, host, or router.')
5373
}
54-
else {
55-
proxy.proxyRequest(port, server);
56-
}
74+
});
75+
76+
server.on('close', function () {
77+
if (proxyTable) proxyTable.close();
5778
});
5879

5980
if (!callback) {
@@ -98,7 +119,7 @@ var HttpProxy = function (req, res, head) {
98119
};
99120

100121
HttpProxy.prototype = {
101-
toArray: function (obj){
122+
toArray: function (obj) {
102123
var len = obj.length,
103124
arr = new Array(len);
104125
for (var i = 0; i < len; ++i) {
@@ -149,11 +170,11 @@ HttpProxy.prototype = {
149170
var client = http.createClient(port, server);
150171
p.request(req.method, req.url, req.headers, function (reverse_proxy) {
151172
// Create an error handler so we can use it temporarily
152-
function error(obj) {
173+
function error (obj) {
153174
var fn = function (err) {
154175
res.writeHead(500, {'Content-Type': 'text/plain'});
155176

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

@@ -191,7 +212,7 @@ HttpProxy.prototype = {
191212

192213
// Add event handler for the proxied response in chunks
193214
response.addListener('data', function (chunk) {
194-
if(req.method !== 'HEAD') {
215+
if (req.method !== 'HEAD') {
195216
res.write(chunk, 'binary');
196217
self.body += chunk;
197218
}
@@ -220,7 +241,6 @@ HttpProxy.prototype = {
220241
});
221242

222243
self.unwatch(req);
223-
224244
});
225245
},
226246

@@ -381,7 +401,7 @@ HttpProxy.prototype = {
381401
}
382402
});
383403

384-
socket.on('data', listeners._data = function(data){
404+
socket.on('data', listeners._data = function(data) {
385405
// Pass data from client to server
386406
try {
387407
reverse_proxy.write(data);
@@ -414,4 +434,5 @@ HttpProxy.prototype = {
414434
}
415435
};
416436

417-
exports.HttpProxy = HttpProxy;
437+
exports.HttpProxy = HttpProxy;
438+
exports.ProxyTable = ProxyTable;

0 commit comments

Comments
 (0)