Skip to content

Commit e6ff8d6

Browse files
committed
[api] merge middleware branch
2 parents 5ba0f89 + 0f8fe8e commit e6ff8d6

12 files changed

+671
-141
lines changed

README.md

+11
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ There are several ways to use node-http-proxy; the library is designed to be fle
4343
3. In conjunction with a Proxy Routing Table
4444
4. As a forward-proxy with a reverse proxy
4545
5. From the command-line as a long running process
46+
6. customized with 3rd party middleware.
4647

4748
In each of these scenarios node-http-proxy can handle any of these types of requests:
4849

@@ -312,6 +313,16 @@ https.createServer(options.https, function (req, res) {
312313
res.end();
313314
}).listen(8000);
314315
```
316+
## Middleware
317+
318+
`node-http-proxy` now supports connect middleware. Add middleware functions to your createServer call:
319+
320+
``` js
321+
httpProxy.createServer(
322+
require('connect-gzip').gzip(),
323+
9000, 'localhost'
324+
).listen(8000);
325+
```
315326

316327
## Proxying WebSockets
317328
Websockets are handled automatically when using the `httpProxy.createServer()`, but if you want to use it in conjunction with a stand-alone HTTP + WebSocket (such as [socket.io][5]) server here's how:

examples/body-decoder.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
body-decoder.js: Example of body-decoder middleware with node-http-proxy
3+
4+
Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Fedor Indutny, & Marak Squires.
5+
6+
Permission is hereby granted, free of charge, to any person obtaining
7+
a copy of this software and associated documentation files (the
8+
"Software"), to deal in the Software without restriction, including
9+
without limitation the rights to use, copy, modify, merge, publish,
10+
distribute, sublicense, and/or sell copies of the Software, and to
11+
permit persons to whom the Software is furnished to do so, subject to
12+
the following conditions:
13+
14+
The above copyright notice and this permission notice shall be
15+
included in all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
25+
*/
26+
27+
var httpProxy = require('http-proxy'),
28+
http = require('http'),
29+
util = require('util'),
30+
colors = require('colors');
31+
32+
exports.bodyMod = function () {
33+
console.log('middleware has been started.'.green);
34+
return function (req, res, next) {
35+
var proxy = next,
36+
total = '';
37+
38+
req.on('data', function (data) {
39+
console.log('ON DATA')
40+
total += data;
41+
});
42+
43+
req.on('end', function () {
44+
console.log('ON END')
45+
console.log(total);
46+
//
47+
// This line, uncommented, hangs forever.
48+
// proxy.proxyRequest(req, res, { port: 9000, host: 'localhost' });
49+
// The following also hangs forever.
50+
// next.proxyRequest(req, res, { port: 9000, host: 'localhost' });
51+
//
52+
});
53+
54+
//
55+
// The following fires just fine.
56+
//proxy.proxyRequest(req, res, { port: 9000, host: 'localhost' });
57+
//
58+
console.log('request proxied...'.blue);
59+
}
60+
}
61+
62+
var proxyServer = httpProxy.createServer(
63+
// Your middleware stack goes here.
64+
exports.bodyMod()
65+
).listen(8000);
66+
67+
68+
var httpServer = http.createServer(function (req, res) {
69+
res.writeHead(200, { 'Content-Type': 'text/plain' });
70+
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
71+
res.end();
72+
}).listen(9000);

examples/bodyDecoder-middleware.js

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
2+
var Store = require('./lib/store')
3+
, http = require('http')
4+
5+
http.createServer(new Store().handler()).listen(7531, function () {
6+
//try these commands:
7+
// get index:
8+
// curl localhost:7531
9+
// []
10+
//
11+
// get a doc:
12+
// curl localhost:7531/foo
13+
// {"error":"not_found"}
14+
//
15+
// post an doc:
16+
// curl -X POST localhost:7531/foo -d '{"content": "hello", "type": "greeting"}'
17+
// {"ok":true}
18+
//
19+
// get index (now, not empty)
20+
// curl localhost:7531
21+
// ["/foo"]
22+
//
23+
// get doc
24+
// curl localhost:7531/foo
25+
// {"content": "hello", "type": "greeting"}
26+
27+
//
28+
// now, suppose we wanted to direct all objects where type == "greeting" to a different store
29+
// than where type == "insult"
30+
//
31+
// we can use connect connect-bodyDecoder and some custom logic to send insults to another Store.
32+
33+
//insult server:
34+
35+
http.createServer(new Store().handler()).listen(2600, function () {
36+
37+
//greetings -> 7531, insults-> 2600
38+
39+
// now, start a proxy server.
40+
41+
var bodyParser = require('connect/lib/middleware/bodyParser')
42+
//don't worry about incoming contont type
43+
//bodyParser.parse[''] = JSON.parse
44+
45+
require('http-proxy').createServer(
46+
//refactor the body parser and re-streamer into a separate package
47+
bodyParser(),
48+
//body parser absorbs the data and end events before passing control to the next
49+
// middleware. if we want to proxy it, we'll need to re-emit these events after
50+
//passing control to the middleware.
51+
require('connect-restreamer')(),
52+
function (req, res, proxy) {
53+
//if your posting an obect which contains type: "insult"
54+
//it will get redirected to port 2600.
55+
//normal get requests will go to 7531 nad will not return insults.
56+
var port = (req.body && req.body.type === 'insult' ? 2600 : 7531)
57+
proxy.proxyRequest(req, res, {host: 'localhost', port: port})
58+
}
59+
).listen(1337, function () {
60+
var request = require('request')
61+
//bodyParser needs content-type set to application/json
62+
//if we use request, it will set automatically if we use the 'json:' field.
63+
function post (greeting, type) {
64+
request.post({
65+
url: 'http://localhost:1337/' + greeting,
66+
json: {content: greeting, type: type || "greeting"}
67+
})
68+
}
69+
post("hello")
70+
post("g'day")
71+
post("kiora")
72+
post("houdy")
73+
post("java", "insult")
74+
75+
//now, the insult should have been proxied to 2600
76+
77+
//curl localhost:2600
78+
//["/java"]
79+
80+
//but the greetings will be sent to 7531
81+
82+
//curl localhost:7531
83+
//["/hello","/g%27day","/kiora","/houdy"]
84+
85+
})
86+
})
87+
})

examples/concurrent-proxy.js

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
concurrent-proxy.js: check levelof concurrency through proxy.
3+
4+
Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Fedor Indutny, & Marak Squires.
5+
6+
Permission is hereby granted, free of charge, to any person obtaining
7+
a copy of this software and associated documentation files (the
8+
"Software"), to deal in the Software without restriction, including
9+
without limitation the rights to use, copy, modify, merge, publish,
10+
distribute, sublicense, and/or sell copies of the Software, and to
11+
permit persons to whom the Software is furnished to do so, subject to
12+
the following conditions:
13+
14+
The above copyright notice and this permission notice shall be
15+
included in all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
25+
*/
26+
27+
var util = require('util'),
28+
colors = require('colors'),
29+
http = require('http'),
30+
httpProxy = require('./../lib/node-http-proxy');
31+
32+
//
33+
// Basic Http Proxy Server
34+
//
35+
httpProxy.createServer(9000, 'localhost').listen(8000);
36+
37+
//
38+
// Target Http Server
39+
//
40+
// to check apparent problems with concurrent connections
41+
// make a server which only responds when there is a given nubmer on connections
42+
//
43+
44+
45+
var connections = []
46+
, go
47+
48+
http.createServer(function (req, res) {
49+
50+
connections.push (function (){
51+
res.writeHead(200, { 'Content-Type': 'text/plain' });
52+
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
53+
res.end();
54+
})
55+
process.stdout.write(connections.length + ', ')
56+
if (connections.length > 110 || go) {
57+
go = true
58+
while(connections.length)
59+
connections.shift()()
60+
}
61+
62+
}).listen(9000);
63+
64+
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8000'.yellow);
65+
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9000 '.yellow);

examples/gzip-middleware.js

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
gzip-middleware.js: Basic example of `connect-gzip` middleware in node-http-proxy
3+
4+
Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Fedor Indutny, Marak Squires, & Dominic Tarr.
5+
6+
Permission is hereby granted, free of charge, to any person obtaining
7+
a copy of this software and associated documentation files (the
8+
"Software"), to deal in the Software without restriction, including
9+
without limitation the rights to use, copy, modify, merge, publish,
10+
distribute, sublicense, and/or sell copies of the Software, and to
11+
permit persons to whom the Software is furnished to do so, subject to
12+
the following conditions:
13+
14+
The above copyright notice and this permission notice shall be
15+
included in all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24+
25+
*/
26+
27+
var util = require('util'),
28+
colors = require('colors'),
29+
http = require('http'),
30+
httpProxy = require('./../lib/node-http-proxy');
31+
32+
//
33+
// Basic Http Proxy Server
34+
//
35+
httpProxy.createServer(
36+
require('connect-gzip').gzip({ matchType: /.?/ }),
37+
9000, 'localhost'
38+
).listen(8000);
39+
40+
//
41+
// Target Http Server
42+
//
43+
http.createServer(function (req, res) {
44+
res.writeHead(200, { 'Content-Type': 'text/plain' });
45+
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
46+
res.end();
47+
}).listen(9000);
48+
49+
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8000'.yellow);
50+
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9000 '.yellow);

examples/jsonp-middleware.js

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
var Store = require('./lib/store')
2+
, http = require('http')
3+
4+
//
5+
// jsonp is a handy technique for getting around the limitations of the same-origin policy.
6+
// (http://en.wikipedia.org/wiki/Same_origin_policy)
7+
//
8+
// normally, to dynamically update a page you use an XmlHttpRequest. this has flakey support
9+
// is some browsers and is restricted by the same origin policy. you cannot perform XHR requests to
10+
// someone else's server. one way around this would be to proxy requests to all the servers you want
11+
// to xhr to, and your core server - so that everything has the same port and host.
12+
//
13+
// another way, is to turn json into javascript. (which is exempt from the same origin policy)
14+
// this is done by wrapping the json object in a function call, and then including a script tag.
15+
//
16+
// here we're proxing our own JSON returning server, but we could proxy any server on the internet,
17+
// and our client side app would be slurping down JSONP from anywhere.
18+
//
19+
// curl localhost:1337/whatever?callback=alert
20+
// alert([]) //which is valid javascript!
21+
//
22+
// also see http://en.wikipedia.org/wiki/JSONP#JSONP
23+
//
24+
25+
http.createServer(new Store().handler()).listen(7531)
26+
27+
require('http-proxy').createServer(
28+
require('connect-jsonp')(true),
29+
'localhost', 7531
30+
).listen(1337)

0 commit comments

Comments
 (0)