diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..099c4d9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,7 @@
+node_modules
+*.swp
+cov
+atest.js
+notes
+primus-proxy.js
+tes.js
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..ba5be41
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,12 @@
+language: node_js
+node_js:
+ - "0.10"
+ - "0.11"
+
+notifications:
+ email:
+ - travis@nodejitsu.com
+ irc: "irc.freenode.org#nodejitsu"
+
+script:
+ npm test
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..21d6bb0
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,4 @@
+### v 1.0.0-alpha
+
+- Complete refactor with new API
+
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..2bab4b9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,23 @@
+
+ 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.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3ec4ed5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,322 @@
+
+
+
+
+node-http-proxy
+=======
+
+`node-http-proxy` is an HTTP programmable proxying library that supports
+websockets. It is suitable for implementing components such as
+proxies and load balancers.
+
+### Build Status
+
+
+
+### Looking to Upgrade from 0.8.x ? Click [here](UPGRADING.md)
+
+### Core Concept
+
+A new proxy is created by calling `createProxyServer` and passing
+an `options` object as argument ([valid properties are available here](lib/http-proxy.js#L26-L39))
+
+```javascript
+var httpProxy = require('http-proxy');
+
+var proxy = httpProxy.createProxyServer(options);
+```
+
+An object will be returned with four values:
+
+* web `req, res, [options]` (used for proxying regular HTTP(S) requests)
+* ws `req, socket, head, [options]` (used for proxying WS(S) requests)
+* listen `port` (a function that wraps the object in a webserver, for your convenience)
+
+Is it then possible to proxy requests by calling these functions
+
+```javascript
+require('http').createServer(function(req, res) {
+ proxy.web(req, res, { target: 'http://mytarget.com:8080' });
+});
+```
+
+Errors can be listened on either using the Event Emitter API
+
+```javascript
+proxy.on('error', function(e) {
+ ...
+});
+```
+
+or using the callback API
+
+```javascript
+proxy.web(req, res, { target: 'http://mytarget.com:8080' }, function(e) { ... });
+```
+
+When a request is proxied it follows two different pipelines ([available here](lib/http-proxy/passes))
+which apply transformations to both the `req` and `res` object.
+The first pipeline (ingoing) is responsible for the creation and manipulation of the stream that connects your client to the target.
+The second pipeline (outgoing) is responsible for the creation and manipulation of the stream that, from your target, returns data
+to the client.
+
+
+#### Setup a basic stand-alone proxy server
+
+```js
+var http = require('http'),
+ httpProxy = require('http-proxy');
+//
+// Create your proxy server and set the target in the options.
+//
+httpProxy.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
+This example show how you can proxy a request using your own HTTP server
+and also you can put your own logic to handle the request.
+
+```js
+var http = require('http'),
+ httpProxy = require('http-proxy');
+
+//
+// Create a proxy server with custom application logic
+//
+var proxy = httpProxy.createProxyServer({});
+
+//
+// Create your custom server and just call `proxy.web()` to proxy
+// a web request to the target passed in the options
+// also you can use `proxy.ws()` to proxy a websockets request
+//
+var server = require('http').createServer(function(req, res) {
+ // You can define here your custom logic to handle the request
+ // and then proxy the request.
+ proxy.web(req, res, { target: 'http://127.0.0.1:5060' });
+});
+
+console.log("listening on port 5050")
+server.listen(5050);
+```
+
+#### Setup a stand-alone proxy server with latency
+
+```js
+var http = require('http'),
+ httpProxy = require('http-proxy');
+
+//
+// Create a proxy server with latency
+//
+var proxy = httpProxy.createProxyServer();
+
+//
+// Create your server that make an operation that take a while
+// and then proxy de request
+//
+http.createServer(function (req, res) {
+ // This simulate an operation that take 500ms in execute
+ setTimeout(function () {
+ proxy.web(req, res, {
+ target: 'http://localhost:9008'
+ });
+ }, 500);
+}).listen(8008);
+
+//
+// Create your target 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);
+```
+
+#### Listening for proxy events
+
+* `error`: The error event is emitted if the request to the target fail.
+* `proxyRes`: This event is emitted if the request to the target got a response.
+
+```js
+var httpProxy = require('http-proxy');
+// Error example
+//
+// Http Proxy Server with bad target
+//
+var proxy = httpProxy.createServer({
+ target:'http://localhost:9005'
+});
+
+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.');
+});
+
+//
+// Listen for the `proxyRes` event on `proxy`.
+//
+proxy.on('proxyRes', function (res) {
+ console.log('RAW Response from the target', JSON.stringify(res.headers, true, 2));
+});
+
+```
+
+#### Using HTTPS
+You can activate the validation of a secure SSL certificate to the target connection (avoid self signed certs), just set `secure: true` in the options.
+
+##### HTTPS -> HTTP
+
+```js
+//
+// Create the HTTPS proxy server in front of a HTTP server
+//
+httpProxy.createServer({
+ target: {
+ host: 'localhost',
+ port: 9009
+ },
+ ssl: {
+ key: fs.readFileSync('valid-ssl-key.pem'), 'utf8'),
+ cert: fs.readFileSync('valid-ssl-cert.pem'), 'utf8')
+ }
+}).listen(8009);
+```
+
+##### HTTPS -> HTTPS
+
+```js
+//
+// Create the proxy server listening on port 443
+//
+httpProxy.createServer({
+ ssl: {
+ key: fs.readFileSync('valid-ssl-key.pem'), 'utf8'),
+ cert: fs.readFileSync('valid-ssl-cert.pem'), 'utf8')
+ },
+ target: 'https://localhost:9010',
+ secure: true // Depends on your needs, could be false.
+}).listen(443);
+```
+
+#### Proxying WebSockets
+You can activate the websocket support for the proxy using `ws:true` in the options.
+
+```js
+//
+// Create a proxy server for websockets
+//
+httpProxy.createServer({
+ target: 'ws://localhost:9014',
+ ws: true
+}).listen(8014);
+```
+
+Also you can proxy the websocket requests just calling the `ws(req, socket, head)` method.
+
+```js
+//
+// 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);
+```
+
+### Contributing and Issues
+
+* Search on Google/Github
+* If you can't find anything, open an issue
+* If you feel comfortable about fixing the issue, fork the repo
+* Commit to your local branch (which must be different from `master`)
+* Submit your Pull Request (be sure to include tests and update documentation)
+
+### Options
+
+`httpProxy.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
+ * **agent**: object to be passed to http(s).request (see Node's [https agent](http://nodejs.org/api/https.html#https_class_https_agent) and [http agent](http://nodejs.org/api/http.html#http_class_http_agent) objects)
+ * **secure**: true/false, if you want to verify the SSL Certs
+
+If you are using the `proxyServer.listen` method, the following options are also applicable:
+
+ * **ssl**: object to be passed to https.createServer()
+ * **ws**: true/false, if you want to proxy websockets
+ * **xfwd**: true/false, adds x-forward headers
+
+
+### Test
+
+```
+$ npm test
+```
+
+### Logo
+
+Logo created by [Diego Pasquali](http://dribbble.com/diegopq)
+
+### License
+
+>The MIT License (MIT)
+>
+>Copyright (c) 2010 - 2013 Nodejitsu Inc.
+>
+>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.
+
+
diff --git a/UPGRADING.md b/UPGRADING.md
new file mode 100644
index 0000000..8c0db43
--- /dev/null
+++ b/UPGRADING.md
@@ -0,0 +1,96 @@
+Looking to upgrade from `http-proxy@0.x.x` to `http-proxy@1.0`? You've come to the right place!
+`http-proxy@1.0` is a from-scratch implementation of `http-proxy` and, as such
+brings some breaking changes to APIs.
+
+## Server creation
+
+Available through `.createServer()` or `.createProxyServer()`.
+
+```javascript
+httpProxy.createServer({
+ target:'http://localhost:9003'
+}).listen(8003);
+```
+
+Check the [README.md](https://github.com/nodejitsu/node-http-proxy/blob/caronte/README.md) for a more detailed explanation of the parameters.
+
+## Proxying
+
+Web proying is done by calling the `.web()` method on a Proxy instance. You can check among some use cases in the [examples folder](https://github.com/nodejitsu/node-http-proxy/tree/caronte/examples/http)
+
+```javascript
+//
+// Create a HTTP Proxy server with a HTTPS target
+//
+httpProxy.createProxyServer({
+ target: 'https://google.com',
+ agent : https.globalAgent,
+ headers: {
+ host: 'google.com'
+ }
+}).listen(8011);
+
+```
+
+Websockets are proxied by the `.ws()` method. The [examples folder](https://github.com/nodejitsu/node-http-proxy/tree/caronte/examples/websocket) again provides a lot of useful snippets!
+
+```javascript
+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);
+});
+```
+
+## Error Handling
+
+It is possible to listen globally on the `error` event on the server. In alternative, a
+callback passed to `.web()` or `.ws()` as last parameter is also accepted.
+
+```javascript
+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.');
+});
+```
+
+## Dropped
+
+Since the API was rewritten to be extremely flexible we decided to drop some features
+which were in the core and delegate them to eventual "userland" modules.
+
+- Middleware API
+- ProxyTable API
+
+### Middleware API
+
+The new API makes it really easy to implement code that behaves like the old Middleware API. You can check some examples [here](https://github.com/nodejitsu/node-http-proxy/tree/caronte/examples/middleware)
+
+
+
diff --git a/benchmark/README.md b/benchmark/README.md
new file mode 100644
index 0000000..2a852d1
--- /dev/null
+++ b/benchmark/README.md
@@ -0,0 +1,33 @@
+# Benchmarking `node-http-proxy`
+
+The long-term goal of these scripts and documentation is to provide a consistent and well understood benchmarking process for `node-http-proxy` so that performance does not degrade over time. They were initially created to compare the performance of `v0.10.3` and `v1.0.0` (which was a significant rewrite).
+
+## Pre-requisites
+
+All benchmarking shall be done with [wrk](https://github.com/wg/wrk) which _is the same tool used for performance testing by the node.js core team._ **Make sure you have `wrk` installed before continuing**.
+
+```
+$ wrk
+Usage: wrk
+ Options:
+ -c, --connections Connections to keep open
+ -r, --requests Total requests to make
+ -t, --threads Number of threads to use
+
+ -H, --header Add header to request
+ -v, --version Print version details
+
+ Numeric arguments may include a SI unit (2k, 2M, 2G)
+```
+
+## Benchmarks
+
+1. [Simple HTTP benchmark](#simple-http)
+
+### Simple HTTP
+
+_This benchmark requires three terminals running:_
+
+1. **A proxy server:** `node benchmark/scripts/proxy.js`
+2. **A target server:** `node benchmark/scripts/hello.js`
+3. **A wrk process:** `wrk -c 20 -r 10000 -t 2 http://127.0.0.1:8000`
\ No newline at end of file
diff --git a/benchmark/scripts/hello.js b/benchmark/scripts/hello.js
new file mode 100644
index 0000000..be09b63
--- /dev/null
+++ b/benchmark/scripts/hello.js
@@ -0,0 +1,3 @@
+require('http').createServer(function(req, res) {
+ res.end('Hello world!');
+}).listen(9000);
\ No newline at end of file
diff --git a/benchmark/scripts/proxy.js b/benchmark/scripts/proxy.js
new file mode 100644
index 0000000..a70c558
--- /dev/null
+++ b/benchmark/scripts/proxy.js
@@ -0,0 +1,6 @@
+var http = require('http'),
+ httpProxy = require('../../');
+//
+// Create your proxy server
+//
+httpProxy.createProxyServer({ target: 'http://localhost:9000' }).listen(8000);
\ No newline at end of file
diff --git a/benchmark/scripts/websockets-throughput.js b/benchmark/scripts/websockets-throughput.js
new file mode 100644
index 0000000..866e424
--- /dev/null
+++ b/benchmark/scripts/websockets-throughput.js
@@ -0,0 +1,88 @@
+var crypto = require('crypto'),
+ WebSocket = require('ws'),
+ async = require('async'),
+ httpProxy = require('../../');
+
+var SERVER_PORT = 8415,
+ PROXY_PORT = 8514;
+
+var testSets = [
+ {
+ size: 1024 * 1024, // 1 MB
+ count: 128 // 128 MB
+ },
+ {
+ size: 1024, // 1 KB,
+ count: 1024 // 1 MB
+ },
+ {
+ size: 128, // 128 B
+ count: 1024 * 8 // 1 MB
+ }
+];
+
+testSets.forEach(function (set) {
+ set.buffer = new Buffer(crypto.randomBytes(set.size));
+
+ set.buffers = [];
+ for (var i = 0; i < set.count; i++) {
+ set.buffers.push(set.buffer);
+ }
+});
+
+function runSet(set, callback) {
+ function runAgainst(port, callback) {
+ function send(sock) {
+ sock.send(set.buffers[got++]);
+ if (got === set.count) {
+ t = new Date() - t;
+
+ server.close();
+ proxy.close();
+
+ callback(null, t);
+ }
+ }
+
+ var server = new WebSocket.Server({ port: SERVER_PORT }),
+ proxy = httpProxy.createServer(SERVER_PORT, 'localhost').listen(PROXY_PORT),
+ client = new WebSocket('ws://localhost:' + port),
+ got = 0,
+ t = new Date();
+
+ server.on('connection', function (ws) {
+ send(ws);
+
+ ws.on('message', function (msg) {
+ send(ws);
+ });
+ });
+
+ client.on('message', function () {
+ send(client);
+ });
+ }
+
+ async.series({
+ server: async.apply(runAgainst, SERVER_PORT),
+ proxy: async.apply(runAgainst, PROXY_PORT)
+ }, function (err, results) {
+ if (err) {
+ throw err;
+ }
+
+ var mb = (set.size * set.count) / (1024 * 1024);
+ console.log(set.size / (1024) + ' KB * ' + set.count + ' (' + mb + ' MB)');
+
+ Object.keys(results).forEach(function (key) {
+ var t = results[key],
+ throughput = mb / (t / 1000);
+
+ console.log(' ' + key + ' took ' + t + ' ms (' + throughput + ' MB/s)');
+ });
+
+ callback();
+ });
+}
+
+async.forEachLimit(testSets, 1, runSet);
diff --git a/doc/logo.png b/doc/logo.png
new file mode 100644
index 0000000..a36bdcf
Binary files /dev/null and b/doc/logo.png differ
diff --git a/examples/balancer/simple-balancer-with-websockets.js b/examples/balancer/simple-balancer-with-websockets.js
new file mode 100644
index 0000000..cc13f4b
--- /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 0000000..3f53cc6
--- /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/helpers/store.js b/examples/helpers/store.js
new file mode 100644
index 0000000..e286057
--- /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 0000000..e9be0d7
--- /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 0000000..30aa53d
--- /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 0000000..1c54b5a
--- /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 0000000..292fb61
--- /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 0000000..c564bfb
--- /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 0000000..d94f484
--- /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 0000000..01ec93c
--- /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 0000000..ba5c838
--- /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 0000000..d2a2d5c
--- /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 0000000..e543f98
--- /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 0000000..410d70b
--- /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/middleware/bodyDecoder-middleware.js b/examples/middleware/bodyDecoder-middleware.js
new file mode 100644
index 0000000..555c3d1
--- /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 0000000..756b68f
--- /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 0000000..fdd7e65
--- /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 0000000..3daede1
--- /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/websocket/latent-websocket-proxy.js b/examples/websocket/latent-websocket-proxy.js
new file mode 100644
index 0000000..64d3d7c
--- /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 0000000..81d0196
--- /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 0000000..33d78c6
--- /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/index.js b/index.js
new file mode 100644
index 0000000..e6fac85
--- /dev/null
+++ b/index.js
@@ -0,0 +1,13 @@
+/*!
+ * Caron dimonio, con occhi di bragia
+ * loro accennando, tutte le raccoglie;
+ * batte col remo qualunque s’adagia
+ *
+ * Charon the demon, with the eyes of glede,
+ * Beckoning to them, collects them all together,
+ * Beats with his oar whoever lags behind
+ *
+ * Dante - The Divine Comedy (Canto III)
+ */
+
+module.exports = require('./lib/http-proxy');
\ No newline at end of file
diff --git a/lib/http-proxy.js b/lib/http-proxy.js
new file mode 100644
index 0000000..196dded
--- /dev/null
+++ b/lib/http-proxy.js
@@ -0,0 +1,48 @@
+var http = require('http'),
+ https = require('https'),
+ url = require('url'),
+ httpProxy = require('./http-proxy/');
+
+/**
+ * Export the the proxy "Server" as the main export
+ */
+module.exports = httpProxy.Server;
+
+/**
+ * Creates the proxy server.
+ *
+ * Examples:
+ *
+ * httpProxy.createProxyServer({ .. }, 8000)
+ * // => '{ web: [Function], ws: [Function] ... }'
+ *
+ * @param {Object} Options Config object passed to the proxy
+ *
+ * @return {Object} Proxy Proxy object with handlers for `ws` and `web` requests
+ *
+ * @api public
+ */
+
+module.exports.createProxyServer = module.exports.createServer = function createProxyServer(options) {
+ /*
+ * `options` is needed and it must have the following layout:
+ *
+ * {
+ * target :
+ * forward:
+ * agent :