Switch to new repository
diff --git a/node_modules/http-proxy/lib/http-proxy.js b/node_modules/http-proxy/lib/http-proxy.js
new file mode 100644
index 0000000..7dab7a4
--- /dev/null
+++ b/node_modules/http-proxy/lib/http-proxy.js
@@ -0,0 +1,66 @@
+ // Use explicit /index.js to help browserify negociation in require '/lib/http-proxy' (!)
+var ProxyServer = require('./http-proxy/index.js').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
+ */
+
+
+function createProxyServer(options) {
+  /*
+   *  `options` is needed and it must have the following layout:
+   *
+   *  {
+   *    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>
+   *    ssl    : <object to be passed to https.createServer()>
+   *    ws     : <true/false, if you want to proxy websockets>
+   *    xfwd   : <true/false, adds x-forward headers>
+   *    secure : <true/false, verify SSL certificate>
+   *    toProxy: <true/false, explicitly specify if we are proxying to another proxy>
+   *    prependPath: <true/false, Default: true - specify whether you want to prepend the target's path to the proxy path>
+   *    ignorePath: <true/false, Default: false - specify whether you want to ignore the proxy path of the incoming request>
+   *    localAddress : <Local interface string to bind for outgoing connections>
+   *    changeOrigin: <true/false, Default: false - changes the origin of the host header to the target URL>
+   *    preserveHeaderKeyCase: <true/false, Default: false - specify whether you want to keep letter case of response header key >
+   *    auth   : Basic authentication i.e. 'user:password' to compute an Authorization header.
+   *    hostRewrite: rewrites the location hostname on (301/302/307/308) redirects, Default: null.
+   *    autoRewrite: rewrites the location host/port on (301/302/307/308) redirects based on requested host/port. Default: false.
+   *    protocolRewrite: rewrites the location protocol on (301/302/307/308) redirects to 'http' or 'https'. Default: null.
+   *  }
+   *
+   *  NOTE: `options.ws` and `options.ssl` are optional.
+   *    `options.target and `options.forward` cannot be
+   *    both missing
+   *  }
+   */
+
+  return new ProxyServer(options);
+}
+
+
+ProxyServer.createProxyServer = createProxyServer;
+ProxyServer.createServer      = createProxyServer;
+ProxyServer.createProxy       = createProxyServer;
+
+
+
+
+/**
+ * Export the proxy "Server" as the main export.
+ */
+module.exports = ProxyServer;
+
diff --git a/node_modules/http-proxy/lib/http-proxy/common.js b/node_modules/http-proxy/lib/http-proxy/common.js
new file mode 100644
index 0000000..6513e81
--- /dev/null
+++ b/node_modules/http-proxy/lib/http-proxy/common.js
@@ -0,0 +1,248 @@
+var common   = exports,
+    url      = require('url'),
+    extend   = require('util')._extend,
+    required = require('requires-port');
+
+var upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i,
+    isSSL = /^https|wss/;
+
+/**
+ * Simple Regex for testing if protocol is https
+ */
+common.isSSL = isSSL;
+/**
+ * Copies the right headers from `options` and `req` to
+ * `outgoing` which is then used to fire the proxied
+ * request.
+ *
+ * Examples:
+ *
+ *    common.setupOutgoing(outgoing, options, req)
+ *    // => { host: ..., hostname: ...}
+ *
+ * @param {Object} Outgoing Base object to be filled with required properties
+ * @param {Object} Options Config object passed to the proxy
+ * @param {ClientRequest} Req Request Object
+ * @param {String} Forward String to select forward or target
+ * 
+ * @return {Object} Outgoing Object with all required properties set
+ *
+ * @api private
+ */
+
+common.setupOutgoing = function(outgoing, options, req, forward) {
+  outgoing.port = options[forward || 'target'].port ||
+                  (isSSL.test(options[forward || 'target'].protocol) ? 443 : 80);
+
+  ['host', 'hostname', 'socketPath', 'pfx', 'key',
+    'passphrase', 'cert', 'ca', 'ciphers', 'secureProtocol'].forEach(
+    function(e) { outgoing[e] = options[forward || 'target'][e]; }
+  );
+
+  outgoing.method = options.method || req.method;
+  outgoing.headers = extend({}, req.headers);
+
+  if (options.headers){
+    extend(outgoing.headers, options.headers);
+  }
+
+  if (options.auth) {
+    outgoing.auth = options.auth;
+  }
+  
+  if (options.ca) {
+      outgoing.ca = options.ca;
+  }
+
+  if (isSSL.test(options[forward || 'target'].protocol)) {
+    outgoing.rejectUnauthorized = (typeof options.secure === "undefined") ? true : options.secure;
+  }
+
+
+  outgoing.agent = options.agent || false;
+  outgoing.localAddress = options.localAddress;
+
+  //
+  // Remark: If we are false and not upgrading, set the connection: close. This is the right thing to do
+  // as node core doesn't handle this COMPLETELY properly yet.
+  //
+  if (!outgoing.agent) {
+    outgoing.headers = outgoing.headers || {};
+    if (typeof outgoing.headers.connection !== 'string'
+        || !upgradeHeader.test(outgoing.headers.connection)
+       ) { outgoing.headers.connection = 'close'; }
+  }
+
+
+  // the final path is target path + relative path requested by user:
+  var target = options[forward || 'target'];
+  var targetPath = target && options.prependPath !== false
+    ? (target.path || '')
+    : '';
+
+  //
+  // Remark: Can we somehow not use url.parse as a perf optimization?
+  //
+  var outgoingPath = !options.toProxy
+    ? (url.parse(req.url).path || '')
+    : req.url;
+
+  //
+  // Remark: ignorePath will just straight up ignore whatever the request's
+  // path is. This can be labeled as FOOT-GUN material if you do not know what
+  // you are doing and are using conflicting options.
+  //
+  outgoingPath = !options.ignorePath ? outgoingPath : '';
+
+  outgoing.path = common.urlJoin(targetPath, outgoingPath);
+
+  if (options.changeOrigin) {
+    outgoing.headers.host =
+      required(outgoing.port, options[forward || 'target'].protocol) && !hasPort(outgoing.host)
+        ? outgoing.host + ':' + outgoing.port
+        : outgoing.host;
+  }
+  return outgoing;
+};
+
+/**
+ * Set the proper configuration for sockets,
+ * set no delay and set keep alive, also set
+ * the timeout to 0.
+ *
+ * Examples:
+ *
+ *    common.setupSocket(socket)
+ *    // => Socket
+ *
+ * @param {Socket} Socket instance to setup
+ * 
+ * @return {Socket} Return the configured socket.
+ *
+ * @api private
+ */
+
+common.setupSocket = function(socket) {
+  socket.setTimeout(0);
+  socket.setNoDelay(true);
+
+  socket.setKeepAlive(true, 0);
+
+  return socket;
+};
+
+/**
+ * Get the port number from the host. Or guess it based on the connection type.
+ *
+ * @param {Request} req Incoming HTTP request.
+ *
+ * @return {String} The port number.
+ *
+ * @api private
+ */
+common.getPort = function(req) {
+  var res = req.headers.host ? req.headers.host.match(/:(\d+)/) : '';
+
+  return res ?
+    res[1] :
+    common.hasEncryptedConnection(req) ? '443' : '80';
+};
+
+/**
+ * Check if the request has an encrypted connection.
+ *
+ * @param {Request} req Incoming HTTP request.
+ *
+ * @return {Boolean} Whether the connection is encrypted or not.
+ *
+ * @api private
+ */
+common.hasEncryptedConnection = function(req) {
+  return Boolean(req.connection.encrypted || req.connection.pair);
+};
+
+/**
+ * OS-agnostic join (doesn't break on URLs like path.join does on Windows)>
+ *
+ * @return {String} The generated path.
+ *
+ * @api private
+ */
+
+common.urlJoin = function() {
+    //
+    // We do not want to mess with the query string. All we want to touch is the path.
+    //
+  var args = Array.prototype.slice.call(arguments),
+      lastIndex = args.length - 1,
+      last = args[lastIndex],
+      lastSegs = last.split('?'),
+      retSegs;
+
+  args[lastIndex] = lastSegs.shift();
+
+  //
+  // Join all strings, but remove empty strings so we don't get extra slashes from
+  // joining e.g. ['', 'am']
+  //
+  retSegs = [
+    args.filter(Boolean).join('/')
+        .replace(/\/+/g, '/')
+        .replace('http:/', 'http://')
+        .replace('https:/', 'https://')
+  ];
+
+  // Only join the query string if it exists so we don't have trailing a '?'
+  // on every request
+
+  // Handle case where there could be multiple ? in the URL.
+  retSegs.push.apply(retSegs, lastSegs);
+
+  return retSegs.join('?')
+};
+
+/**
+ * Rewrites or removes the domain of a cookie header
+ *
+ * @param {String|Array} Header
+ * @param {Object} Config, mapping of domain to rewritten domain.
+ *                 '*' key to match any domain, null value to remove the domain.
+ *
+ * @api private
+ */
+common.rewriteCookieProperty = function rewriteCookieProperty(header, config, property) {
+  if (Array.isArray(header)) {
+    return header.map(function (headerElement) {
+      return rewriteCookieProperty(headerElement, config, property);
+    });
+  }
+  return header.replace(new RegExp("(;\\s*" + property + "=)([^;]+)", 'i'), function(match, prefix, previousValue) {
+    var newValue;
+    if (previousValue in config) {
+      newValue = config[previousValue];
+    } else if ('*' in config) {
+      newValue = config['*'];
+    } else {
+      //no match, return previous value
+      return match;
+    }
+    if (newValue) {
+      //replace value
+      return prefix + newValue;
+    } else {
+      //remove value
+      return '';
+    }
+  });
+};
+
+/**
+ * Check the host and see if it potentially has a port in it (keep it simple)
+ *
+ * @returns {Boolean} Whether we have one or not
+ *
+ * @api private
+ */
+function hasPort(host) {
+  return !!~host.indexOf(':');
+};
diff --git a/node_modules/http-proxy/lib/http-proxy/index.js b/node_modules/http-proxy/lib/http-proxy/index.js
new file mode 100644
index 0000000..977a4b3
--- /dev/null
+++ b/node_modules/http-proxy/lib/http-proxy/index.js
@@ -0,0 +1,185 @@
+var httpProxy = module.exports,
+    extend    = require('util')._extend,
+    parse_url = require('url').parse,
+    EE3       = require('eventemitter3'),
+    http      = require('http'),
+    https     = require('https'),
+    web       = require('./passes/web-incoming'),
+    ws        = require('./passes/ws-incoming');
+
+httpProxy.Server = ProxyServer;
+
+/**
+ * Returns a function that creates the loader for
+ * either `ws` or `web`'s  passes.
+ *
+ * Examples:
+ *
+ *    httpProxy.createRightProxy('ws')
+ *    // => [Function]
+ *
+ * @param {String} Type Either 'ws' or 'web'
+ * 
+ * @return {Function} Loader Function that when called returns an iterator for the right passes
+ *
+ * @api private
+ */
+
+function createRightProxy(type) {
+
+  return function(options) {
+    return function(req, res /*, [head], [opts] */) {
+      var passes = (type === 'ws') ? this.wsPasses : this.webPasses,
+          args = [].slice.call(arguments),
+          cntr = args.length - 1,
+          head, cbl;
+
+      /* optional args parse begin */
+      if(typeof args[cntr] === 'function') {
+        cbl = args[cntr];
+
+        cntr--;
+      }
+
+      var requestOptions = options;
+      if(
+        !(args[cntr] instanceof Buffer) &&
+        args[cntr] !== res
+      ) {
+        //Copy global options
+        requestOptions = extend({}, options);
+        //Overwrite with request options
+        extend(requestOptions, args[cntr]);
+
+        cntr--;
+      }
+
+      if(args[cntr] instanceof Buffer) {
+        head = args[cntr];
+      }
+
+      /* optional args parse end */
+
+      ['target', 'forward'].forEach(function(e) {
+        if (typeof requestOptions[e] === 'string')
+          requestOptions[e] = parse_url(requestOptions[e]);
+      });
+
+      if (!requestOptions.target && !requestOptions.forward) {
+        return this.emit('error', new Error('Must provide a proper URL as target'));
+      }
+
+      for(var i=0; i < passes.length; i++) {
+        /**
+         * Call of passes functions
+         * pass(req, res, options, head)
+         *
+         * In WebSockets case the `res` variable
+         * refer to the connection socket
+         * pass(req, socket, options, head)
+         */
+        if(passes[i](req, res, requestOptions, head, this, cbl)) { // passes can return a truthy value to halt the loop
+          break;
+        }
+      }
+    };
+  };
+}
+httpProxy.createRightProxy = createRightProxy;
+
+function ProxyServer(options) {
+  EE3.call(this);
+
+  options = options || {};
+  options.prependPath = options.prependPath === false ? false : true;
+
+  this.web = this.proxyRequest           = createRightProxy('web')(options);
+  this.ws  = this.proxyWebsocketRequest  = createRightProxy('ws')(options);
+  this.options = options;
+
+  this.webPasses = Object.keys(web).map(function(pass) {
+    return web[pass];
+  });
+
+  this.wsPasses = Object.keys(ws).map(function(pass) {
+    return ws[pass];
+  });
+
+  this.on('error', this.onError, this);
+
+}
+
+require('util').inherits(ProxyServer, EE3);
+
+ProxyServer.prototype.onError = function (err) {
+  //
+  // Remark: Replicate node core behavior using EE3
+  // so we force people to handle their own errors
+  //
+  if(this.listeners('error').length === 1) {
+    throw err;
+  }
+};
+
+ProxyServer.prototype.listen = function(port, hostname) {
+  var self    = this,
+      closure = function(req, res) { self.web(req, res); };
+
+  this._server  = this.options.ssl ?
+    https.createServer(this.options.ssl, closure) :
+    http.createServer(closure);
+
+  if(this.options.ws) {
+    this._server.on('upgrade', function(req, socket, head) { self.ws(req, socket, head); });
+  }
+
+  this._server.listen(port, hostname);
+
+  return this;
+};
+
+ProxyServer.prototype.close = function(callback) {
+  var self = this;
+  if (this._server) {
+    this._server.close(done);
+  }
+
+  // Wrap callback to nullify server after all open connections are closed.
+  function done() {
+    self._server = null;
+    if (callback) {
+      callback.apply(null, arguments);
+    }
+  };
+};
+
+ProxyServer.prototype.before = function(type, passName, callback) {
+  if (type !== 'ws' && type !== 'web') {
+    throw new Error('type must be `web` or `ws`');
+  }
+  var passes = (type === 'ws') ? this.wsPasses : this.webPasses,
+      i = false;
+
+  passes.forEach(function(v, idx) {
+    if(v.name === passName) i = idx;
+  })
+
+  if(i === false) throw new Error('No such pass');
+
+  passes.splice(i, 0, callback);
+};
+ProxyServer.prototype.after = function(type, passName, callback) {
+  if (type !== 'ws' && type !== 'web') {
+    throw new Error('type must be `web` or `ws`');
+  }
+  var passes = (type === 'ws') ? this.wsPasses : this.webPasses,
+      i = false;
+
+  passes.forEach(function(v, idx) {
+    if(v.name === passName) i = idx;
+  })
+
+  if(i === false) throw new Error('No such pass');
+
+  passes.splice(i++, 0, callback);
+};
diff --git a/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js b/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js
new file mode 100644
index 0000000..995a0db
--- /dev/null
+++ b/node_modules/http-proxy/lib/http-proxy/passes/web-incoming.js
@@ -0,0 +1,192 @@
+var httpNative   = require('http'),
+    httpsNative  = require('https'),
+    web_o  = require('./web-outgoing'),
+    common = require('../common'),
+    followRedirects = require('follow-redirects');
+
+web_o = Object.keys(web_o).map(function(pass) {
+  return web_o[pass];
+});
+
+var nativeAgents = { http: httpNative, https: httpsNative };
+
+/*!
+ * Array of passes.
+ *
+ * A `pass` is just a function that is executed on `req, res, options`
+ * so that you can easily add new checks while still keeping the base
+ * flexible.
+ */
+
+
+module.exports = {
+
+  /**
+   * Sets `content-length` to '0' if request is of DELETE type.
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {IncomingMessage} Res Response object
+   * @param {Object} Options Config object passed to the proxy
+   *
+   * @api private
+   */
+
+  deleteLength: function deleteLength(req, res, options) {
+    if((req.method === 'DELETE' || req.method === 'OPTIONS')
+       && !req.headers['content-length']) {
+      req.headers['content-length'] = '0';
+      delete req.headers['transfer-encoding'];
+    }
+  },
+
+  /**
+   * Sets timeout in request socket if it was specified in options.
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {IncomingMessage} Res Response object
+   * @param {Object} Options Config object passed to the proxy
+   *
+   * @api private
+   */
+
+  timeout: function timeout(req, res, options) {
+    if(options.timeout) {
+      req.socket.setTimeout(options.timeout);
+    }
+  },
+
+  /**
+   * Sets `x-forwarded-*` headers if specified in config.
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {IncomingMessage} Res Response object
+   * @param {Object} Options Config object passed to the proxy
+   *
+   * @api private
+   */
+
+  XHeaders: function XHeaders(req, res, options) {
+    if(!options.xfwd) return;
+
+    var encrypted = req.isSpdy || common.hasEncryptedConnection(req);
+    var values = {
+      for  : req.connection.remoteAddress || req.socket.remoteAddress,
+      port : common.getPort(req),
+      proto: encrypted ? 'https' : 'http'
+    };
+
+    ['for', 'port', 'proto'].forEach(function(header) {
+      req.headers['x-forwarded-' + header] =
+        (req.headers['x-forwarded-' + header] || '') +
+        (req.headers['x-forwarded-' + header] ? ',' : '') +
+        values[header];
+    });
+
+    req.headers['x-forwarded-host'] = req.headers['host'] || '';
+  },
+
+  /**
+   * Does the actual proxying. If `forward` is enabled fires up
+   * a ForwardStream, same happens for ProxyStream. The request
+   * just dies otherwise.
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {IncomingMessage} Res Response object
+   * @param {Object} Options Config object passed to the proxy
+   *
+   * @api private
+   */
+
+  stream: function stream(req, res, options, _, server, clb) {
+
+    // And we begin!
+    server.emit('start', req, res, options.target || options.forward);
+
+    var agents = options.followRedirects ? followRedirects : nativeAgents;
+    var http = agents.http;
+    var https = agents.https;
+
+    if(options.forward) {
+      // If forward enable, so just pipe the request
+      var forwardReq = (options.forward.protocol === 'https:' ? https : http).request(
+        common.setupOutgoing(options.ssl || {}, options, req, 'forward')
+      );
+
+      // error handler (e.g. ECONNRESET, ECONNREFUSED)
+      // Handle errors on incoming request as well as it makes sense to
+      var forwardError = createErrorHandler(forwardReq, options.forward);
+      req.on('error', forwardError);
+      forwardReq.on('error', forwardError);
+
+      (options.buffer || req).pipe(forwardReq);
+      if(!options.target) { return res.end(); }
+    }
+
+    // Request initalization
+    var proxyReq = (options.target.protocol === 'https:' ? https : http).request(
+      common.setupOutgoing(options.ssl || {}, options, req)
+    );
+
+    // Enable developers to modify the proxyReq before headers are sent
+    proxyReq.on('socket', function(socket) {
+      if(server) { server.emit('proxyReq', proxyReq, req, res, options); }
+    });
+
+    // allow outgoing socket to timeout so that we could
+    // show an error page at the initial request
+    if(options.proxyTimeout) {
+      proxyReq.setTimeout(options.proxyTimeout, function() {
+         proxyReq.abort();
+      });
+    }
+
+    // Ensure we abort proxy if request is aborted
+    req.on('aborted', function () {
+      proxyReq.abort();
+    });
+
+    // handle errors in proxy and incoming request, just like for forward proxy
+    var proxyError = createErrorHandler(proxyReq, options.target);
+    req.on('error', proxyError);
+    proxyReq.on('error', proxyError);
+
+    function createErrorHandler(proxyReq, url) {
+      return function proxyError(err) {
+        if (req.socket.destroyed && err.code === 'ECONNRESET') {
+          server.emit('econnreset', err, req, res, url);
+          return proxyReq.abort();
+        }
+
+        if (clb) {
+          clb(err, req, res, url);
+        } else {
+          server.emit('error', err, req, res, url);
+        }
+      }
+    }
+
+    (options.buffer || req).pipe(proxyReq);
+
+    proxyReq.on('response', function(proxyRes) {
+      if(server) { server.emit('proxyRes', proxyRes, req, res); }
+
+      if(!res.headersSent && !options.selfHandleResponse) {
+        for(var i=0; i < web_o.length; i++) {
+          if(web_o[i](req, res, proxyRes, options)) { break; }
+        }
+      }
+
+      if (!res.finished) {
+        // Allow us to listen when the proxy has completed
+        proxyRes.on('end', function () {
+          if (server) server.emit('end', req, res, proxyRes);
+        });
+        // We pipe to the response unless its expected to be handled by the user
+        if (!options.selfHandleResponse) proxyRes.pipe(res);
+      } else {
+        if (server) server.emit('end', req, res, proxyRes);
+      }
+    });
+  }
+
+};
diff --git a/node_modules/http-proxy/lib/http-proxy/passes/web-outgoing.js b/node_modules/http-proxy/lib/http-proxy/passes/web-outgoing.js
new file mode 100644
index 0000000..46352f6
--- /dev/null
+++ b/node_modules/http-proxy/lib/http-proxy/passes/web-outgoing.js
@@ -0,0 +1,147 @@
+var url    = require('url'),
+    common = require('../common');
+
+
+var redirectRegex = /^201|30(1|2|7|8)$/;
+
+/*!
+ * Array of passes.
+ *
+ * A `pass` is just a function that is executed on `req, res, options`
+ * so that you can easily add new checks while still keeping the base
+ * flexible.
+ */
+
+module.exports = { // <--
+
+  /**
+   * If is a HTTP 1.0 request, remove chunk headers
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {IncomingMessage} Res Response object
+   * @param {proxyResponse} Res Response object from the proxy request
+   *
+   * @api private
+   */
+  removeChunked: function removeChunked(req, res, proxyRes) {
+    if (req.httpVersion === '1.0') {
+      delete proxyRes.headers['transfer-encoding'];
+    }
+  },
+
+  /**
+   * If is a HTTP 1.0 request, set the correct connection header
+   * or if connection header not present, then use `keep-alive`
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {IncomingMessage} Res Response object
+   * @param {proxyResponse} Res Response object from the proxy request
+   *
+   * @api private
+   */
+  setConnection: function setConnection(req, res, proxyRes) {
+    if (req.httpVersion === '1.0') {
+      proxyRes.headers.connection = req.headers.connection || 'close';
+    } else if (req.httpVersion !== '2.0' && !proxyRes.headers.connection) {
+      proxyRes.headers.connection = req.headers.connection || 'keep-alive';
+    }
+  },
+
+  setRedirectHostRewrite: function setRedirectHostRewrite(req, res, proxyRes, options) {
+    if ((options.hostRewrite || options.autoRewrite || options.protocolRewrite)
+        && proxyRes.headers['location']
+        && redirectRegex.test(proxyRes.statusCode)) {
+      var target = url.parse(options.target);
+      var u = url.parse(proxyRes.headers['location']);
+
+      // make sure the redirected host matches the target host before rewriting
+      if (target.host != u.host) {
+        return;
+      }
+
+      if (options.hostRewrite) {
+        u.host = options.hostRewrite;
+      } else if (options.autoRewrite) {
+        u.host = req.headers['host'];
+      }
+      if (options.protocolRewrite) {
+        u.protocol = options.protocolRewrite;
+      }
+
+      proxyRes.headers['location'] = u.format();
+    }
+  },
+  /**
+   * Copy headers from proxyResponse to response
+   * set each header in response object.
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {IncomingMessage} Res Response object
+   * @param {proxyResponse} Res Response object from the proxy request
+   * @param {Object} Options options.cookieDomainRewrite: Config to rewrite cookie domain
+   *
+   * @api private
+   */
+  writeHeaders: function writeHeaders(req, res, proxyRes, options) {
+    var rewriteCookieDomainConfig = options.cookieDomainRewrite,
+        rewriteCookiePathConfig = options.cookiePathRewrite,
+        preserveHeaderKeyCase = options.preserveHeaderKeyCase,
+        rawHeaderKeyMap,
+        setHeader = function(key, header) {
+          if (header == undefined) return;
+          if (rewriteCookieDomainConfig && key.toLowerCase() === 'set-cookie') {
+            header = common.rewriteCookieProperty(header, rewriteCookieDomainConfig, 'domain');
+          }
+          if (rewriteCookiePathConfig && key.toLowerCase() === 'set-cookie') {
+            header = common.rewriteCookieProperty(header, rewriteCookiePathConfig, 'path');
+          }
+          res.setHeader(String(key).trim(), header);
+        };
+
+    if (typeof rewriteCookieDomainConfig === 'string') { //also test for ''
+      rewriteCookieDomainConfig = { '*': rewriteCookieDomainConfig };
+    }
+
+    if (typeof rewriteCookiePathConfig === 'string') { //also test for ''
+      rewriteCookiePathConfig = { '*': rewriteCookiePathConfig };
+    }
+
+    // message.rawHeaders is added in: v0.11.6
+    // https://nodejs.org/api/http.html#http_message_rawheaders
+    if (preserveHeaderKeyCase && proxyRes.rawHeaders != undefined) {
+      rawHeaderKeyMap = {};
+      for (var i = 0; i < proxyRes.rawHeaders.length; i += 2) {
+        var key = proxyRes.rawHeaders[i];
+        rawHeaderKeyMap[key.toLowerCase()] = key;
+      }
+    }
+
+    Object.keys(proxyRes.headers).forEach(function(key) {
+      var header = proxyRes.headers[key];
+      if (preserveHeaderKeyCase && rawHeaderKeyMap) {
+        key = rawHeaderKeyMap[key] || key;
+      }
+      setHeader(key, header);
+    });
+  },
+
+  /**
+   * Set the statusCode from the proxyResponse
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {IncomingMessage} Res Response object
+   * @param {proxyResponse} Res Response object from the proxy request
+   *
+   * @api private
+   */
+  writeStatusCode: function writeStatusCode(req, res, proxyRes) {
+    // From Node.js docs: response.writeHead(statusCode[, statusMessage][, headers])
+    if(proxyRes.statusMessage) {
+      res.statusCode = proxyRes.statusCode;
+      res.statusMessage = proxyRes.statusMessage;
+    } else {
+      res.statusCode = proxyRes.statusCode;
+    }
+  }
+
+};
diff --git a/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js b/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js
new file mode 100644
index 0000000..270f23f
--- /dev/null
+++ b/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js
@@ -0,0 +1,162 @@
+var http   = require('http'),
+    https  = require('https'),
+    common = require('../common');
+
+/*!
+ * Array of passes.
+ *
+ * A `pass` is just a function that is executed on `req, socket, options`
+ * so that you can easily add new checks while still keeping the base
+ * flexible.
+ */
+
+/*
+ * Websockets Passes
+ *
+ */
+
+
+module.exports = {
+  /**
+   * WebSocket requests must have the `GET` method and
+   * the `upgrade:websocket` header
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {Socket} Websocket
+   *
+   * @api private
+   */
+
+  checkMethodAndHeader : function checkMethodAndHeader(req, socket) {
+    if (req.method !== 'GET' || !req.headers.upgrade) {
+      socket.destroy();
+      return true;
+    }
+
+    if (req.headers.upgrade.toLowerCase() !== 'websocket') {
+      socket.destroy();
+      return true;
+    }
+  },
+
+  /**
+   * Sets `x-forwarded-*` headers if specified in config.
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {Socket} Websocket
+   * @param {Object} Options Config object passed to the proxy
+   *
+   * @api private
+   */
+
+  XHeaders : function XHeaders(req, socket, options) {
+    if(!options.xfwd) return;
+
+    var values = {
+      for  : req.connection.remoteAddress || req.socket.remoteAddress,
+      port : common.getPort(req),
+      proto: common.hasEncryptedConnection(req) ? 'wss' : 'ws'
+    };
+
+    ['for', 'port', 'proto'].forEach(function(header) {
+      req.headers['x-forwarded-' + header] =
+        (req.headers['x-forwarded-' + header] || '') +
+        (req.headers['x-forwarded-' + header] ? ',' : '') +
+        values[header];
+    });
+  },
+
+  /**
+   * Does the actual proxying. Make the request and upgrade it
+   * send the Switching Protocols request and pipe the sockets.
+   *
+   * @param {ClientRequest} Req Request object
+   * @param {Socket} Websocket
+   * @param {Object} Options Config object passed to the proxy
+   *
+   * @api private
+   */
+  stream : function stream(req, socket, options, head, server, clb) {
+
+    var createHttpHeader = function(line, headers) {
+      return Object.keys(headers).reduce(function (head, key) {
+        var value = headers[key];
+
+        if (!Array.isArray(value)) {
+          head.push(key + ': ' + value);
+          return head;
+        }
+
+        for (var i = 0; i < value.length; i++) {
+          head.push(key + ': ' + value[i]);
+        }
+        return head;
+      }, [line])
+      .join('\r\n') + '\r\n\r\n';
+    }
+
+    common.setupSocket(socket);
+
+    if (head && head.length) socket.unshift(head);
+
+
+    var proxyReq = (common.isSSL.test(options.target.protocol) ? https : http).request(
+      common.setupOutgoing(options.ssl || {}, options, req)
+    );
+
+    // Enable developers to modify the proxyReq before headers are sent
+    if (server) { server.emit('proxyReqWs', proxyReq, req, socket, options, head); }
+
+    // Error Handler
+    proxyReq.on('error', onOutgoingError);
+    proxyReq.on('response', function (res) {
+      // if upgrade event isn't going to happen, close the socket
+      if (!res.upgrade) {
+        socket.write(createHttpHeader('HTTP/' + res.httpVersion + ' ' + res.statusCode + ' ' + res.statusMessage, res.headers));
+        res.pipe(socket);
+      }
+    });
+
+    proxyReq.on('upgrade', function(proxyRes, proxySocket, proxyHead) {
+      proxySocket.on('error', onOutgoingError);
+
+      // Allow us to listen when the websocket has completed
+      proxySocket.on('end', function () {
+        server.emit('close', proxyRes, proxySocket, proxyHead);
+      });
+
+      // The pipe below will end proxySocket if socket closes cleanly, but not
+      // if it errors (eg, vanishes from the net and starts returning
+      // EHOSTUNREACH). We need to do that explicitly.
+      socket.on('error', function () {
+        proxySocket.end();
+      });
+
+      common.setupSocket(proxySocket);
+
+      if (proxyHead && proxyHead.length) proxySocket.unshift(proxyHead);
+
+      //
+      // Remark: Handle writing the headers to the socket when switching protocols
+      // Also handles when a header is an array
+      //
+      socket.write(createHttpHeader('HTTP/1.1 101 Switching Protocols', proxyRes.headers));
+
+      proxySocket.pipe(socket).pipe(proxySocket);
+
+      server.emit('open', proxySocket);
+      server.emit('proxySocket', proxySocket);  //DEPRECATED.
+    });
+
+    return proxyReq.end(); // XXX: CHECK IF THIS IS THIS CORRECT
+
+    function onOutgoingError(err) {
+      if (clb) {
+        clb(err, req, socket);
+      } else {
+        server.emit('error', err, req, socket);
+      }
+      socket.end();
+    }
+  }
+};