mirror of
https://github.com/http-party/node-http-proxy.git
synced 2025-12-08 20:59:18 +00:00
[api] merge middleware branch
This commit is contained in:
commit
e6ff8d6597
11
README.md
11
README.md
@ -43,6 +43,7 @@ There are several ways to use node-http-proxy; the library is designed to be fle
|
|||||||
3. In conjunction with a Proxy Routing Table
|
3. In conjunction with a Proxy Routing Table
|
||||||
4. As a forward-proxy with a reverse proxy
|
4. As a forward-proxy with a reverse proxy
|
||||||
5. From the command-line as a long running process
|
5. From the command-line as a long running process
|
||||||
|
6. customized with 3rd party middleware.
|
||||||
|
|
||||||
In each of these scenarios node-http-proxy can handle any of these types of requests:
|
In each of these scenarios node-http-proxy can handle any of these types of requests:
|
||||||
|
|
||||||
@ -312,6 +313,16 @@ https.createServer(options.https, function (req, res) {
|
|||||||
res.end();
|
res.end();
|
||||||
}).listen(8000);
|
}).listen(8000);
|
||||||
```
|
```
|
||||||
|
## Middleware
|
||||||
|
|
||||||
|
`node-http-proxy` now supports connect middleware. Add middleware functions to your createServer call:
|
||||||
|
|
||||||
|
``` js
|
||||||
|
httpProxy.createServer(
|
||||||
|
require('connect-gzip').gzip(),
|
||||||
|
9000, 'localhost'
|
||||||
|
).listen(8000);
|
||||||
|
```
|
||||||
|
|
||||||
## Proxying WebSockets
|
## Proxying WebSockets
|
||||||
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:
|
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:
|
||||||
|
|||||||
72
examples/body-decoder.js
Normal file
72
examples/body-decoder.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
body-decoder.js: Example of body-decoder middleware with node-http-proxy
|
||||||
|
|
||||||
|
Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Fedor Indutny, & Marak Squires.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
var httpProxy = require('http-proxy'),
|
||||||
|
http = require('http'),
|
||||||
|
util = require('util'),
|
||||||
|
colors = require('colors');
|
||||||
|
|
||||||
|
exports.bodyMod = function () {
|
||||||
|
console.log('middleware has been started.'.green);
|
||||||
|
return function (req, res, next) {
|
||||||
|
var proxy = next,
|
||||||
|
total = '';
|
||||||
|
|
||||||
|
req.on('data', function (data) {
|
||||||
|
console.log('ON DATA')
|
||||||
|
total += data;
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on('end', function () {
|
||||||
|
console.log('ON END')
|
||||||
|
console.log(total);
|
||||||
|
//
|
||||||
|
// This line, uncommented, hangs forever.
|
||||||
|
// proxy.proxyRequest(req, res, { port: 9000, host: 'localhost' });
|
||||||
|
// The following also hangs forever.
|
||||||
|
// next.proxyRequest(req, res, { port: 9000, host: 'localhost' });
|
||||||
|
//
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// The following fires just fine.
|
||||||
|
//proxy.proxyRequest(req, res, { port: 9000, host: 'localhost' });
|
||||||
|
//
|
||||||
|
console.log('request proxied...'.blue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var proxyServer = httpProxy.createServer(
|
||||||
|
// Your middleware stack goes here.
|
||||||
|
exports.bodyMod()
|
||||||
|
).listen(8000);
|
||||||
|
|
||||||
|
|
||||||
|
var httpServer = 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();
|
||||||
|
}).listen(9000);
|
||||||
87
examples/bodyDecoder-middleware.js
Normal file
87
examples/bodyDecoder-middleware.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
var Store = require('./lib/store')
|
||||||
|
, http = require('http')
|
||||||
|
|
||||||
|
http.createServer(new Store().handler()).listen(7531, function () {
|
||||||
|
//try these commands:
|
||||||
|
// get index:
|
||||||
|
// curl localhost:7531
|
||||||
|
// []
|
||||||
|
//
|
||||||
|
// get a doc:
|
||||||
|
// curl localhost:7531/foo
|
||||||
|
// {"error":"not_found"}
|
||||||
|
//
|
||||||
|
// post an doc:
|
||||||
|
// curl -X POST localhost:7531/foo -d '{"content": "hello", "type": "greeting"}'
|
||||||
|
// {"ok":true}
|
||||||
|
//
|
||||||
|
// get index (now, not empty)
|
||||||
|
// curl localhost:7531
|
||||||
|
// ["/foo"]
|
||||||
|
//
|
||||||
|
// get doc
|
||||||
|
// curl localhost:7531/foo
|
||||||
|
// {"content": "hello", "type": "greeting"}
|
||||||
|
|
||||||
|
//
|
||||||
|
// now, suppose we wanted to direct all objects where type == "greeting" to a different store
|
||||||
|
// than where type == "insult"
|
||||||
|
//
|
||||||
|
// we can use connect connect-bodyDecoder and some custom logic to send insults to another Store.
|
||||||
|
|
||||||
|
//insult server:
|
||||||
|
|
||||||
|
http.createServer(new Store().handler()).listen(2600, function () {
|
||||||
|
|
||||||
|
//greetings -> 7531, insults-> 2600
|
||||||
|
|
||||||
|
// now, start a proxy server.
|
||||||
|
|
||||||
|
var bodyParser = require('connect/lib/middleware/bodyParser')
|
||||||
|
//don't worry about incoming contont type
|
||||||
|
//bodyParser.parse[''] = JSON.parse
|
||||||
|
|
||||||
|
require('http-proxy').createServer(
|
||||||
|
//refactor the body parser and re-streamer into a separate package
|
||||||
|
bodyParser(),
|
||||||
|
//body parser absorbs the data and end events before passing control to the next
|
||||||
|
// middleware. if we want to proxy it, we'll need to re-emit these events after
|
||||||
|
//passing control to the middleware.
|
||||||
|
require('connect-restreamer')(),
|
||||||
|
function (req, res, proxy) {
|
||||||
|
//if your posting an obect which contains type: "insult"
|
||||||
|
//it will get redirected to port 2600.
|
||||||
|
//normal get requests will go to 7531 nad will not return insults.
|
||||||
|
var port = (req.body && req.body.type === 'insult' ? 2600 : 7531)
|
||||||
|
proxy.proxyRequest(req, res, {host: 'localhost', port: port})
|
||||||
|
}
|
||||||
|
).listen(1337, function () {
|
||||||
|
var request = require('request')
|
||||||
|
//bodyParser needs content-type set to application/json
|
||||||
|
//if we use request, it will set automatically if we use the 'json:' field.
|
||||||
|
function post (greeting, type) {
|
||||||
|
request.post({
|
||||||
|
url: 'http://localhost:1337/' + greeting,
|
||||||
|
json: {content: greeting, type: type || "greeting"}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
post("hello")
|
||||||
|
post("g'day")
|
||||||
|
post("kiora")
|
||||||
|
post("houdy")
|
||||||
|
post("java", "insult")
|
||||||
|
|
||||||
|
//now, the insult should have been proxied to 2600
|
||||||
|
|
||||||
|
//curl localhost:2600
|
||||||
|
//["/java"]
|
||||||
|
|
||||||
|
//but the greetings will be sent to 7531
|
||||||
|
|
||||||
|
//curl localhost:7531
|
||||||
|
//["/hello","/g%27day","/kiora","/houdy"]
|
||||||
|
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
65
examples/concurrent-proxy.js
Normal file
65
examples/concurrent-proxy.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
concurrent-proxy.js: check levelof concurrency through proxy.
|
||||||
|
|
||||||
|
Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Fedor Indutny, & Marak Squires.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
var util = require('util'),
|
||||||
|
colors = require('colors'),
|
||||||
|
http = require('http'),
|
||||||
|
httpProxy = require('./../lib/node-http-proxy');
|
||||||
|
|
||||||
|
//
|
||||||
|
// Basic Http Proxy Server
|
||||||
|
//
|
||||||
|
httpProxy.createServer(9000, 'localhost').listen(8000);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Target Http Server
|
||||||
|
//
|
||||||
|
// to check apparent problems with concurrent connections
|
||||||
|
// make a server which only responds when there is a given nubmer on connections
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
var connections = []
|
||||||
|
, go
|
||||||
|
|
||||||
|
http.createServer(function (req, res) {
|
||||||
|
|
||||||
|
connections.push (function (){
|
||||||
|
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
||||||
|
res.write('request successfully proxied to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2));
|
||||||
|
res.end();
|
||||||
|
})
|
||||||
|
process.stdout.write(connections.length + ', ')
|
||||||
|
if (connections.length > 110 || go) {
|
||||||
|
go = true
|
||||||
|
while(connections.length)
|
||||||
|
connections.shift()()
|
||||||
|
}
|
||||||
|
|
||||||
|
}).listen(9000);
|
||||||
|
|
||||||
|
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8000'.yellow);
|
||||||
|
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9000 '.yellow);
|
||||||
50
examples/gzip-middleware.js
Normal file
50
examples/gzip-middleware.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
gzip-middleware.js: Basic example of `connect-gzip` middleware in node-http-proxy
|
||||||
|
|
||||||
|
Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Fedor Indutny, Marak Squires, & Dominic Tarr.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
var util = require('util'),
|
||||||
|
colors = require('colors'),
|
||||||
|
http = require('http'),
|
||||||
|
httpProxy = require('./../lib/node-http-proxy');
|
||||||
|
|
||||||
|
//
|
||||||
|
// Basic Http Proxy Server
|
||||||
|
//
|
||||||
|
httpProxy.createServer(
|
||||||
|
require('connect-gzip').gzip({ matchType: /.?/ }),
|
||||||
|
9000, 'localhost'
|
||||||
|
).listen(8000);
|
||||||
|
|
||||||
|
//
|
||||||
|
// 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();
|
||||||
|
}).listen(9000);
|
||||||
|
|
||||||
|
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8000'.yellow);
|
||||||
|
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9000 '.yellow);
|
||||||
30
examples/jsonp-middleware.js
Normal file
30
examples/jsonp-middleware.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
var Store = require('./lib/store')
|
||||||
|
, http = require('http')
|
||||||
|
|
||||||
|
//
|
||||||
|
// jsonp is a handy technique for getting around the limitations of the same-origin policy.
|
||||||
|
// (http://en.wikipedia.org/wiki/Same_origin_policy)
|
||||||
|
//
|
||||||
|
// normally, to dynamically update a page you use an XmlHttpRequest. this has flakey support
|
||||||
|
// is some browsers and is restricted by the same origin policy. you cannot perform XHR requests to
|
||||||
|
// someone else's server. one way around this would be to proxy requests to all the servers you want
|
||||||
|
// to xhr to, and your core server - so that everything has the same port and host.
|
||||||
|
//
|
||||||
|
// another way, is to turn json into javascript. (which is exempt from the same origin policy)
|
||||||
|
// this is done by wrapping the json object in a function call, and then including a script tag.
|
||||||
|
//
|
||||||
|
// here we're proxing our own JSON returning server, but we could proxy any server on the internet,
|
||||||
|
// and our client side app would be slurping down JSONP from anywhere.
|
||||||
|
//
|
||||||
|
// curl localhost:1337/whatever?callback=alert
|
||||||
|
// alert([]) //which is valid javascript!
|
||||||
|
//
|
||||||
|
// also see http://en.wikipedia.org/wiki/JSONP#JSONP
|
||||||
|
//
|
||||||
|
|
||||||
|
http.createServer(new Store().handler()).listen(7531)
|
||||||
|
|
||||||
|
require('http-proxy').createServer(
|
||||||
|
require('connect-jsonp')(true),
|
||||||
|
'localhost', 7531
|
||||||
|
).listen(1337)
|
||||||
67
examples/lib/store.js
Normal file
67
examples/lib/store.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
module.exports = Store
|
||||||
|
//
|
||||||
|
// just to make these example a little bit interesting,
|
||||||
|
// make a little key value store with an http interface
|
||||||
|
// (see couchbd for a grown-up version of this)
|
||||||
|
//
|
||||||
|
// API:
|
||||||
|
// GET /
|
||||||
|
// retrive list of keys
|
||||||
|
//
|
||||||
|
// GET /[url]
|
||||||
|
// retrive object stored at [url]
|
||||||
|
// will respond with 404 if there is nothing stored at [url]
|
||||||
|
//
|
||||||
|
// POST /[url]
|
||||||
|
//
|
||||||
|
// JSON.parse the body and store it under [url]
|
||||||
|
// will respond 400 (bad request) if body is not valid json.
|
||||||
|
//
|
||||||
|
// TODO: cached map-reduce views and auto-magic sharding.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function Store () {
|
||||||
|
this.store = {}
|
||||||
|
}
|
||||||
|
Store.prototype = {
|
||||||
|
get: function (key) {
|
||||||
|
return this.store[key]
|
||||||
|
},
|
||||||
|
set: function (key, value) {
|
||||||
|
return this.store[key] = value
|
||||||
|
},
|
||||||
|
handler:function () {
|
||||||
|
var store = this
|
||||||
|
return function (req, res) {
|
||||||
|
function send (obj, status) {
|
||||||
|
res.writeHead(200 || status,{'Content-Type': 'application/json'})
|
||||||
|
res.write(JSON.stringify(obj) + '\n')
|
||||||
|
res.end()
|
||||||
|
}
|
||||||
|
var url = req.url.split('?').shift()
|
||||||
|
if(url === '/') {
|
||||||
|
console.log('get index')
|
||||||
|
return send(Object.keys(store.store))
|
||||||
|
} else if(req.method == 'GET') {
|
||||||
|
var obj = store.get (url)
|
||||||
|
send(obj || {error: 'not_found', url: url}, obj ? 200 : 404)
|
||||||
|
} else {
|
||||||
|
//post: buffer body, and parse.
|
||||||
|
var body = '', obj
|
||||||
|
req.on('data', function (c) { body += c})
|
||||||
|
req.on('end', function (c) {
|
||||||
|
try {
|
||||||
|
obj = JSON.parse(body)
|
||||||
|
} catch (err) {
|
||||||
|
return send (err, 400)
|
||||||
|
}
|
||||||
|
store.set(url, obj)
|
||||||
|
send({ok: true})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
examples/package.json
Normal file
12
examples/package.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "http-proxy-examples"
|
||||||
|
, "description": "packages required to run the examples"
|
||||||
|
, "version": "0.0.0"
|
||||||
|
, "dependencies": {
|
||||||
|
"connect": "1.6"
|
||||||
|
, "connect-gzip": "0.1"
|
||||||
|
, "connect-jsonp": "0.0.5"
|
||||||
|
, "connect-restreamer": "1"
|
||||||
|
, "proxy-by-url": "0.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
58
examples/url-middleware.js
Normal file
58
examples/url-middleware.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
url-middleware.js: Example of a simple url routing middleware for node-http-proxy
|
||||||
|
|
||||||
|
Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Fedor Indutny, & Marak Squires.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
var util = require('util'),
|
||||||
|
colors = require('colors'),
|
||||||
|
http = require('http'),
|
||||||
|
httpProxy = require('http-proxy');
|
||||||
|
|
||||||
|
//
|
||||||
|
// Now we set up our proxy.
|
||||||
|
//
|
||||||
|
httpProxy.createServer(
|
||||||
|
//
|
||||||
|
// This is where our middlewares go, with any options desired - in this case,
|
||||||
|
// the list of routes/URLs and their destinations.
|
||||||
|
//
|
||||||
|
require('proxy-by-url')({
|
||||||
|
'/hello': { port: 9000, host: 'localhost' },
|
||||||
|
'/charlie': { port: 80, host: 'charlieistheman.com' },
|
||||||
|
'/google': { port: 80, host: 'google.com' }
|
||||||
|
});
|
||||||
|
).listen(8000);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Target Http Server (to listen for requests on 'localhost')
|
||||||
|
//
|
||||||
|
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();
|
||||||
|
}).listen(9000);
|
||||||
|
|
||||||
|
// And finally, some colored startup output.
|
||||||
|
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8000'.yellow);
|
||||||
|
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9000 '.yellow);
|
||||||
31
examples/url-middleware2.js
Normal file
31
examples/url-middleware2.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
var util = require('util'),
|
||||||
|
colors = require('colors'),
|
||||||
|
http = require('http'),
|
||||||
|
httpProxy = require('http-proxy'),
|
||||||
|
Store = require('./lib/store')
|
||||||
|
|
||||||
|
http.createServer(new Store().handler()).listen(7531)
|
||||||
|
|
||||||
|
// Now we set up our proxy.
|
||||||
|
httpProxy.createServer(
|
||||||
|
// This is where our middlewares go, with any options desired - in this case,
|
||||||
|
// the list of routes/URLs and their destinations.
|
||||||
|
require('proxy-by-url')({
|
||||||
|
'/store': { port: 7531, host: 'localhost' },
|
||||||
|
'/': { port: 9000, host: 'localhost' }
|
||||||
|
})
|
||||||
|
).listen(8000);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Target Http Server (to listen for requests on 'localhost')
|
||||||
|
//
|
||||||
|
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();
|
||||||
|
}).listen(9000);
|
||||||
|
|
||||||
|
// And finally, some colored startup output.
|
||||||
|
util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8000'.yellow);
|
||||||
|
util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9000 '.yellow);
|
||||||
@ -47,6 +47,7 @@ var server = http.createServer(function (req, res) {
|
|||||||
res.writeHead(200);
|
res.writeHead(200);
|
||||||
res.end();
|
res.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(8080);
|
server.listen(8080);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@ -137,6 +137,34 @@ function stack (middlewares, proxy) {
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// stack
|
||||||
|
// adapted from https://github.com/creationix/stack
|
||||||
|
//
|
||||||
|
function stack (middlewares, proxy) {
|
||||||
|
var handle;
|
||||||
|
middlewares.reverse().forEach(function (layer) {
|
||||||
|
var child = handle;
|
||||||
|
handle = function (req, res) {
|
||||||
|
var next = function (err) {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
//
|
||||||
|
// TODO: figure out where to send errors.
|
||||||
|
// return error(req, res, err);
|
||||||
|
//
|
||||||
|
}
|
||||||
|
child(req, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
next.__proto__ = proxy;
|
||||||
|
layer(req, res, next);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// ### function createServer ([port, host, options, handler])
|
// ### function createServer ([port, host, options, handler])
|
||||||
// #### @port {number} **Optional** Port to use on the proxy target host.
|
// #### @port {number} **Optional** Port to use on the proxy target host.
|
||||||
@ -151,54 +179,69 @@ function stack (middlewares, proxy) {
|
|||||||
//
|
//
|
||||||
exports.createServer = function () {
|
exports.createServer = function () {
|
||||||
var args = Array.prototype.slice.call(arguments),
|
var args = Array.prototype.slice.call(arguments),
|
||||||
callback,
|
callback, forward,
|
||||||
options = {}, port, host, forward, silent, proxy, server, middleware = [];
|
port, host,
|
||||||
|
proxy, server,
|
||||||
|
options = {},
|
||||||
|
middleware = [],
|
||||||
|
silent;
|
||||||
|
|
||||||
args.forEach(function (arg) {
|
args.forEach(function (arg) {
|
||||||
|
|
||||||
switch (typeof arg) {
|
switch (typeof arg) {
|
||||||
case 'string': host = arg; break;
|
case 'string': host = arg; break;
|
||||||
case 'number': port = arg; break;
|
case 'number': port = arg; break;
|
||||||
case 'function': middleware.push(arg); break;
|
case 'function': middleware.push(handler = callback = arg); break;
|
||||||
case 'object': options = arg; break;
|
case 'object': options = arg; break;
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var proxy = new HttpProxy(options);
|
var proxy = new HttpProxy(options);
|
||||||
|
|
||||||
if(middleware.length)
|
if (port && host) {
|
||||||
//handler = callback = middleware.shift()
|
//
|
||||||
//else if (middleware.length)
|
// If we have a target host and port for the request
|
||||||
handler = callback = stack(middleware, proxy);
|
// then proxy to the specified location.
|
||||||
|
//
|
||||||
|
handler = function (req, res) {
|
||||||
|
proxy.proxyRequest(req, res, {
|
||||||
|
port: port,
|
||||||
|
host: host
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (port && host) {
|
if (middleware.length) {
|
||||||
//
|
middleware.push(handler);
|
||||||
// If we have a target host and port for the request
|
|
||||||
// then proxy to the specified location.
|
|
||||||
//
|
|
||||||
handler = function (req, res) {
|
|
||||||
proxy.proxyRequest(req, res, {
|
|
||||||
port: port,
|
|
||||||
host: host
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (proxy.proxyTable) {
|
}
|
||||||
//
|
else if (proxy.proxyTable) {
|
||||||
// If the proxy is configured with a ProxyTable
|
//
|
||||||
// instance then use that before failing.
|
// If the proxy is configured with a ProxyTable
|
||||||
//
|
// instance then use that before failing.
|
||||||
handler = function (req, res) {
|
//
|
||||||
proxy.proxyRequest(req, res);
|
handler = function (req, res) {
|
||||||
}
|
proxy.proxyRequest(req, res);
|
||||||
}
|
}
|
||||||
else if (!handler) {
|
|
||||||
//
|
if (middleware.length) {
|
||||||
// Otherwise this server is improperly configured.
|
middleware.push(handler);
|
||||||
//
|
|
||||||
throw new Error('Cannot proxy without port, host, or router.')
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (middleware.length > 1) {
|
||||||
|
handler = callback = stack(middleware, proxy);
|
||||||
|
}
|
||||||
|
else if (middleware.length) {
|
||||||
|
//do not use middleware code if it's not needed.
|
||||||
|
var h = middleware[0];
|
||||||
|
handler = callback = function (req,res) { h(req,res,proxy) };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handler) {
|
||||||
|
//
|
||||||
|
// Otherwise this server is improperly configured.
|
||||||
|
//
|
||||||
|
throw new Error('Cannot proxy without port, host, or router.')
|
||||||
|
}
|
||||||
|
|
||||||
server = options.https
|
server = options.https
|
||||||
? https.createServer(options.https, handler)
|
? https.createServer(options.https, handler)
|
||||||
@ -217,7 +260,6 @@ exports.createServer = function () {
|
|||||||
// websocket request automatically
|
// websocket request automatically
|
||||||
server.on('upgrade', function (req, socket, head) {
|
server.on('upgrade', function (req, socket, head) {
|
||||||
// Tunnel websocket requests too
|
// Tunnel websocket requests too
|
||||||
|
|
||||||
proxy.proxyWebSocketRequest(req, socket, head, {
|
proxy.proxyWebSocketRequest(req, socket, head, {
|
||||||
port: port,
|
port: port,
|
||||||
host: host
|
host: host
|
||||||
@ -338,7 +380,9 @@ HttpProxy.prototype.buffer = function (obj) {
|
|||||||
// if they exist.
|
// if they exist.
|
||||||
//
|
//
|
||||||
HttpProxy.prototype.close = function () {
|
HttpProxy.prototype.close = function () {
|
||||||
if (this.proxyTable) this.proxyTable.close();
|
if (this.proxyTable) {
|
||||||
|
this.proxyTable.close();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -405,7 +449,7 @@ HttpProxy.prototype.proxyRequest = function (req, res, options) {
|
|||||||
// * `x-forwarded-proto`: Protocol of the original request
|
// * `x-forwarded-proto`: Protocol of the original request
|
||||||
// * `x-forwarded-port`: Port of the original request.
|
// * `x-forwarded-port`: Port of the original request.
|
||||||
//
|
//
|
||||||
if (options.enableXForwarded == true) {
|
if (options.enableXForwarded === true) {
|
||||||
req.headers['x-forwarded-for'] = req.connection.remoteAddress || req.connection.socket.remoteAddress;
|
req.headers['x-forwarded-for'] = req.connection.remoteAddress || req.connection.socket.remoteAddress;
|
||||||
req.headers['x-forwarded-port'] = req.connection.remotePort || req.connection.socket.remotePort;
|
req.headers['x-forwarded-port'] = req.connection.remotePort || req.connection.socket.remotePort;
|
||||||
req.headers['x-forwarded-proto'] = res.connection.pair ? 'https' : 'http';
|
req.headers['x-forwarded-proto'] = res.connection.pair ? 'https' : 'http';
|
||||||
@ -619,12 +663,13 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
|
|||||||
location = this.proxyTable.getProxyLocation(req);
|
location = this.proxyTable.getProxyLocation(req);
|
||||||
|
|
||||||
if (!location) {
|
if (!location) {
|
||||||
res.writeHead(404);
|
return socket.destroy();
|
||||||
return res.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
options.port = location.port;
|
options.port = location.port;
|
||||||
options.host = location.host;
|
options.host = location.host;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// WebSocket requests must have the `GET` method and
|
// WebSocket requests must have the `GET` method and
|
||||||
// the `upgrade:websocket` header
|
// the `upgrade:websocket` header
|
||||||
@ -767,6 +812,7 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
|
|||||||
path: req.url,
|
path: req.url,
|
||||||
headers: req.headers,
|
headers: req.headers,
|
||||||
};
|
};
|
||||||
|
|
||||||
var reverseProxy = agent.appendMessage(outgoing);
|
var reverseProxy = agent.appendMessage(outgoing);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user