diff --git a/.travis.yml b/.travis.yml index d7eeacc3f..ba5be4174 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,4 +9,4 @@ notifications: irc: "irc.freenode.org#nodejitsu" script: - npm run-script coveralls + npm test diff --git a/examples/balancer/simple-balancer-with-websockets.js b/examples/balancer/simple-balancer-with-websockets.js new file mode 100644 index 000000000..cc13f4b5c --- /dev/null +++ b/examples/balancer/simple-balancer-with-websockets.js @@ -0,0 +1,84 @@ +/* + simple-balancer.js: Example of a simple round robin balancer for websockets + + Copyright (c) Nodejitsu 2013 + + 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 http = require('http'), + httpProxy = require('../../lib/http-proxy'); + +// +// A simple round-robin load balancing strategy. +// +// First, list the servers you want to use in your rotation. +// +var addresses = [ + { + host: 'ws1.0.0.0', + port: 80 + }, + { + host: 'ws2.0.0.0', + port: 80 + } +]; + +// +// Create a HttpProxy object for each target +// + +var proxies = addresses.map(function (target) { + return new httpProxy.createProxyServer({ + target: target + }); +}); + +// +// Get the proxy at the front of the array, put it at the end and return it +// If you want a fancier balancer, put your code here +// + +function nextProxy() { + var proxy = proxies.shift(); + proxies.push(proxy); + return proxy; +} + +// +// Get the 'next' proxy and send the http request +// + +var server = http.createServer(function (req, res) { + nextProxy().web(req, res); +}); + +// +// Get the 'next' proxy and send the upgrade request +// + +server.on('upgrade', function (req, socket, head) { + nextProxy().ws(req, socket, head); +}); + +server.listen(8001); + \ No newline at end of file diff --git a/examples/balancer/simple-balancer.js b/examples/balancer/simple-balancer.js new file mode 100644 index 000000000..3f53cc63d --- /dev/null +++ b/examples/balancer/simple-balancer.js @@ -0,0 +1,64 @@ +/* + simple-balancer.js: Example of a simple round robin balancer + + Copyright (c) Nodejitsu 2013 + + 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 http = require('http'), + httpProxy = require('../../lib/http-proxy'); +// +// A simple round-robin load balancing strategy. +// +// First, list the servers you want to use in your rotation. +// +var addresses = [ + { + host: 'ws1.0.0.0', + port: 80 + }, + { + host: 'ws2.0.0.0', + port: 80 + } +]; +var proxy = httpProxy.createServer(); + +http.createServer(function (req, res) { + // + // On each request, get the first location from the list... + // + var target = { target: addresses.shift() }; + + // + // ...then proxy to the server whose 'turn' it is... + // + console.log('balancing request to: ', target); + proxy.web(req, res, target); + + // + // ...and then the server you just used becomes the last item in the list. + // + addresses.push(target); +}).listen(8021); + +// Rinse; repeat; enjoy. \ No newline at end of file diff --git a/examples/concurrent-proxy.js b/examples/concurrent-proxy.js deleted file mode 100644 index 0d1889f89..000000000 --- a/examples/concurrent-proxy.js +++ /dev/null @@ -1,36 +0,0 @@ -var http = require('http'), - httpProxy = require('../lib/http-proxy'); - -var connections = [], - go; - - -// -// Target Http Server -// -// to check apparent problems with concurrent connections -// make a server which only responds when there is a given nubmer on connections -// -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 > 10 || go) { - go = true; - while (connections.length) { - connections.shift()(); - } - } -}).listen(9000); -console.log("Web server listening on port 9000"); - -// -// Basic Http Proxy Server -// -httpProxy.createProxyServer({target:'http://localhost:9000'}).listen(8000); -console.log("Proxy server listening on port 8000"); \ No newline at end of file diff --git a/examples/error-handling.js b/examples/error-handling.js deleted file mode 100644 index 76a09d955..000000000 --- a/examples/error-handling.js +++ /dev/null @@ -1,33 +0,0 @@ -var httpProxy = require('../lib/http-proxy'), - http = require('http'); -/* - * Create your proxy server - */ -var proxy = httpProxy.createProxyServer({target:'http://localhost:30404', ws:true}); - -var proxyServer = http.createServer(requestHandler); - -function requestHandler(req, res) { - // Pass a callback to the web proxy method - // and catch the error there. - proxy.web(req, res, function (err) { - // Now you can get the err - // and handle it by your self - // if (err) throw err; - res.writeHead(502); - res.end("There was an error proxying your request"); - }); - - // In a websocket request case - req.on('upgrade', function (req, socket, head) { - proxy.ws(req, socket, head, function (err) { - // Now you can get the err - // and handle it by your self - // if (err) throw err; - socket.close(); - }) - }) -} - -console.log("Proxy server is listening on port 8000"); -proxyServer.listen(8000) \ No newline at end of file diff --git a/examples/forward-proxy.js b/examples/forward-proxy.js deleted file mode 100644 index 4cb516f50..000000000 --- a/examples/forward-proxy.js +++ /dev/null @@ -1,33 +0,0 @@ -var http = require('http'), - httpProxy = require('../lib/http-proxy'); - -// -// 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); -console.log("Web server listening on port 9000"); - -// -// Target Http Forwarding Server -// -http.createServer(function (req, res) { - console.log('Receiving forward for: ' + req.url); - res.writeHead(200, { 'Content-Type': 'text/plain' }); - res.write('request successfully forwarded to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2)); - res.end(); -}).listen(9001); - -// -// Basic Http Proxy Server -// Forward example: send requests without care about response -// -httpProxy.createServer({ - target: 'http://localhost:9000', - forward: 'http://localhost:9001' -}).listen(8000) -console.log("Proxy server listening on port 8000"); - diff --git a/examples/helpers/store.js b/examples/helpers/store.js new file mode 100644 index 000000000..e2860573f --- /dev/null +++ b/examples/helpers/store.js @@ -0,0 +1,64 @@ + +// +// 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. +// +var Store = module.exports = 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}) + }) + } + } + } +} diff --git a/examples/http/basic-proxy.js b/examples/http/basic-proxy.js new file mode 100644 index 000000000..e9be0d79b --- /dev/null +++ b/examples/http/basic-proxy.js @@ -0,0 +1,60 @@ +/* + basic-proxy.js: Basic example of proxying over HTTP + + Copyright (c) Nodejitsu 2013 + + 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/http-proxy'); + +var welcome = [ + '# # ##### ##### ##### ##### ##### #### # # # #', + '# # # # # # # # # # # # # # # # ', + '###### # # # # ##### # # # # # # ## # ', + '# # # # ##### ##### ##### # # ## # ', + '# # # # # # # # # # # # # ', + '# # # # # # # # #### # # # ' +].join('\n'); + +util.puts(welcome.rainbow.bold); + +// +// Basic Http Proxy Server +// +httpProxy.createServer({ + target:'http://localhost:9003' +}).listen(8003); + +// +// 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(9003); + +util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8003'.yellow); +util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9003 '.yellow); diff --git a/examples/http/concurrent-proxy.js b/examples/http/concurrent-proxy.js new file mode 100644 index 000000000..30aa53dd6 --- /dev/null +++ b/examples/http/concurrent-proxy.js @@ -0,0 +1,68 @@ +/* + concurrent-proxy.js: check levelof concurrency through proxy. + + Copyright (c) Nodejitsu 2013 + + 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/http-proxy'); + +// +// Basic Http Proxy Server +// +httpProxy.createServer({ + target:'http://localhost:9004' +}).listen(8004); + +// +// 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(9004); + +util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8004'.yellow); +util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9004 '.yellow); diff --git a/examples/http/custom-proxy-error.js b/examples/http/custom-proxy-error.js new file mode 100644 index 000000000..1c54b5ab8 --- /dev/null +++ b/examples/http/custom-proxy-error.js @@ -0,0 +1,55 @@ +/* + custom-proxy-error.js: Example of using the custom `proxyError` event. + + Copyright (c) Nodejitsu 2013 + + 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/http-proxy'); + +// +// Http Proxy Server with bad target +// +var proxy = httpProxy.createServer({ + target:'http://localhost:9005' +}); + +// +// Tell the proxy to listen on port 8000 +// +proxy.listen(8005); + +// +// Listen for the `error` event on `proxy`. +proxy.on('error', function (err, req, res) { + res.writeHead(500, { + 'Content-Type': 'text/plain' + }); + + res.end('Something went wrong. And we are reporting a custom error message.'); +}); + + +util.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8005 '.yellow + 'with custom error message'.magenta.underline); \ No newline at end of file diff --git a/examples/http/error-handling.js b/examples/http/error-handling.js new file mode 100644 index 000000000..292fb6144 --- /dev/null +++ b/examples/http/error-handling.js @@ -0,0 +1,63 @@ +/* + error-handling.js: Example of handle erros for HTTP and WebSockets + + Copyright (c) Nodejitsu 2013 + + 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/http-proxy'); + +// +// HTTP Proxy Server +// +var proxy = httpProxy.createProxyServer({target:'http://localhost:9000', ws:true}); + +// +// Example of error handling +// +function requestHandler(req, res) { + // Pass a callback to the web proxy method + // and catch the error there. + proxy.web(req, res, function (err) { + // Now you can get the err + // and handle it by your self + // if (err) throw err; + res.writeHead(502); + res.end("There was an error proxying your request"); + }); + + // In a websocket request case + req.on('upgrade', function (req, socket, head) { + proxy.ws(req, socket, head, function (err) { + // Now you can get the err + // and handle it by your self + // if (err) throw err; + socket.close(); + }) + }) +} + +http.createServer(requestHandler).listen(8000); +util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8000'.yellow); diff --git a/examples/http/forward-and-target-proxy.js b/examples/http/forward-and-target-proxy.js new file mode 100644 index 000000000..c564bfbbd --- /dev/null +++ b/examples/http/forward-and-target-proxy.js @@ -0,0 +1,67 @@ +/* + forward-and-target-proxy.js: Example of proxying over HTTP with additional forward proxy + + Copyright (c) Nodejitsu 2013 + + 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/http-proxy'); + +// +// Setup proxy server with forwarding +// +httpProxy.createServer({ + target: { + port: 9006, + host: 'localhost' + }, + forward: { + port: 9007, + host: 'localhost' + } +}).listen(8006); + +// +// 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(9006); + +// +// Target Http Forwarding Server +// +http.createServer(function (req, res) { + util.puts('Receiving forward for: ' + req.url); + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('request successfully forwarded to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2)); + res.end(); +}).listen(9007); + +util.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8006 '.yellow + 'with forward proxy'.magenta.underline); +util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9006 '.yellow); +util.puts('http forward server '.blue + 'started '.green.bold + 'on port '.blue + '9007 '.yellow); \ No newline at end of file diff --git a/examples/http/forward-proxy.js b/examples/http/forward-proxy.js new file mode 100644 index 000000000..d94f48414 --- /dev/null +++ b/examples/http/forward-proxy.js @@ -0,0 +1,53 @@ +/* + forward-proxy.js: Example of proxying over HTTP with additional forward proxy + + Copyright (c) Nodejitsu 2013 + + 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/http-proxy'); + +// +// Setup proxy server with forwarding +// +httpProxy.createServer({ + forward: { + port: 9019, + host: 'localhost' + } +}).listen(8019); + +// +// Target Http Forwarding Server +// +http.createServer(function (req, res) { + util.puts('Receiving forward for: ' + req.url); + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('request successfully forwarded to: ' + req.url + '\n' + JSON.stringify(req.headers, true, 2)); + res.end(); +}).listen(9019); + +util.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8019 '.yellow + 'with forward proxy'.magenta.underline); +util.puts('http forward server '.blue + 'started '.green.bold + 'on port '.blue + '9019 '.yellow); \ No newline at end of file diff --git a/examples/http/latent-proxy.js b/examples/http/latent-proxy.js new file mode 100644 index 000000000..01ec93cc7 --- /dev/null +++ b/examples/http/latent-proxy.js @@ -0,0 +1,54 @@ +/* + latent-proxy.js: Example of proxying over HTTP with latency + + Copyright (c) Nodejitsu 2013 + + 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/http-proxy'); + +// +// Http Proxy Server with Latency +// +var proxy = httpProxy.createProxyServer(); +http.createServer(function (req, res) { + setTimeout(function () { + proxy.web(req, res, { + target: 'http://localhost:9008' + }); + }, 500); +}).listen(8008); + +// +// 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(9008); + +util.puts('http proxy server '.blue + 'started '.green.bold + 'on port '.blue + '8008 '.yellow + 'with latency'.magenta.underline); +util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9008 '.yellow); diff --git a/examples/http/proxy-http-to-https.js b/examples/http/proxy-http-to-https.js new file mode 100644 index 000000000..ba5c83816 --- /dev/null +++ b/examples/http/proxy-http-to-https.js @@ -0,0 +1,46 @@ +/* + proxy-http-to-https.js: Basic example of proxying over HTTP to a target HTTPS server + + Copyright (c) Nodejitsu 2013 + + 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 https = require('https'), + http = require('http'), + util = require('util'), + path = require('path'), + fs = require('fs'), + colors = require('colors'), + httpProxy = require('../../lib/http-proxy'); + +// +// Create a HTTP Proxy server with a HTTPS target +// +httpProxy.createProxyServer({ + target: 'https://google.com', + agent : https.globalAgent, + headers: { + host: 'google.com' + } +}).listen(8011); + +util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8011'.yellow); \ No newline at end of file diff --git a/examples/http/proxy-https-to-http.js b/examples/http/proxy-https-to-http.js new file mode 100644 index 000000000..d2a2d5c0d --- /dev/null +++ b/examples/http/proxy-https-to-http.js @@ -0,0 +1,60 @@ +/* + proxy-https-to-http.js: Basic example of proxying over HTTPS to a target HTTP server + + Copyright (c) Nodejitsu 2013 + + 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 https = require('https'), + http = require('http'), + util = require('util'), + path = require('path'), + fs = require('fs'), + colors = require('colors'), + httpProxy = require('../../lib/http-proxy'), + fixturesDir = path.join(__dirname, '..', '..', 'test', 'fixtures'); + +// +// Create the target HTTP server +// +http.createServer(function (req, res) { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('hello http over https\n'); + res.end(); +}).listen(9009); + +// +// Create the HTTPS proxy server listening on port 8000 +// +httpProxy.createServer({ + target: { + host: 'localhost', + port: 9009 + }, + ssl: { + key: fs.readFileSync(path.join(fixturesDir, 'agent2-key.pem'), 'utf8'), + cert: fs.readFileSync(path.join(fixturesDir, 'agent2-cert.pem'), 'utf8') + } +}).listen(8009); + +util.puts('https proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8009'.yellow); +util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9009 '.yellow); diff --git a/examples/http/proxy-https-to-https.js b/examples/http/proxy-https-to-https.js new file mode 100644 index 000000000..e543f98a7 --- /dev/null +++ b/examples/http/proxy-https-to-https.js @@ -0,0 +1,59 @@ +/* + proxy-https-to-https.js: Basic example of proxying over HTTPS to a target HTTPS server + + Copyright (c) Nodejitsu 2013 + + 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 https = require('https'), + http = require('http'), + util = require('util'), + fs = require('fs'), + path = require('path'), + colors = require('colors'), + httpProxy = require('../../lib/http-proxy'), + fixturesDir = path.join(__dirname, '..', '..', 'test', 'fixtures'), + httpsOpts = { + key: fs.readFileSync(path.join(fixturesDir, 'agent2-key.pem'), 'utf8'), + cert: fs.readFileSync(path.join(fixturesDir, 'agent2-cert.pem'), 'utf8') + }; + +// +// Create the target HTTPS server +// +https.createServer(httpsOpts, function (req, res) { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('hello https\n'); + res.end(); +}).listen(9010); + +// +// Create the proxy server listening on port 443 +// +httpProxy.createServer({ + ssl: httpsOpts, + target: 'https://localhost:9010', + secure: false +}).listen(8010); + +util.puts('https proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8010'.yellow); +util.puts('https server '.blue + 'started '.green.bold + 'on port '.blue + '9010 '.yellow); diff --git a/examples/http/standalone-proxy.js b/examples/http/standalone-proxy.js new file mode 100644 index 000000000..410d70b31 --- /dev/null +++ b/examples/http/standalone-proxy.js @@ -0,0 +1,54 @@ +/* + standalone-proxy.js: Example of proxying over HTTP with a standalone HTTP server. + + Copyright (c) Nodejitsu 2013 + + 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/http-proxy'); + +// +// Http Server with proxyRequest Handler and Latency +// +var proxy = new httpProxy.createProxyServer(); +http.createServer(function (req, res) { + setTimeout(function () { + proxy.web(req, res, { + target: 'http://localhost:9002' + }); + }, 200); +}).listen(8002); + +// +// 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(9002); + +util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '8002 '.yellow + 'with proxy.web() handler'.cyan.underline + ' and latency'.magenta); +util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9001 '.yellow); diff --git a/examples/https-secure.js b/examples/https-secure.js deleted file mode 100644 index 83b87eb7c..000000000 --- a/examples/https-secure.js +++ /dev/null @@ -1,16 +0,0 @@ -var httpProxy = require('../lib/http-proxy'), - https = require('https'); -/* - * Create your proxy server pointing to a secure domain - * Enable ssl validation - */ -var options = { - target : 'https://google.com', - agent : https.globalAgent, - headers: {host: 'google.com'} -}; - -var proxyServer = httpProxy.createProxyServer(options); -console.log("Proxy server listening on port 8000"); -proxyServer.listen(8000); - diff --git a/examples/https.js b/examples/https.js deleted file mode 100644 index 364d7cb2f..000000000 --- a/examples/https.js +++ /dev/null @@ -1,13 +0,0 @@ -var httpProxy = require('../lib/http-proxy'); -/* - * Create your proxy server pointing to a secure domain - */ -var options = { - target:'https://google.com', - headers: {host: 'google.com'} -}; - -var proxyServer = httpProxy.createProxyServer(options); -console.log("Proxy server listening on port 8000"); -proxyServer.listen(8000); - diff --git a/examples/middleware/bodyDecoder-middleware.js b/examples/middleware/bodyDecoder-middleware.js new file mode 100644 index 000000000..555c3d154 --- /dev/null +++ b/examples/middleware/bodyDecoder-middleware.js @@ -0,0 +1,119 @@ +/* + bodyDecoder-middleware.js: Basic example of `connect.bodyParser()` middleware in node-http-proxy + + Copyright (c) Nodejitsu 2013 + + 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 http = require('http'), + connect = require('connect'), + request = require('request'), + colors = require('colors'), + util = require('util'), + Store = require('../helpers/store'), + httpProxy = require('../../lib/http-proxy'), + proxy = httpProxy.createProxyServer({}); + +http.createServer(new Store().handler()).listen(7531, function () { + util.puts('http '.blue + 'greetings '.green + 'server'.blue + ' started '.green.bold + 'on port '.blue + '7531'.yellow); +//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 () { + util.puts('http '.blue + 'insults '.red + 'server'.blue + ' started '.green.bold + 'on port '.blue + '2600'.yellow); + + //greetings -> 7531, insults-> 2600 + + // now, start a proxy server. + + //don't worry about incoming contont type + //bodyParser.parse[''] = JSON.parse + + connect.createServer( + //refactor the body parser and re-streamer into a separate package + connect.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) { + //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.web(req, res, { target: { host: 'localhost', port: port }}); + } + ).listen(1337, function () { + util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '1337'.yellow); + //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"] + + }) + }) +}); \ No newline at end of file diff --git a/examples/middleware/gzip-middleware.js b/examples/middleware/gzip-middleware.js new file mode 100644 index 000000000..756b68fa3 --- /dev/null +++ b/examples/middleware/gzip-middleware.js @@ -0,0 +1,65 @@ +/* + gzip-middleware.js: Basic example of `connect-gzip` middleware in node-http-proxy + + Copyright (c) Nodejitsu 2013 + + 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'), + connect = require('connect') + httpProxy = require('../../lib/http-proxy'); + +// +// Basic Connect App +// +connect.createServer( + connect.compress({ + // Pass to connect.compress() the options + // that you need, just for show the example + // we use threshold to 1 + threshold: 1 + }), + function (req, res) { + proxy.web(req, res); + } +).listen(8012); + +// +// Basic Http Proxy Server +// +var proxy = httpProxy.createProxyServer({ + target: 'http://localhost:9012' +}); + +// +// 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(9012); + +util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8012'.yellow); +util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9012 '.yellow); diff --git a/examples/middleware/modifyResponse-middleware.js b/examples/middleware/modifyResponse-middleware.js new file mode 100644 index 000000000..fdd7e6596 --- /dev/null +++ b/examples/middleware/modifyResponse-middleware.js @@ -0,0 +1,67 @@ +/* + modifyBody-middleware.js: Example of middleware which modifies response + + Copyright (c) Nodejitsu 2013 + + 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'), + connect = require('connect'), + httpProxy = require('../../lib/http-proxy'); + +// +// Basic Connect App +// +connect.createServer( + function (req, res, next) { + var _write = res.write; + + res.write = function (data) { + _write.call(res, data.toString().replace("Ruby", "nodejitsu")); + } + next(); + }, + function (req, res) { + proxy.web(req, res); + } +).listen(8013); + +// +// Basic Http Proxy Server +// +var proxy = httpProxy.createProxyServer({ + target: 'http://localhost:9013' +}); + +// +// Target Http Server +// +http.createServer(function (req, res) { + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.end('Hello, I know Ruby\n'); +}).listen(9013); + +util.puts('http proxy server'.blue + ' started '.green.bold + 'on port '.blue + '8013'.yellow); +util.puts('http server '.blue + 'started '.green.bold + 'on port '.blue + '9013 '.yellow); + diff --git a/examples/package.json b/examples/package.json new file mode 100644 index 000000000..3daede1f1 --- /dev/null +++ b/examples/package.json @@ -0,0 +1,13 @@ +{ + "name": "http-proxy-examples", + "description": "packages required to run the examples", + "version": "0.0.0", + "dependencies": { + "colors": "~0.6.2", + "socket.io": "~0.9.16", + "socket.io-client": "~0.9.16", + "connect": "~2.11.0", + "request": "~2.27.0", + "connect-restreamer": "~1.0.0" + } +} diff --git a/examples/stand-alone.js b/examples/stand-alone.js deleted file mode 100644 index e5239c460..000000000 --- a/examples/stand-alone.js +++ /dev/null @@ -1,17 +0,0 @@ -var http = require('http'), - httpProxy = require('../lib/http-proxy'); -// -// Create your proxy server -// -console.log("Proxy server listening on port 8000"); -httpProxy.createProxyServer({target:'http://localhost:9000'}).listen(8000); - -// -// Create your target server -// -console.log("Web server listening on port 9000"); -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/examples/websocket/latent-websocket-proxy.js b/examples/websocket/latent-websocket-proxy.js new file mode 100644 index 000000000..64d3d7ce0 --- /dev/null +++ b/examples/websocket/latent-websocket-proxy.js @@ -0,0 +1,91 @@ +/* + standalone-websocket-proxy.js: Example of proxying websockets over HTTP with a standalone HTTP server. + + Copyright (c) Nodejitsu 2013 + + 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'), + http = require('http'), + colors = require('colors'), + httpProxy = require('../../lib/http-proxy'); + +try { + var io = require('socket.io'), + client = require('socket.io-client'); +} +catch (ex) { + console.error('Socket.io is required for this example:'); + console.error('npm ' + 'install'.green); + process.exit(1); +} + +// +// Create the target HTTP server and setup +// socket.io on it. +// +var server = io.listen(9016); +server.sockets.on('connection', function (client) { + util.debug('Got websocket connection'); + + client.on('message', function (msg) { + util.debug('Got message from client: ' + msg); + }); + + client.send('from server'); +}); + +// +// Setup our server to proxy standard HTTP requests +// +var proxy = new httpProxy.createProxyServer({ + target: { + host: 'localhost', + port: 9016 + } +}); + +var proxyServer = http.createServer(function (req, res) { + proxy.web(req, res); +}); + +// +// Listen to the `upgrade` event and proxy the +// WebSocket requests as well. +// +proxyServer.on('upgrade', function (req, socket, head) { + setTimeout(function () { + proxy.ws(req, socket, head); + }, 1000); +}); + +proxyServer.listen(8016); + +// +// Setup the socket.io client against our proxy +// +var ws = client.connect('ws://localhost:8016'); + +ws.on('message', function (msg) { + util.debug('Got message: ' + msg); + ws.send('I am the client'); +}); diff --git a/examples/websocket/standalone-websocket-proxy.js b/examples/websocket/standalone-websocket-proxy.js new file mode 100644 index 000000000..81d019650 --- /dev/null +++ b/examples/websocket/standalone-websocket-proxy.js @@ -0,0 +1,88 @@ +/* + standalone-websocket-proxy.js: Example of proxying websockets over HTTP with a standalone HTTP server. + + Copyright (c) Nodejitsu 2013 + + 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'), + http = require('http'), + colors = require('colors'), + httpProxy = require('../../lib/http-proxy'); + +try { + var io = require('socket.io'), + client = require('socket.io-client'); +} +catch (ex) { + console.error('Socket.io is required for this example:'); + console.error('npm ' + 'install'.green); + process.exit(1); +} + +// +// Create the target HTTP server and setup +// socket.io on it. +// +var server = io.listen(9015); +server.sockets.on('connection', function (client) { + util.debug('Got websocket connection'); + + client.on('message', function (msg) { + util.debug('Got message from client: ' + msg); + }); + + client.send('from server'); +}); + +// +// Setup our server to proxy standard HTTP requests +// +var proxy = new httpProxy.createProxyServer({ + target: { + host: 'localhost', + port: 9015 + } +}); +var proxyServer = http.createServer(function (req, res) { + proxy.web(req, res); +}); + +// +// Listen to the `upgrade` event and proxy the +// WebSocket requests as well. +// +proxyServer.on('upgrade', function (req, socket, head) { + proxy.ws(req, socket, head); +}); + +proxyServer.listen(8015); + +// +// Setup the socket.io client against our proxy +// +var ws = client.connect('ws://localhost:8015'); + +ws.on('message', function (msg) { + util.debug('Got message: ' + msg); + ws.send('I am the client'); +}); diff --git a/examples/websocket/websocket-proxy.js b/examples/websocket/websocket-proxy.js new file mode 100644 index 000000000..33d78c675 --- /dev/null +++ b/examples/websocket/websocket-proxy.js @@ -0,0 +1,70 @@ +/* + web-socket-proxy.js: Example of proxying over HTTP and WebSockets. + + Copyright (c) Nodejitsu 2013 + + 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'), + http = require('http'), + colors = require('colors'), + httpProxy = require('../../lib/http-proxy'); + +try { + var io = require('socket.io'), + client = require('socket.io-client'); +} +catch (ex) { + console.error('Socket.io is required for this example:'); + console.error('npm ' + 'install'.green); + process.exit(1); +} + +// +// Create the target HTTP server and setup +// socket.io on it. +// +var server = io.listen(9014); +server.sockets.on('connection', function (client) { + util.debug('Got websocket connection'); + + client.on('message', function (msg) { + util.debug('Got message from client: ' + msg); + }); + + client.send('from server'); +}); + +// +// Create a proxy server with node-http-proxy +// +httpProxy.createServer({ target: 'ws://localhost:9014', ws: true }).listen(8014); + +// +// Setup the socket.io client against our proxy +// +var ws = client.connect('ws://localhost:8014'); + +ws.on('message', function (msg) { + util.debug('Got message: ' + msg); + ws.send('I am the client'); +}); diff --git a/package.json b/package.json index 98cd9b5d4..5c7c3a1eb 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "blanket" : "*", "ws" : "*", "socket.io" : "*", - "socket.io-client" : "*" + "socket.io-client" : "*", + "async" : "*" }, "scripts" : { "coveralls" : "mocha --require blanket --reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js", diff --git a/test/examples-test.js b/test/examples-test.js new file mode 100644 index 000000000..8464e3fe5 --- /dev/null +++ b/test/examples-test.js @@ -0,0 +1,71 @@ +/* + examples-test.js: Test to run all the examples + + Copyright (c) Nodejitsu 2013 + +*/ +var path = require('path'), + fs = require('fs'), + spawn = require('child_process').spawn, + expect = require('expect.js'), + async = require('async'); + +var rootDir = path.join(__dirname, '..'), + examplesDir = path.join(rootDir, 'examples'); + +describe.skip('http-proxy examples', function () { + describe('Before testing examples', function () { + // Set a timeout to avoid this error + this.timeout(30 * 1000); + it('should have installed dependencies', function (done) { + async.waterfall([ + // + // 1. Read files in examples dir + // + async.apply(fs.readdir, examplesDir), + // + // 2. If node_modules exists, continue. Otherwise + // exec `npm` to install them + // + function checkNodeModules(files, next) { + if (files.indexOf('node_modules') !== -1) { + return next(); + } + + console.log('Warning: installing dependencies, this operation could take a while'); + + var child = spawn('npm', ['install', '-f'], { + cwd: examplesDir + }); + + child.on('exit', function (code) { + return code + ? next(new Error('npm install exited with non-zero exit code')) + : next(); + }); + }, + // + // 3. Read files in examples dir again to ensure the install + // worked as expected. + // + async.apply(fs.readdir, examplesDir), + ], done); + }) + }); + + describe('Requiring all the examples', function () { + it('should have no errors', function (done) { + async.each(['balancer', 'http', 'middleware', 'websocket'], function (dir, cb) { + var name = 'examples/' + dir, + files = fs.readdirSync(path.join(rootDir, 'examples', dir)); + + async.each(files, function (file, callback) { + var example; + expect(function () { example = require(path.join(examplesDir, dir, file)); }).to.not.throwException(); + expect(example).to.be.an('object'); + callback(); + }, cb); + }, done); + }) + }) +}) \ No newline at end of file