diff --git a/lib/node-http-proxy.js b/lib/node-http-proxy.js
index 1e5df658bc004978c65af6c8fdf45efbef053011..aaf3a34bd817fbe6f78792dfba087016a87f6c22 100644
--- a/lib/node-http-proxy.js
+++ b/lib/node-http-proxy.js
@@ -1,28 +1,28 @@
 /*
-  node-http-proxy.js: http proxy for node.js
+ node-http-proxy.js: http proxy for node.js
 
-  Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Marak Squires, Fedor Indutny
+ Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Marak Squires, Fedor Indutny
 
-  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:
+ 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 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.
+ 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'),
@@ -49,25 +49,25 @@ var _agents = {};
 // Retreives an agent from the `http` or `https` module
 // and sets the `maxSockets` property appropriately.
 //
-function _getAgent (host, port, secure) {
-  var Agent, id = [host, port].join(':');
+function _getAgent(host, port, secure) {
+    var Agent, id = [host, port].join(':');
 
-  if (!port) {
-    port = secure ? 443 : 80;
-  }
+    if (!port) {
+        port = secure ? 443 : 80;
+    }
 
-  if (!_agents[id]) {
-    Agent = secure ? https.Agent : http.Agent;
+    if (!_agents[id]) {
+        Agent = secure ? https.Agent : http.Agent;
 
-    _agents[id] = new Agent({ 
-      host: host, 
-      port: port
-    });
+        _agents[id] = new Agent({
+            host: host,
+            port: port
+        });
 
-    _agents[id].maxSockets = maxSockets;
-  }
+        _agents[id].maxSockets = maxSockets;
+    }
 
-  return _agents[id];
+    return _agents[id];
 }
 
 //
@@ -79,19 +79,19 @@ function _getAgent (host, port, secure) {
 // the options in `outgoing` as appropriate by adding `ca`, `key`,
 // and `cert` if they exist in `secure`.
 //
-function _getProtocol (secure, outgoing) {
-  var protocol = secure ? https : http;
+function _getProtocol(secure, outgoing) {
+    var protocol = secure ? https : http;
 
-  if (typeof secure === 'object') {
-    outgoing = outgoing || {};
-    ['ca', 'cert', 'key'].forEach(function (prop) {
-      if (secure[prop]) {
-        outgoing[prop] = secure[prop];
-      }
-    })
-  }
+    if (typeof secure === 'object') {
+        outgoing = outgoing || {};
+        ['ca', 'cert', 'key'].forEach(function (prop) {
+            if (secure[prop]) {
+                outgoing[prop] = secure[prop];
+            }
+        })
+    }
 
-  return protocol;
+    return protocol;
 }
 
 //
@@ -101,7 +101,7 @@ function _getProtocol (secure, outgoing) {
 // made by __all__ instances of `HttpProxy`
 //
 exports.getMaxSockets = function () {
-  return maxSockets;
+    return maxSockets;
 };
 
 //
@@ -111,35 +111,35 @@ exports.getMaxSockets = function () {
 // made by __all__ instances of `HttpProxy`
 //
 exports.setMaxSockets = function (value) {
-  maxSockets = value;
+    maxSockets = value;
 };
 
 //
 // ### function stack (middlewares, proxy)
 // adapted from https://github.com/creationix/stack
 //
-exports.stack = function stack (middlewares, proxy) {
-  var handle;
-  middlewares.reverse().forEach(function (layer) {
-    var child = handle;
-    handle = function (req, res) {
-      var next = function (err) {
-        if (err) {
-          throw err;
-          //
-          // TODO: figure out where to send errors.
-          // return error(req, res, err);
-          //
-        }
-        child(req, res);
-      }
-
-      next.__proto__ = proxy;
-      layer(req, res, next);
-    };
-  });
+exports.stack = function stack(middlewares, proxy) {
+    var handle;
+    middlewares.reverse().forEach(function (layer) {
+        var child = handle;
+        handle = function (req, res) {
+            var next = function (err) {
+                if (err) {
+                    throw err;
+                    //
+                    // TODO: figure out where to send errors.
+                    // return error(req, res, err);
+                    //
+                }
+                child(req, res);
+            }
+
+            next.__proto__ = proxy;
+            layer(req, res, next);
+        };
+    });
 
-  return handle;
+    return handle;
 }
 
 //
@@ -155,104 +155,115 @@ exports.stack = function stack (middlewares, proxy) {
 // * `httpPRoxy.createServer(function (req, res, proxy) { ... })`
 //
 exports.createServer = function () {
-  var args = Array.prototype.slice.call(arguments),
-      callback, forward,
-      port, host,
-      proxy, server,
-      options = {},
-      middleware = [],
-      handler,
-      silent;
-
-  args.forEach(function (arg) {
-    switch (typeof arg) {
-      case 'string': host = arg; break;
-      case 'number': port = arg; break;
-      case 'function': middleware.push(handler = callback = arg); break;
-      case 'object': options = arg; break;
-    };
-  });
+    var args = Array.prototype.slice.call(arguments),
+        callback, forward,
+        port, host,
+        proxy, server,
+        options = {},
+        middleware = [],
+        handler,
+        silent;
+
+    args.forEach(function (arg) {
+        switch (typeof arg) {
+            case 'string':
+                host = arg;
+                break;
+            case 'number':
+                port = arg;
+                break;
+            case 'function':
+                middleware.push(handler = callback = arg);
+                break;
+            case 'object':
+                options = arg;
+                break;
+        }
+        ;
+    });
 
-  proxy = new HttpProxy(options);
+    proxy = new HttpProxy(options);
 
-  if (port && host) {
-    //
-    // If we have a target host and port for the request
-    // then proxy to the specified location.
-    //
-    handler = function (req, res) {
-      proxy.proxyRequest(req, res, {
-        port: port,
-        host: host
-      });
-    }
+    if (port && host) {
+        //
+        // If we have a target host and port for the request
+        // then proxy to the specified location.
+        //
+        handler = function (req, res) {
+            proxy.proxyRequest(req, res, {
+                port: port,
+                host: host
+            });
+        }
 
-    if (middleware.length) {
-      middleware.push(handler);
+        if (middleware.length) {
+            middleware.push(handler);
+        }
     }
-  }
-  else if (proxy.proxyTable) {
-    //
-    // If the proxy is configured with a ProxyTable
-    // instance then use that before failing.
-    //
-    handler = function (req, res) {
-      proxy.proxyRequest(req, res);
+    else if (proxy.proxyTable) {
+        //
+        // If the proxy is configured with a ProxyTable
+        // instance then use that before failing.
+        //
+        handler = function (req, res) {
+            proxy.proxyRequest(req, res);
+        }
+
+        if (middleware.length) {
+            middleware.push(handler);
+        }
     }
 
-    if (middleware.length) {
-      middleware.push(handler);
+    if (middleware.length > 1) {
+        handler = callback = exports.stack(middleware, proxy);
+    }
+    else if (middleware.length) {
+        //
+        // Do not use middleware code if it's not needed.
+        //
+        var h = middleware[0];
+        handler = callback = function (req, res) {
+            h(req, res, proxy)
+        };
     }
-  }
 
-  if (middleware.length > 1) {
-    handler = callback = exports.stack(middleware, proxy);
-  }
-  else if (middleware.length) { 
-    //
-    // Do not use middleware code if it's not needed.
-    //
-    var h = middleware[0];
-    handler = callback = function (req,res) { h(req,res,proxy) };
-  }
+    if (!handler) {
+        //
+        // Otherwise this server is improperly configured.
+        //
+        throw new Error('Cannot proxy without port, host, or router.')
+    }
 
-  if (!handler) {
-    //
-    // Otherwise this server is improperly configured.
-    //
-    throw new Error('Cannot proxy without port, host, or router.')
-  }
+    server = options.https
+        ? https.createServer(options.https, handler)
+        : http.createServer(handler);
 
-  server = options.https
-    ? https.createServer(options.https, handler)
-    : http.createServer(handler);
+    server.on('close', function () {
+        proxy.close();
+    });
 
-  server.on('close', function () {
-    proxy.close();
-  });
+    proxy.on('routes', function (routes) {
+        server.emit('routes', routes);
+    });
 
-  proxy.on('routes', function (routes) {
-    server.emit('routes', routes);
-  });
+    if (!callback) {
+        // WebSocket support: if callback is empty tunnel
+        // websocket request automatically
+        server.on('upgrade', function (req, socket, head) {
+            // Tunnel websocket requests too
+            proxy.proxyWebSocketRequest(req, socket, head, {
+                port: port,
+                host: host
+            });
+        });
+    }
 
-  if (!callback) {
-    // WebSocket support: if callback is empty tunnel
-    // websocket request automatically
-    server.on('upgrade', function (req, socket, head) {
-      // Tunnel websocket requests too
-      proxy.proxyWebSocketRequest(req, socket, head, {
-        port: port,
-        host: host
-      });
-    });
-  }
-
-  //
-  // Set the proxy on the server so it is available
-  // to the consumer of the server
-  //
-  server.proxy = proxy;
-  return server;
+    //
+    // Set the proxy on the server so it is available
+    // to the consumer of the server
+    //
+    server.proxy = proxy;
+    return server;
 };
 
 //
@@ -275,34 +286,34 @@ exports.createServer = function () {
 //      }
 //
 var HttpProxy = exports.HttpProxy = function (options) {
-  events.EventEmitter.call(this);
-
-  var self          = this;
-  options           = options || {};
-
-  //
-  // Setup basic proxying options
-  //
-  this.https        = options.https;
-  this.forward      = options.forward;
-  this.target       = options.target || {};
-
-  //
-  // Setup additional options for WebSocket proxying. When forcing
-  // the WebSocket handshake to change the `sec-websocket-location`
-  // and `sec-websocket-origin` headers `options.source` **MUST**
-  // be provided or the operation will fail with an `origin mismatch`
-  // by definition.
-  //
-  this.source       = options.source || { host: 'localhost', port: 8000 };
-  this.changeOrigin = options.changeOrigin || false;
-
-  if (options.router) {
-    this.proxyTable = new ProxyTable(options.router, options.silent, options.hostnameOnly);
-    this.proxyTable.on('routes', function (routes) {
-      self.emit('routes', routes);
-    });
-  }
+    events.EventEmitter.call(this);
+
+    var self = this;
+    options = options || {};
+
+    //
+    // Setup basic proxying options
+    //
+    this.https = options.https;
+    this.forward = options.forward;
+    this.target = options.target || {};
+
+    //
+    // Setup additional options for WebSocket proxying. When forcing
+    // the WebSocket handshake to change the `sec-websocket-location`
+    // and `sec-websocket-origin` headers `options.source` **MUST**
+    // be provided or the operation will fail with an `origin mismatch`
+    // by definition.
+    //
+    this.source = options.source || { host: 'localhost', port: 8000 };
+    this.changeOrigin = options.changeOrigin || false;
+
+    if (options.router) {
+        this.proxyTable = new ProxyTable(options.router, options.silent, options.hostnameOnly);
+        this.proxyTable.on('routes', function (routes) {
+            self.emit('routes', routes);
+        });
+    }
 };
 
 // Inherit from events.EventEmitter
@@ -329,35 +340,35 @@ util.inherits(HttpProxy, events.EventEmitter);
 // [on the HttpProxy instance](https://github.com/nodejitsu/node-http-proxy/blob/v0.3.1/lib/node-http-proxy.js#L154).
 //
 HttpProxy.prototype.buffer = function (obj) {
-  var onData, onEnd, events = [];
-
-  obj.on('data', onData = function (data, encoding) {
-    events.push(['data', data, encoding]);
-  });
-
-  obj.on('end', onEnd = function (data, encoding) {
-    events.push(['end', data, encoding]);
-  });
-
-  return {
-    end: function () {
-      obj.removeListener('data', onData);
-      obj.removeListener('end', onEnd);
-    },
-    destroy: function () {
-      this.end();
-      this.resume = function () {
-        console.error("Cannot resume buffer after destroying it.");
-      };
-      onData = onEnd = events = obj = null;
-    },
-    resume: function () {
-      this.end();
-      for (var i = 0, len = events.length; i < len; ++i) {
-        obj.emit.apply(obj, events[i]);
-      }
-    }
-  };
+    var onData, onEnd, events = [];
+
+    obj.on('data', onData = function (data, encoding) {
+        events.push(['data', data, encoding]);
+    });
+
+    obj.on('end', onEnd = function (data, encoding) {
+        events.push(['end', data, encoding]);
+    });
+
+    return {
+        end: function () {
+            obj.removeListener('data', onData);
+            obj.removeListener('end', onEnd);
+        },
+        destroy: function () {
+            this.end();
+            this.resume = function () {
+                console.error("Cannot resume buffer after destroying it.");
+            };
+            onData = onEnd = events = obj = null;
+        },
+        resume: function () {
+            this.end();
+            for (var i = 0, len = events.length; i < len; ++i) {
+                obj.emit.apply(obj, events[i]);
+            }
+        }
+    };
 };
 
 //
@@ -366,9 +377,9 @@ HttpProxy.prototype.buffer = function (obj) {
 // if they exist.
 //
 HttpProxy.prototype.close = function () {
-  if (this.proxyTable) {
-    this.proxyTable.close();
-  }
+    if (this.proxyTable) {
+        this.proxyTable.close();
+    }
 };
 
 //
@@ -384,222 +395,230 @@ HttpProxy.prototype.close = function () {
 //     options.enableXForwarded {boolean} Don't clobber x-forwarded headers to allow layered proxies.
 //
 HttpProxy.prototype.proxyRequest = function (req, res, options) {
-  var self = this, errState = false, location, outgoing, protocol, reverseProxy;
-
-  //
-  // Create an empty options hash if none is passed.
-  // If default options have been passed to the constructor
-  // of this instance, use them by default.
-  //
-  options      = options || {};
-  options.host = options.host || this.target.host;
-  options.port = options.port || this.target.port;
-  options.enableXForwarded =
-    (undefined === options.enableXForwarded ? true : options.enableXForwarded);
-
-  //
-  // Check the proxy table for this instance to see if we need
-  // to get the proxy location for the request supplied. We will
-  // always ignore the proxyTable if an explicit `port` and `host`
-  // arguments are supplied to `proxyRequest`.
-  //
-  if (this.proxyTable && !options.host) {
-    location = this.proxyTable.getProxyLocation(req);
-
-    //
-    // If no location is returned from the ProxyTable instance
-    // then respond with `404` since we do not have a valid proxy target.
-    //
-    if (!location) {
-      try {
-        res.writeHead(404);
-        res.end();
-      } catch (er) {
-        console.error("res.writeHead/res.end error: %s", er.message);
-      }
-      return;
-    }
+    var self = this, errState = false, location, outgoing, protocol, reverseProxy;
 
     //
-    // When using the ProxyTable in conjunction with an HttpProxy instance
-    // only the following arguments are valid:
-    //
-    // * `proxy.proxyRequest(req, res, { host: 'localhost' })`: This will be skipped
-    // * `proxy.proxyRequest(req, res, { buffer: buffer })`: Buffer will get updated appropriately
-    // * `proxy.proxyRequest(req, res)`: Options will be assigned appropriately.
-    //
-    options.port = location.port;
-    options.host = location.host;
-  }
-
-  //
-  // Add common proxy headers to the request so that they can
-  // be availible to the proxy target server:
-  //
-  // * `x-forwarded-for`: IP Address of the original request
-  // * `x-forwarded-proto`: Protocol of the original request
-  // * `x-forwarded-port`: Port of the original request.
-  //
-  if (options.enableXForwarded === true && req.connection && req.connection.socket) {
-    req.headers['x-forwarded-for']   = req.connection.remoteAddress || req.connection.socket.remoteAddress;
-    req.headers['x-forwarded-port']  = req.connection.remotePort || req.connection.socket.remotePort;
-    req.headers['x-forwarded-proto'] = req.connection.pair ? 'https' : 'http';
-  }
-
-  //
-  // Emit the `start` event indicating that we have begun the proxy operation.
-  //
-  this.emit('start', req, res, options);
-
-  //
-  // If forwarding is enabled for this instance, foward proxy the
-  // specified request to the address provided in `this.forward`
-  //
-  if (this.forward) {
-    this.emit('forward', req, res, this.forward);
-    this._forwardRequest(req);
-  }
-
-  //
-  // #### function proxyError (err)
-  // #### @err {Error} Error contacting the proxy target
-  // Short-circuits `res` in the event of any error when
-  // contacting the proxy target at `host` / `port`.
-  //
-  function proxyError(err) {
-    errState = true;
-
-    //
-    // Emit an `error` event, allowing the application to use custom
-    // error handling. The error handler should end the response.
-    //
-    if (self.emit('proxyError', err, req, res)) {
-      return;
-    }
+    // Create an empty options hash if none is passed.
+    // If default options have been passed to the constructor
+    // of this instance, use them by default.
+    //
+    options = options || {};
+    options.host = options.host || this.target.host;
+    options.port = options.port || this.target.port;
+    options.enableXForwarded =
+        (undefined === options.enableXForwarded ? true : options.enableXForwarded);
 
-    res.writeHead(500, { 'Content-Type': 'text/plain' });
-
-    if (req.method !== 'HEAD') {
-      //
-      // This NODE_ENV=production behavior is mimics Express and
-      // Connect.
-      //
-      if (process.env.NODE_ENV === 'production') {
-        res.write('Internal Server Error');
-      }
-      else {
-        res.write('An error has occurred: ' + JSON.stringify(err));
-      }
-    }
+    //
+    // Check the proxy table for this instance to see if we need
+    // to get the proxy location for the request supplied. We will
+    // always ignore the proxyTable if an explicit `port` and `host`
+    // arguments are supplied to `proxyRequest`.
+    //
+    if (this.proxyTable && !options.host) {
+        location = this.proxyTable.getProxyLocation(req);
 
-    try {
-      res.end();
-    } catch (er) {
-      console.error("res.end error: %s", er.message);
+        //
+        // If no location is returned from the ProxyTable instance
+        // then respond with `404` since we do not have a valid proxy target.
+        //
+        if (!location) {
+            try {
+                res.writeHead(404);
+                res.end();
+            } catch (er) {
+                console.error("res.writeHead/res.end error: %s", er.message);
+            }
+            return;
+        }
+
+        //
+        // When using the ProxyTable in conjunction with an HttpProxy instance
+        // only the following arguments are valid:
+        //
+        // * `proxy.proxyRequest(req, res, { host: 'localhost' })`: This will be skipped
+        // * `proxy.proxyRequest(req, res, { buffer: buffer })`: Buffer will get updated appropriately
+        // * `proxy.proxyRequest(req, res)`: Options will be assigned appropriately.
+        //
+        options.port = location.port;
+        options.host = location.host;
     }
-  }
-
-  outgoing = {
-    host: options.host,
-    port: options.port,
-    agent: _getAgent(options.host, options.port, options.https || this.target.https),
-    method: req.method,
-    path: req.url,
-    headers: req.headers
-  };
-
-  protocol = _getProtocol(options.https || this.target.https, outgoing);
-
-  // Open new HTTP request to internal resource with will act as a reverse proxy pass
-  reverseProxy = protocol.request(outgoing, function (response) {
-
-    // Process the `reverseProxy` `response` when it's received.
-    if (response.headers.connection) {
-      if (req.headers.connection) response.headers.connection = req.headers.connection;
-      else response.headers.connection = 'close';
+
+    //
+    // Add common proxy headers to the request so that they can
+    // be availible to the proxy target server:
+    //
+    // * `x-forwarded-for`: IP Address of the original request
+    // * `x-forwarded-proto`: Protocol of the original request
+    // * `x-forwarded-port`: Port of the original request.
+    //
+    if (options.enableXForwarded === true && req.connection && req.connection.socket) {
+        req.headers['x-forwarded-for'] = req.connection.remoteAddress || req.connection.socket.remoteAddress;
+        req.headers['x-forwarded-port'] = req.connection.remotePort || req.connection.socket.remotePort;
+        req.headers['x-forwarded-proto'] = req.connection.pair ? 'https' : 'http';
     }
 
-    // Set the headers of the client response
-    res.writeHead(response.statusCode, response.headers);
-
-    // `response.statusCode === 304`: No 'data' event and no 'end'
-    if (response.statusCode === 304) {
-      try {
-        res.end();
-      } catch (er) {
-        console.error("res.end error: %s", er.message)
-      }
-      return;
+    //
+    // Emit the `start` event indicating that we have begun the proxy operation.
+    //
+    this.emit('start', req, res, options);
+
+    //
+    // If forwarding is enabled for this instance, foward proxy the
+    // specified request to the address provided in `this.forward`
+    //
+    if (this.forward) {
+        this.emit('forward', req, res, this.forward);
+        this._forwardRequest(req);
     }
 
-    // For each data `chunk` received from the `reverseProxy`
-    // `response` write it to the outgoing `res`.
-    // If the res socket has been killed already, then write()
-    // will throw. Nevertheless, try our best to end it nicely.
-    response.on('data', function (chunk) {
-      if (req.method !== 'HEAD' && res.writable) {
+    //
+    // #### function proxyError (err)
+    // #### @err {Error} Error contacting the proxy target
+    // Short-circuits `res` in the event of any error when
+    // contacting the proxy target at `host` / `port`.
+    //
+    function proxyError(err) {
+        errState = true;
+
+        //
+        // Emit an `error` event, allowing the application to use custom
+        // error handling. The error handler should end the response.
+        //
+        if (self.emit('proxyError', err, req, res)) {
+            return;
+        }
+
+        res.writeHead(500, { 'Content-Type': 'text/plain' });
+
+        if (req.method !== 'HEAD') {
+            //
+            // This NODE_ENV=production behavior is mimics Express and
+            // Connect.
+            //
+            if (process.env.NODE_ENV === 'production') {
+                res.write('Internal Server Error');
+            }
+            else {
+                res.write('An error has occurred: ' + JSON.stringify(err));
+            }
+        }
+
         try {
-          res.write(chunk);
-        } catch (er) {
-          console.error("res.write error: %s", er.message);
-          try {
             res.end();
-          } catch (er) {
+        } catch (er) {
             console.error("res.end error: %s", er.message);
-          }
         }
-      }
-    });
+    }
 
-    // When the `reverseProxy` `response` ends, end the
-    // corresponding outgoing `res` unless we have entered
-    // an error state. In which case, assume `res.end()` has
-    // already been called and the 'error' event listener
-    // removed.
-    response.on('end', function () {
-      if (!errState) {
-        reverseProxy.removeListener('error', proxyError);
-        try {
-          res.end();
-        } catch (er) {
-          console.error("res.end error: %s", er.message);
+    outgoing = {
+        host: options.host,
+        port: options.port,
+        agent: _getAgent(options.host, options.port, options.https || this.target.https),
+        method: req.method,
+        path: req.url,
+        headers: req.headers
+    };
+
+    protocol = _getProtocol(options.https || this.target.https, outgoing);
+
+    // Open new HTTP request to internal resource with will act as a reverse proxy pass
+    reverseProxy = protocol.request(outgoing, function(response) {
+        if (typeof options.postFlightMethod == 'function') {
+            options.postFlightMethod(response)
         }
+        handleResponse(response)
+    })
 
-        // Emit the `end` event now that we have completed proxying
-        self.emit('end', req, res);
-      }
-    });
-  });
 
-  // Handle 'error' events from the `reverseProxy`.
-  reverseProxy.once('error', proxyError);
+    function handleResponse(response) {
+        // Process the `reverseProxy` `response` when it's received.
+        if (response.headers.connection) {
+            if (req.headers.connection) response.headers.connection = req.headers.connection;
+            else response.headers.connection = 'close';
+        }
 
-  // For each data `chunk` received from the incoming
-  // `req` write it to the `reverseProxy` request.
-  req.on('data', function (chunk) {
-    if (!errState) {
-      reverseProxy.write(chunk);
-    }
-  });
-
-  //
-  // When the incoming `req` ends, end the corresponding `reverseProxy`
-  // request unless we have entered an error state.
-  //
-  req.on('end', function () {
-    if (!errState) {
-      reverseProxy.end();
+
+        // Set the headers of the client response
+        res.writeHead(response.statusCode, response.headers);
+
+        // `response.statusCode === 304`: No 'data' event and no 'end'
+        if (response.statusCode === 304) {
+            try {
+                res.end();
+            } catch (er) {
+                console.error("res.end error: %s", er.message)
+            }
+            return;
+        }
+
+        // For each data `chunk` received from the `reverseProxy`
+        // `response` write it to the outgoing `res`.
+        // If the res socket has been killed already, then write()
+        // will throw. Nevertheless, try our best to end it nicely.
+        response.on('data', function (chunk) {
+            if (req.method !== 'HEAD' && res.writable) {
+                try {
+                    res.write(chunk);
+                } catch (er) {
+                    console.error("res.write error: %s", er.message);
+                    try {
+                        res.end();
+                    } catch (er) {
+                        console.error("res.end error: %s", er.message);
+                    }
+                }
+            }
+        });
+
+        // When the `reverseProxy` `response` ends, end the
+        // corresponding outgoing `res` unless we have entered
+        // an error state. In which case, assume `res.end()` has
+        // already been called and the 'error' event listener
+        // removed.
+        response.on('end', function () {
+            if (!errState) {
+                reverseProxy.removeListener('error', proxyError);
+                try {
+                    res.end();
+                } catch (er) {
+                    console.error("res.end error: %s", er.message);
+                }
+
+                // Emit the `end` event now that we have completed proxying
+                self.emit('end', req, res);
+            }
+        });
     }
-  });
-
-  // If we have been passed buffered data, resume it.
-  if (options.buffer) {
-    if (!errState) {
-      options.buffer.resume();
-    } else {
-      options.buffer.destroy();
+
+    // Handle 'error' events from the `reverseProxy`.
+    reverseProxy.once('error', proxyError);
+
+    // For each data `chunk` received from the incoming
+    // `req` write it to the `reverseProxy` request.
+    req.on('data', function (chunk) {
+        if (!errState) {
+            reverseProxy.write(chunk);
+        }
+    });
+
+    //
+    // When the incoming `req` ends, end the corresponding `reverseProxy`
+    // request unless we have entered an error state.
+    //
+    req.on('end', function () {
+        if (!errState) {
+            reverseProxy.end();
+        }
+    });
+
+    // If we have been passed buffered data, resume it.
+    if (options.buffer) {
+        if (!errState) {
+            options.buffer.resume();
+        } else {
+            options.buffer.destroy();
+        }
     }
-  }
 };
 
 //
@@ -609,50 +628,51 @@ HttpProxy.prototype.proxyRequest = function (req, res, options) {
 // by `this.forward` ignoring errors and the subsequent response.
 //
 HttpProxy.prototype._forwardRequest = function (req) {
-  var self = this, port, host, outgoing, protocol, forwardProxy;
-
-  port = this.forward.port;
-  host = this.forward.host;
-
-  outgoing = {
-    host: host,
-    port: port,
-    agent: _getAgent(host, port, this.forward.https),
-    method: req.method,
-    path: req.url,
-    headers: req.headers
-  };
-
-  // Force the `connection` header to be 'close' until
-  // node.js core re-implements 'keep-alive'.
-  outgoing.headers['connection'] = 'close';
-
-  protocol = _getProtocol(this.forward.https, outgoing);
-
-  // Open new HTTP request to internal resource with will act as a reverse proxy pass
-  forwardProxy = protocol.request(outgoing, function (response) {
-    //
-    // Ignore the response from the forward proxy since this is a 'fire-and-forget' proxy.
-    // Remark (indexzero): We will eventually emit a 'forward' event here for performance tuning.
-    //
-  });
-
-  // Add a listener for the connection timeout event.
-  //
-  // Remark: Ignoring this error in the event
-  //         forward target doesn't exist.
-  //
-  forwardProxy.once('error', function (err) { });
-
-  // Chunk the client request body as chunks from the proxied request come in
-  req.on('data', function (chunk) {
-    forwardProxy.write(chunk);
-  })
-
-  // At the end of the client request, we are going to stop the proxied request
-  req.on('end', function () {
-    forwardProxy.end();
-  });
+    var self = this, port, host, outgoing, protocol, forwardProxy;
+
+    port = this.forward.port;
+    host = this.forward.host;
+
+    outgoing = {
+        host: host,
+        port: port,
+        agent: _getAgent(host, port, this.forward.https),
+        method: req.method,
+        path: req.url,
+        headers: req.headers
+    };
+
+    // Force the `connection` header to be 'close' until
+    // node.js core re-implements 'keep-alive'.
+    outgoing.headers['connection'] = 'close';
+
+    protocol = _getProtocol(this.forward.https, outgoing);
+
+    // Open new HTTP request to internal resource with will act as a reverse proxy pass
+    forwardProxy = protocol.request(outgoing, function (response) {
+        //
+        // Ignore the response from the forward proxy since this is a 'fire-and-forget' proxy.
+        // Remark (indexzero): We will eventually emit a 'forward' event here for performance tuning.
+        //
+    });
+
+    // Add a listener for the connection timeout event.
+    //
+    // Remark: Ignoring this error in the event
+    //         forward target doesn't exist.
+    //
+    forwardProxy.once('error', function (err) {
+    });
+
+    // Chunk the client request body as chunks from the proxied request come in
+    req.on('data', function (chunk) {
+        forwardProxy.write(chunk);
+    })
+
+    // At the end of the client request, we are going to stop the proxied request
+    req.on('end', function () {
+        forwardProxy.end();
+    });
 };
 
 //
@@ -668,288 +688,290 @@ HttpProxy.prototype._forwardRequest = function (req) {
 //     options.https {Object|boolean} Settings for https.
 //
 HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options) {
-  var self      = this,
-      listeners = {},
-      errState  = false,
-      CRLF      = '\r\n',
-      outgoing;
+    var self = this,
+        listeners = {},
+        errState = false,
+        CRLF = '\r\n',
+        outgoing;
 
-  options      = options || {};
-  options.host = options.host || this.target.host;
-  options.port = options.port || this.target.port;
+    options = options || {};
+    options.host = options.host || this.target.host;
+    options.port = options.port || this.target.port;
 
-  if (this.proxyTable && !options.host) {
-    location = this.proxyTable.getProxyLocation(req);
+    if (this.proxyTable && !options.host) {
+        location = this.proxyTable.getProxyLocation(req);
 
-    if (!location) {
-      return socket.destroy();
-    }
+        if (!location) {
+            return socket.destroy();
+        }
 
-    options.port = location.port;
-    options.host = location.host;
-  }
-
-  //
-  // WebSocket requests must have the `GET` method and
-  // the `upgrade:websocket` header
-  //
-  if (req.method !== 'GET' || req.headers.upgrade.toLowerCase() !== 'websocket') {
-    //
-    // This request is not WebSocket request
-    //
-    return;
-  }
-
-  //
-  // Helper function for setting appropriate socket values:
-  // 1. Turn of all bufferings
-  // 2. For server set KeepAlive
-  // 3. For client set encoding
-  //
-  function _socket(socket, keepAlive) {
-    socket.setTimeout(0);
-    socket.setNoDelay(true);
-    if (keepAlive) {
-      if (socket.setKeepAlive) {
-        socket.setKeepAlive(true, 0);
-      }
-      else if (socket.pair.cleartext.socket.setKeepAlive) {
-        socket.pair.cleartext.socket.setKeepAlive(true, 0);
-      }
-    }
-    else {
-      socket.setEncoding('utf8');
+        options.port = location.port;
+        options.host = location.host;
     }
-  }
-
-  //
-  // On `upgrade` from the Agent socket, listen to
-  // the appropriate events.
-  //
-  function onUpgrade (reverseProxy, proxySocket) {
-    if (!reverseProxy) {
-      proxySocket.end();
-      socket.end();
-      return;
+
+    //
+    // WebSocket requests must have the `GET` method and
+    // the `upgrade:websocket` header
+    //
+    if (req.method !== 'GET' || req.headers.upgrade.toLowerCase() !== 'websocket') {
+        //
+        // This request is not WebSocket request
+        //
+        return;
     }
 
     //
-    // Any incoming data on this WebSocket to the proxy target
-    // will be written to the `reverseProxy` socket.
+    // Helper function for setting appropriate socket values:
+    // 1. Turn of all bufferings
+    // 2. For server set KeepAlive
+    // 3. For client set encoding
     //
-    proxySocket.on('data', listeners.onIncoming = function (data) {
-      if (reverseProxy.incoming.socket.writable) {
-        try {
-          self.emit('websocket:outgoing', req, socket, head, data);
-          reverseProxy.incoming.socket.write(data);
+    function _socket(socket, keepAlive) {
+        socket.setTimeout(0);
+        socket.setNoDelay(true);
+        if (keepAlive) {
+            if (socket.setKeepAlive) {
+                socket.setKeepAlive(true, 0);
+            }
+            else if (socket.pair.cleartext.socket.setKeepAlive) {
+                socket.pair.cleartext.socket.setKeepAlive(true, 0);
+            }
         }
-        catch (e) {
-          detach();
-          reverseProxy.incoming.socket.end();
-          proxySocket.end();
+        else {
+            socket.setEncoding('utf8');
         }
-      }
-    });
+    }
 
     //
-    // Any outgoing data on this Websocket from the proxy target
-    // will be written to the `proxySocket` socket.
+    // On `upgrade` from the Agent socket, listen to
+    // the appropriate events.
     //
-    reverseProxy.incoming.socket.on('data', listeners.onOutgoing = function(data) {
-      try {
-        self.emit('websocket:incoming', reverseProxy, reverseProxy.incoming, head, data);
-        proxySocket.write(data);
-      }
-      catch (e) {
-        detach();
-        proxySocket.end();
-        socket.end();
-      }
-    });
+    function onUpgrade(reverseProxy, proxySocket) {
+        if (!reverseProxy) {
+            proxySocket.end();
+            socket.end();
+            return;
+        }
+
+        //
+        // Any incoming data on this WebSocket to the proxy target
+        // will be written to the `reverseProxy` socket.
+        //
+        proxySocket.on('data', listeners.onIncoming = function (data) {
+            if (reverseProxy.incoming.socket.writable) {
+                try {
+                    self.emit('websocket:outgoing', req, socket, head, data);
+                    reverseProxy.incoming.socket.write(data);
+                }
+                catch (e) {
+                    detach();
+                    reverseProxy.incoming.socket.end();
+                    proxySocket.end();
+                }
+            }
+        });
+
+        //
+        // Any outgoing data on this Websocket from the proxy target
+        // will be written to the `proxySocket` socket.
+        //
+        reverseProxy.incoming.socket.on('data', listeners.onOutgoing = function(data) {
+            try {
+                self.emit('websocket:incoming', reverseProxy, reverseProxy.incoming, head, data);
+                proxySocket.write(data);
+            }
+            catch (e) {
+                detach();
+                proxySocket.end();
+                socket.end();
+            }
+        });
+
+        //
+        // Helper function to detach all event listeners
+        // from `reverseProxy` and `proxySocket`.
+        //
+        function detach() {
+            proxySocket.removeListener('end', listeners.onIncomingClose);
+            proxySocket.removeListener('data', listeners.onIncoming);
+            reverseProxy.incoming.socket.removeListener('end', listeners.onOutgoingClose);
+            reverseProxy.incoming.socket.removeListener('data', listeners.onOutgoing);
+        }
+
+        //
+        // If the incoming `proxySocket` socket closes, then
+        // detach all event listeners.
+        //
+        proxySocket.on('end', listeners.onIncomingClose = function() {
+            reverseProxy.incoming.socket.end();
+            detach();
+
+            // Emit the `end` event now that we have completed proxying
+            self.emit('websocket:end', req, socket, head);
+        });
+
+        //
+        // If the `reverseProxy` socket closes, then detach all
+        // event listeners.
+        //
+        reverseProxy.incoming.socket.on('end', listeners.onOutgoingClose = function() {
+            proxySocket.end();
+            detach();
+        });
+    }
+
+    ;
+
+    // Setup the incoming client socket.
+    _socket(socket);
+
+    function getPort(port) {
+        port = port || 80;
+        return port - 80 === 0 ? '' : ':' + port
+    }
 
     //
-    // Helper function to detach all event listeners
-    // from `reverseProxy` and `proxySocket`.
+    // Get the protocol, and host for this request and create an instance
+    // of `http.Agent` or `https.Agent` from the pool managed by `node-http-proxy`.
     //
-    function detach() {
-      proxySocket.removeListener('end', listeners.onIncomingClose);
-      proxySocket.removeListener('data', listeners.onIncoming);
-      reverseProxy.incoming.socket.removeListener('end', listeners.onOutgoingClose);
-      reverseProxy.incoming.socket.removeListener('data', listeners.onOutgoing);
+    var protocolName = options.https || this.target.https ? 'https' : 'http',
+        portUri = getPort(this.source.port),
+        remoteHost = options.host + portUri,
+        agent = _getAgent(options.host, options.port, options.https || this.target.https);
+
+    // Change headers (if requested).
+    if (this.changeOrigin) {
+        req.headers.host = remoteHost;
+        req.headers.origin = protocolName + '://' + remoteHost;
     }
 
     //
-    // If the incoming `proxySocket` socket closes, then
-    // detach all event listeners.
+    // Make the outgoing WebSocket request
     //
-    proxySocket.on('end', listeners.onIncomingClose = function() {
-      reverseProxy.incoming.socket.end();
-      detach();
+    outgoing = {
+        host: options.host,
+        port: options.port,
+        method: 'GET',
+        path: req.url,
+        headers: req.headers,
+    };
 
-      // Emit the `end` event now that we have completed proxying
-      self.emit('websocket:end', req, socket, head);
-    });
+    var reverseProxy = agent.appendMessage(outgoing);
 
     //
-    // If the `reverseProxy` socket closes, then detach all
-    // event listeners.
+    // On any errors from the `reverseProxy` emit the
+    // `webSocketProxyError` and close the appropriate
+    // connections.
     //
-    reverseProxy.incoming.socket.on('end', listeners.onOutgoingClose = function() {
-      proxySocket.end();
-      detach();
-    });
-  };
-
-  // Setup the incoming client socket.
-  _socket(socket);
-
-  function getPort (port) {
-    port = port || 80;
-    return port - 80 === 0 ? '' : ':' + port
-  }
-
-  //
-  // Get the protocol, and host for this request and create an instance
-  // of `http.Agent` or `https.Agent` from the pool managed by `node-http-proxy`.
-  //
-  var protocolName = options.https || this.target.https ? 'https' : 'http',
-      portUri      = getPort(this.source.port),
-      remoteHost   = options.host + portUri,
-      agent        = _getAgent(options.host, options.port, options.https || this.target.https);
-
-  // Change headers (if requested).
-  if (this.changeOrigin) {
-    req.headers.host   = remoteHost;
-    req.headers.origin = protocolName + '://' + remoteHost;
-  }
-
-  //
-  // Make the outgoing WebSocket request
-  //
-  outgoing = {
-    host: options.host,
-    port: options.port,
-    method: 'GET',
-    path: req.url,
-    headers: req.headers,
-  };
-  
-  var reverseProxy = agent.appendMessage(outgoing);
-
-  //
-  // On any errors from the `reverseProxy` emit the
-  // `webSocketProxyError` and close the appropriate
-  // connections.
-  //
-  function proxyError (err) {
-    reverseProxy.end();
-    if (self.emit('webSocketProxyError', req, socket, head)) {
-      return;
+    function proxyError(err) {
+        reverseProxy.end();
+        if (self.emit('webSocketProxyError', req, socket, head)) {
+            return;
+        }
+        socket.end();
     }
-    socket.end();
-  }
-
-  //
-  // Here we set the incoming `req`, `socket` and `head` data to the outgoing
-  // request so that we can reuse this data later on in the closure scope
-  // available to the `upgrade` event. This bookkeeping is not tracked anywhere
-  // in nodejs core and is **very** specific to proxying WebSockets.
-  //
-  reverseProxy.agent = agent;
-  reverseProxy.incoming = {
-    request: req,
-    socket: socket,
-    head: head
-  };
-
-  //
-  // If the agent for this particular `host` and `port` combination
-  // is not already listening for the `upgrade` event, then do so once.
-  // This will force us not to disconnect.
-  //
-  // In addition, it's important to note the closure scope here. Since
-  // there is no mapping of the
-  //
-  if (!agent._events || agent._events['upgrade'].length === 0) {
-    agent.on('upgrade', function (_, remoteSocket, head) {
-      //
-      // Prepare the socket for the reverseProxy request and begin to
-      // stream data between the two sockets. Here it is important to
-      // note that `remoteSocket._httpMessage === reverseProxy`.
-      //
-      _socket(remoteSocket, true);
-      onUpgrade(remoteSocket._httpMessage, remoteSocket);
-    });
-  }
-
-  //
-  // If the reverseProxy connection has an underlying socket,
-  // then execute the WebSocket handshake.
-  //
-  if (typeof reverseProxy.socket !== 'undefined') {
-    reverseProxy.socket.on('data', function handshake (data) {
-      //
-      // Ok, kind of harmfull part of code. Socket.IO sends a hash
-      // at the end of handshake if protocol === 76, but we need
-      // to replace 'host' and 'origin' in response so we split
-      // data to printable data and to non-printable. (Non-printable
-      // will come after double-CRLF).
-      //
-      var sdata = data.toString();
-
-      // Get the Printable data
-      sdata = sdata.substr(0, sdata.search(CRLF + CRLF));
-
-      // Get the Non-Printable data
-      data = data.slice(Buffer.byteLength(sdata), data.length);
-
-      if (self.https && !self.target.https) {
-        //
-        // If the proxy server is running HTTPS but the client is running
-        // HTTP then replace `ws` with `wss` in the data sent back to the client.
-        //
-        sdata = sdata.replace('ws:', 'wss:');
-      }
 
-      try {
-        //
-        // Write the printable and non-printable data to the socket
-        // from the original incoming request.
-        //
-        self.emit('websocket:handshake', req, socket, head, sdata, data);
-        socket.write(sdata);
-        socket.write(data);
-      }
-      catch (ex) {
-        proxyError(ex)
-      }
-
-      // Catch socket errors
-      socket.on('error', proxyError);
-
-      // Remove data listener now that the 'handshake' is complete
-      reverseProxy.socket.removeListener('data', handshake);
-    });
-  }
+    //
+    // Here we set the incoming `req`, `socket` and `head` data to the outgoing
+    // request so that we can reuse this data later on in the closure scope
+    // available to the `upgrade` event. This bookkeeping is not tracked anywhere
+    // in nodejs core and is **very** specific to proxying WebSockets.
+    //
+    reverseProxy.agent = agent;
+    reverseProxy.incoming = {
+        request: req,
+        socket: socket,
+        head: head
+    };
 
-  reverseProxy.on('error', proxyError);
+    //
+    // If the agent for this particular `host` and `port` combination
+    // is not already listening for the `upgrade` event, then do so once.
+    // This will force us not to disconnect.
+    //
+    // In addition, it's important to note the closure scope here. Since
+    // there is no mapping of the
+    //
+    if (!agent._events || agent._events['upgrade'].length === 0) {
+        agent.on('upgrade', function (_, remoteSocket, head) {
+            //
+            // Prepare the socket for the reverseProxy request and begin to
+            // stream data between the two sockets. Here it is important to
+            // note that `remoteSocket._httpMessage === reverseProxy`.
+            //
+            _socket(remoteSocket, true);
+            onUpgrade(remoteSocket._httpMessage, remoteSocket);
+        });
+    }
 
-  try {
     //
-    // Attempt to write the upgrade-head to the reverseProxy request.
+    // If the reverseProxy connection has an underlying socket,
+    // then execute the WebSocket handshake.
     //
-    reverseProxy.write(head);
-  }
-  catch (ex) {
-    proxyError(ex);
-  }
+    if (typeof reverseProxy.socket !== 'undefined') {
+        reverseProxy.socket.on('data', function handshake(data) {
+            //
+            // Ok, kind of harmfull part of code. Socket.IO sends a hash
+            // at the end of handshake if protocol === 76, but we need
+            // to replace 'host' and 'origin' in response so we split
+            // data to printable data and to non-printable. (Non-printable
+            // will come after double-CRLF).
+            //
+            var sdata = data.toString();
+
+            // Get the Printable data
+            sdata = sdata.substr(0, sdata.search(CRLF + CRLF));
+
+            // Get the Non-Printable data
+            data = data.slice(Buffer.byteLength(sdata), data.length);
+
+            if (self.https && !self.target.https) {
+                //
+                // If the proxy server is running HTTPS but the client is running
+                // HTTP then replace `ws` with `wss` in the data sent back to the client.
+                //
+                sdata = sdata.replace('ws:', 'wss:');
+            }
+
+            try {
+                //
+                // Write the printable and non-printable data to the socket
+                // from the original incoming request.
+                //
+                self.emit('websocket:handshake', req, socket, head, sdata, data);
+                socket.write(sdata);
+                socket.write(data);
+            }
+            catch (ex) {
+                proxyError(ex)
+            }
+
+            // Catch socket errors
+            socket.on('error', proxyError);
+
+            // Remove data listener now that the 'handshake' is complete
+            reverseProxy.socket.removeListener('data', handshake);
+        });
+    }
+
+    reverseProxy.on('error', proxyError);
+
+    try {
+        //
+        // Attempt to write the upgrade-head to the reverseProxy request.
+        //
+        reverseProxy.write(head);
+    }
+    catch (ex) {
+        proxyError(ex);
+    }
 
-  // If we have been passed buffered data, resume it.
-  if (options.buffer) {
-    if (!errState) {
-      options.buffer.resume();
-    } else {
-      options.buffer.destroy();
+    // If we have been passed buffered data, resume it.
+    if (options.buffer) {
+        if (!errState) {
+            options.buffer.resume();
+        } else {
+            options.buffer.destroy();
+        }
     }
-  }
 };