diff --git a/README.md b/README.md index 86e7ff746..e5b38566b 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,43 @@ You can easily add a `pass` (stages) into both the pipelines (XXX: ADD API). In addition, every stage emits a corresponding event so introspection during the process is always available. +#### Setup a basic stand-alone proxy server + +var http = require('http'), + caronte = require('caronte'); +// +// Create your proxy server +// +caronte.createProxyServer({target:'http://localhost:9000'}).listen(8000); + +// +// 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(); +}).listen(9000); + +#### Setup a stand-alone proxy server with custom server logic + +``` js +var http = require('http'), + caronte = require('caronte'); + +// +// Create a proxy server with custom application logic +// +var proxy = caronte.createProxyServer({}); + +var server = require('http').createServer(function(req, res) { + proxy.web(req, res, { target: 'http://127.0.0.1:5060' }); +}); + +console.log("listening on port 5050") +server.listen(5050); +``` + ### Contributing and Issues * Search on Google/Github @@ -53,6 +90,17 @@ In addition, every stage emits a corresponding event so introspection during the * Commit to your local branch (which must be different from `master`) * Submit your Pull Request (be sure to include tests and update documentation) +### Options + +`caronte.createProxyServer` supports the following options: + + * **target**: url string to be parsed with the url module + * **forward**: url string to be parsed with the url module + * **ssl**: object to be passed to https.createServer() + * **ws**: true/false, if you want to proxy websockets + * **xfwd**: true/false, adds x-forward headers + * **maxSock**: maximum number of sockets + ### Test ``` diff --git a/examples/stand-alone.js b/examples/stand-alone.js new file mode 100644 index 000000000..d3848abf4 --- /dev/null +++ b/examples/stand-alone.js @@ -0,0 +1,15 @@ +var http = require('http'), + caronte = require('caronte'); +// +// Create your proxy server +// +caronte.createProxyServer({target:'http://localhost:9000'}).listen(8000); + +// +// 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(); +}).listen(9000); \ No newline at end of file diff --git a/lib/caronte/index.js b/lib/caronte/index.js index 30db143f5..ef0187fa9 100644 --- a/lib/caronte/index.js +++ b/lib/caronte/index.js @@ -1,5 +1,7 @@ var caronte = exports, - web = require('./passes/web-incoming'); + extend = require('util')._extend, + parse_url = require('url').parse, + web = require('./passes/web-incoming'), ws = require('./passes/ws-incoming'); caronte.createWebProxy = createRightProxy('web'); @@ -41,7 +43,11 @@ function createRightProxy(type) { !(args[cntr] instanceof Buffer) && args[cntr] !== res ) { - options = args[cntr]; + //Copy global options + options = extend({}, options); + //Overwrite with request options + extend(options, args[cntr]); + cntr--; } @@ -51,7 +57,12 @@ function createRightProxy(type) { options.ee.emit(ev + 'begin', req, res); - + ['target', 'forward'].forEach( + function(e) { + if (typeof options[e] === 'string') + options[e] = parse_url(options[e]); + }); + passes.some(function(pass) { var evnt = ev + pass.name.toLowerCase() + ':'; diff --git a/lib/caronte/passes/web-incoming.js b/lib/caronte/passes/web-incoming.js index 6906ae873..66beb011c 100644 --- a/lib/caronte/passes/web-incoming.js +++ b/lib/caronte/passes/web-incoming.js @@ -102,6 +102,14 @@ function stream(req, res, options) { common.setupOutgoing(options.ssl || {}, options, req) ); + proxyReq.on('error', function(err){ + var ev = 'caronte:outgoing:web:'; + if (options.ee.listeners(ev + 'error').length == 0){ + throw err; + } + options.ee.emit(ev + 'error', err, req, res); + }); + req.pipe(proxyReq); proxyReq.on('response', function(proxyRes) { diff --git a/lib/caronte/passes/ws-incoming.js b/lib/caronte/passes/ws-incoming.js index 1fd3fd780..3b5e1f525 100644 --- a/lib/caronte/passes/ws-incoming.js +++ b/lib/caronte/passes/ws-incoming.js @@ -78,6 +78,13 @@ function stream(req, socket, options, head) { var proxyReq = (~['https:', 'wss:'].indexOf(options.target.protocol) ? https : http).request( common.setupOutgoing(options.ssl || {}, options, req) ); + proxyReq.on('error', function(err){ + var ev = 'caronte:outgoing:ws:'; + if (options.ee.listeners(ev + 'error').length == 0){ + throw err; + } + options.ee.emit(ev + 'error', err, req, res); + }); proxyReq.on('upgrade', function(proxyRes, proxySocket, proxyHead) { common.setupSocket(proxySocket);