diff --git a/docs/docco.css b/docs/docco.css index bd54134..5aa0a8d 100644 --- a/docs/docco.css +++ b/docs/docco.css @@ -15,20 +15,12 @@ a { p { margin: 0 0 15px 0; } -h4, h5, h6 { - color: #333; - margin: 6px 0 6px 0; - font-size: 13px; +h1, h2, h3, h4, h5, h6 { + margin: 0px 0 15px 0; } - h2, h3 { - margin-bottom: 0; - color: #000; + h1 { + margin-top: 40px; } - h1 { - margin-top: 40px; - margin-bottom: 15px; - color: #000; - } #container { position: relative; } @@ -123,7 +115,7 @@ table td { } pre, tt, code { font-size: 12px; line-height: 18px; - font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; + font-family: Monaco, Consolas, "Lucida Console", monospace; margin: 0; padding: 0; } diff --git a/docs/node-http-proxy.html b/docs/node-http-proxy.html index 7ef31c9..1975f0b 100644 --- a/docs/node-http-proxy.html +++ b/docs/node-http-proxy.html @@ -1,4 +1,4 @@ - node-http-proxy.js
Jump To …

node-http-proxy.js

/*
+      node-http-proxy.js           

node-http-proxy.js

/*
   node-http-proxy.js: http proxy for node.js
 
   Copyright (c) 2010 Charlie Robbins, Mikeal Rogers, Marak Squires, Fedor Indutny 
@@ -26,18 +26,48 @@
 
 var util = require('util'),
     http = require('http'),
+    https = require('https'),
     events = require('events'),
     ProxyTable = require('./proxy-table').ProxyTable,
-    maxSockets = 100;

Version 0.4.2

exports.version = [0, 4, 2];

function _getAgent (host, port)

+ maxSockets = 100;

Version 0.5.0

exports.version = [0, 5, 0];

function _getAgent (host, port, secure)

@host {string} Host of the agent to get

@port {number} Port of the agent to get

-

Retreives an agent from the http module -and sets the maxSockets property appropriately.

function _getAgent (host, port) {

TODO (indexzero): Make this configurable for http / https

  var agent = http.getAgent(host, port);
+

@secure {boolean} Value indicating whether or not to use HTTPS

+ +

Retreives an agent from the http or https module +and sets the maxSockets property appropriately.

function _getAgent (host, port, secure) {
+  var agent = !secure ? http.getAgent(host, port) : https.getAgent({ 
+    host: host, 
+    port: port 
+  });
+      
   agent.maxSockets = maxSockets;
   return agent;
+}

function _getProtocol (secure, outgoing)

+ +

@secure {Object|boolean} Settings for https

+ +

@outgoing {Object} Outgoing request options

+ +

Returns the appropriate protocol based on the settings in +secure. If the protocol is https this function will update +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;
+  
+  if (typeof secure === 'object') {
+    outgoing = outgoing || {};
+    ['ca', 'cert', 'key'].forEach(function (prop) {
+      if (secure[prop]) {
+        outgoing[prop] = secure[prop];
+      }
+    })
+  }
+  
+  return protocol;
 }

function getMaxSockets ()

Returns the maximum number of sockets @@ -67,11 +97,10 @@ made by all instances of HttpProxy

  • `httpProxy.createServer(9000, 'localhost', options)
  • httpPRoxy.createServer(function (req, res, proxy) { ... })
  • exports.createServer = function () {
    -  var args, callback, port, host, forward, 
    -      silent, options, proxy, server;
    -  
    -  args = Array.prototype.slice.call(arguments);
    -  callback = typeof args[args.length - 1] === 'function' && args.pop();
    +  var args = Array.prototype.slice.call(arguments), 
    +      callback = typeof args[0] === 'function' && args.shift(),
    +      options = {},
    +      port, host, forward, silent, proxy, server;
       
       if (args.length >= 2) {
         port = args[0];
    @@ -86,21 +115,27 @@ made by all instances of HttpProxy

    } proxy = new HttpProxy(options); - server = http.createServer(function (req, res) { - proxy.emit('request', req, request.headers.host, req.url);

    If we were passed a callback to process the request -or response in some way, then call it.

        if (callback) {
    -      callback(req, res, proxy);
    +  
    +  handler = function (req, res) {
    +    if (callback) {

    If we were passed a callback to process the request +or response in some way, then call it.

          callback(req, res, proxy);
         } 
    -    else if (port && host) {
    -      proxy.proxyRequest(req, res, port, host);
    +    else if (port && host) {

    If we have a target host and port for the request +then proxy to the specified location.

          proxy.proxyRequest(req, res, {
    +        port: port, 
    +        host: host
    +      });
         }
    -    else if (proxy.proxyTable) {
    -      proxy.proxyRequest(req, res);
    +    else if (proxy.proxyTable) {

    If the proxy is configured with a ProxyTable +instance then use that before failing.

          proxy.proxyRequest(req, res);
         }
    -    else {
    -      throw new Error('Cannot proxy without port, host, or router.')
    +    else {

    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.on('close', function () {
         proxy.close();
    @@ -110,14 +145,19 @@ or response in some way, then call it.

    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(port, 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;
    -};

    function HttpProxy (options)

    +};

    function HttpProxy (options)

    @options {Object} Options for this instance.

    @@ -139,17 +179,18 @@ for managing the life-cycle of streaming reverse proxyied HTTP requests.

    var HttpProxy = exports.HttpProxy = function (options) {
       events.EventEmitter.call(this);
       
    -  options = options || {};
    -  this.options = options;
    +  var self     = this;
    +  options      = options || {};
    +  this.forward = options.forward;
    +  this.https   = options.https;
       
       if (options.router) {
    -    var self = this;
         this.proxyTable = new ProxyTable(options.router, options.silent, options.hostnameOnly);
         this.proxyTable.on('routes', function (routes) {
           self.emit('routes', routes);
         });
       }
    -};

    Inherit from events.EventEmitter

    util.inherits(HttpProxy, events.EventEmitter);

    function buffer (obj)

    +};

    Inherit from events.EventEmitter

    util.inherits(HttpProxy, events.EventEmitter);

    function buffer (obj)

    @obj {Object} Object to pause events from

    @@ -167,7 +208,7 @@ the async operation has completed, otherwise these

    Attribution: This approach is based heavily on Connect. -However, this is not a big leap from the implementation in node-http-proxy < 0.4.0. +However, this is not a big leap from the implementation in node-http-proxy < 0.4.0. This simply chooses to manage the scope of the events on a new Object literal as opposed to on the HttpProxy instance.

    HttpProxy.prototype.buffer = function (obj) {
       var onData, onEnd, events = [];
    @@ -192,51 +233,54 @@ This simply chooses to manage the scope of  the events on a new Object literal a
           }
         }
       };
    -};

    function close ()

    +};

    function close ()

    Frees the resources associated with this instance, if they exist.

    HttpProxy.prototype.close = function () {
       if (this.proxyTable) this.proxyTable.close();
    -};

    function proxyRequest (req, res, [port, host, paused])

    +};

    function proxyRequest (req, res, [port, host, paused])

    @req {ServerRequest} Incoming HTTP Request to proxy.

    @res {ServerResponse} Outgoing HTTP Request to write proxied data to.

    -

    @port {number} Optional Port to use on the proxy target host.

    +

    @options {Object} Options for the outgoing proxy request.

    -

    @host {string} Optional Host of the proxy target.

    - -

    @buffer {Object} Optional Result from httpProxy.buffer(req)

    HttpProxy.prototype.proxyRequest = function (req, res, port, host, buffer) {
    -  var self = this, reverseProxy, location, errState = false, opts;
    -  

    Check the proxy table for this instance to see if we need +

    options.port {number} Port to use on the proxy target host.
    +options.host {string} Host of the proxy target.
    +options.buffer {Object} Result from `httpProxy.buffer(req)`
    +options.https {Object|boolean} Settings for https.
    +
    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.

      options = options || {};
    +  

    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 && !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 +

    If no location is returned from the ProxyTable instance then respond with 404 since we do not have a valid proxy target.

        if (!location) {
           res.writeHead(404);
           return res.end();
         }
    -    

    When using the ProxyTable in conjunction with an HttpProxy instance +

    When using the ProxyTable in conjunction with an HttpProxy instance only the following arguments are valid:

      -
    • proxy.proxyRequest(req, res, port, host, buffer): This will be skipped
    • -
    • proxy.proxyRequest(req, res, buffer): Buffer will get updated appropriately
    • -
    • proxy.proxyRequest(req, res): No effect undefined = undefined
    • -
        buffer = port;
    -    port = location.port;
    -    host = location.host;
    +
  • 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;
       }
    -  

    Emit the start event indicating that we have begun the proxy operation.

      this.emit('start', req, res, host, port);
    -  

    If forwarding is enabled for this instance, foward proxy the -specified request to the address provided in this.options.forward

      if (this.options.forward) {
    -    this.emit('forward', req, res, this.options.forward.host, this.options.forward.port);
    +  

    Add x-forwarded-for header to availible client IP to apps behind proxy

      req.headers['x-forwarded-for'] = req.connection.remoteAddress;
    +  

    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)

    +

    function proxyError (err)

    @err {Error} Error contacting the proxy target

    @@ -252,28 +296,30 @@ contacting the proxy target at host / port.

    res.end(); } - var opts = { - host: host, - port: port, - agent: _getAgent(host, port), + outgoing = { + host: options.host, + port: options.port, + agent: _getAgent(options.host, options.port, options.https || this.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'.

      opts.headers['connection'] = 'close';
    -  

    Open new HTTP request to internal resource with will act as a reverse proxy pass

      reverseProxy = http.request(opts, function (response) {
    -    

    Process the reverseProxy response when it's received.

        if (response.headers.connection) {
    +    

    Force the connection header to be 'close' until +node.js core re-implements 'keep-alive'.

      outgoing.headers['connection'] = 'close';
    +  
    +  protocol = _getProtocol(options.https || this.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';
    -    }

    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) {
    +    }

    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) {
           return res.end();
    -    }

    For each data chunk received from the reverseProxy + }

    For each data chunk received from the reverseProxy response write it to the outgoing res.

        response.on('data', function (chunk) {
           if (req.method !== 'HEAD') {
             res.write(chunk);
           }
    -    });

    When the reverseProxy response ends, end the + });

    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 @@ -281,164 +327,174 @@ removed.

    if (!errState) { reverseProxy.removeListener('error', proxyError); res.end(); +

    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);
    -  

    For each data chunk received from the incoming +

    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 + });

    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 (buffer && !errState) {
    -    buffer.resume();
    +  });

    If we have been passed buffered data, resume it.

      if (options.buffer && !errState) {
    +    options.buffer.resume();
       }
     };
    -  

    @private function _forwardRequest (req)

    +

    @private function _forwardRequest (req)

    @req {ServerRequest} Incoming HTTP Request to proxy.

    Forwards the specified req to the location specified -by this.options.forward ignoring errors and the subsequent response.

    HttpProxy.prototype._forwardRequest = function (req) {
    -  var self = this, port, host, forwardProxy, opts;
    +by this.forward ignoring errors and the subsequent response.

    HttpProxy.prototype._forwardRequest = function (req) {
    +  var self = this, port, host, outgoing, protocol, forwardProxy;
     
    -  port = this.options.forward.port;
    -  host = this.options.forward.host;
    +  port = this.forward.port;
    +  host = this.forward.host;
       
    -  opts = {
    +  outgoing = {
         host: host,
         port: port,
    -    agent: _getAgent(host, 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'.

      opts.headers['connection'] = 'close';
    -  

    Open new HTTP request to internal resource with will act as a reverse proxy pass

      forwardProxy = http.request(opts, function (response) {

    Ignore the response from the forward proxy since this is a 'fire-and-forget' proxy. +

    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.

    +

    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) {
    +        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 () {
    +  })

    At the end of the client request, we are going to stop the proxied request

      req.on('end', function () {
         forwardProxy.end();
       });
     };
     
    -HttpProxy.prototype.proxyWebSocketRequest = function (port, server, host, data) {
    -  var self = this, req = self.req, socket = self.sock, head = self.head, 
    -      headers = new _headers(req.headers), CRLF = '\r\n';

    Will generate clone of headers -To not change original

      function _headers(headers) {
    -    var h = {};
    -    for (var i in headers) {
    -      h[i] = headers[i];
    -    }
    -    return h;
    -  }

    WebSocket requests has method = GET

      if (req.method !== 'GET' || headers.upgrade.toLowerCase() !== 'websocket') {

    This request is not WebSocket request

        return;
    -  }

    Turn of all bufferings +HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options) { + var self = this, outgoing, errState = false, CRLF = '\r\n';

    WebSocket requests has method = GET

      if (req.method !== 'GET' || req.headers.upgrade.toLowerCase() !== 'websocket') {

    This request is not WebSocket request

        return;
    +  }

    Turn of all bufferings For server set KeepAlive -For client set encoding

      function _socket(socket, server) {
    +For client set encoding

      function _socket(socket, keepAlive) {
         socket.setTimeout(0);
         socket.setNoDelay(true);
    -    if (server) {
    +    if (keepAlive) {
           socket.setKeepAlive(true, 0);
         } 
         else {
           socket.setEncoding('utf8');
         }
    -  }

    Client socket

      _socket(socket);

    If host is undefined -Get it from headers

      if (!host) {
    -    host = headers.Host;
       }
    -  

    Remote host address

      var remote_host = server + (port - 80 === 0 ? '' : ':' + port);

    Change headers

      headers.Host = remote_host;
    -  headers.Origin = 'http://' + remote_host;

    Open request

      var p = manager.getPool(port, server);
    -
    -  p.getClient(function(client) {

    Based on 'pool/main.js'

        var request = client.request('GET', req.url, headers);
    -
    -    var errorListener = function (error) {
    -      client.removeListener('error', errorListener);
    -      

    Remove the client from the pool's available clients since it has errored

          p.clients.splice(p.clients.indexOf(client), 1);
    -      socket.end();
    -    }

    Not disconnect on update

        client.on('upgrade', function(request, remote_socket, head) {

    Prepare socket

          _socket(remote_socket, true);

    Emit event

          onUpgrade(remote_socket);
    -    });
    -
    -    client.on('error', errorListener);
    -    request.on('response', function (response) {
    -      response.on('end', function () {
    -        client.removeListener('error', errorListener);
    -        client.busy = false;
    -        p.onFree(client);
    -      })
    -    })
    -    client.busy = true;
    -
    -    var handshake;
    -    request.socket.on('data', handshake = function(data) {

    Handshaking

    Ok, kind of harmfull part of code -Socket.IO is sending 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 Printable

          sdata = sdata.substr(0, sdata.search(CRLF + CRLF));

    Get Non-Printable

          data = data.slice(Buffer.byteLength(sdata), data.length);

    Replace host and origin

          sdata = sdata.replace(remote_host, host)
    -                   .replace(remote_host, host);
    -
    -      try {

    Write printable

            socket.write(sdata);

    Write non-printable

            socket.write(data);
    -      } 
    -      catch (e) {
    -        request.end();
    -        socket.end();
    -      }

    Catch socket errors

          socket.on('error', function() {
    -        request.end();
    -      });

    Remove data listener now that the 'handshake' is complete

          request.socket.removeListener('data', handshake);
    -    });

    Write upgrade-head

        try {
    -      request.write(head);
    -    } 
    -    catch(e) {
    -      request.end();
    +  
    +  function onUpgrade(out, reverseProxy) {
    +    if (!out) {
    +      reverseProxy.end();
           socket.end();
    +      return;
         }
    -    self.unwatch(socket);
    -  });

    Request

      function onUpgrade(reverse_proxy) {
    +    
         var listeners = {};
    -    

    We're now connected to the server, so lets change server socket

        reverse_proxy.on('data', listeners._r_data = function(data) {

    Pass data to client

          if (socket.writable) {
    +    

    We're now connected to the server, so lets change server socket

        reverseProxy.on('data', listeners._r_data = function(data) {

    Pass data to client

          if (out.incoming.socket.writable) {
             try {
    -          socket.write(data);
    +          out.incoming.socket.write(data);
             } 
             catch (e) {
    -          socket.end();
    -          reverse_proxy.end();
    +          out.incoming.socket.end();
    +          reverseProxy.end();
             }
           }
         });
     
    -    socket.on('data', listeners._data = function(data) {

    Pass data from client to server

          try {
    -        reverse_proxy.write(data);
    +    out.incoming.socket.on('data', listeners._data = function(data) {

    Pass data from client to server

          try {
    +        reverseProxy.write(data);
           } 
           catch (e) {
    -        reverse_proxy.end();
    +        reverseProxy.end();
             socket.end();
           }
    -    });

    Detach event listeners from reverse_proxy

        function detach() {
    -      reverse_proxy.removeListener('close', listeners._r_close);
    -      reverse_proxy.removeListener('data', listeners._r_data);
    -      socket.removeListener('data', listeners._data);
    -      socket.removeListener('close', listeners._close);
    -    }

    Hook disconnections

        reverse_proxy.on('end', listeners._r_close = function() {
    -      socket.end();
    +    });

    Detach event listeners from reverseProxy

        function detach() {
    +      reverseProxy.removeListener('close', listeners._r_close);
    +      reverseProxy.removeListener('data', listeners._r_data);
    +      out.incoming.socket.removeListener('data', listeners._data);
    +      out.incoming.socket.removeListener('close', listeners._close);
    +    }

    Hook disconnections

        reverseProxy.on('end', listeners._r_close = function() {
    +      out.incoming.socket.end();
           detach();
         });
     
         socket.on('end', listeners._close = function() {
    -      reverse_proxy.end();
    +      reverseProxy.end();
           detach();
         });
    +  };

    Client socket

      _socket(socket);
    +  

    Remote host address

      var agent      = _getAgent(options.host, options.port),
    +      remoteHost = options.host + (options.port - 80 === 0 ? '' : ':' + options.port);

    Change headers

      req.headers.host   = remoteHost;
    +  req.headers.origin = 'http://' + options.host;
    +  
    +  outgoing = {
    +    host: options.host,
    +    port: options.port,
    +    method: 'GET',
    +    path: req.url,
    +    headers: req.headers,
    +  };

    Make the outgoing WebSocket request

      var request = agent.appendMessage(outgoing);

    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.

      request.agent = agent;
    +  request.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 (out, remoteSocket, head) {

    Prepare socket

          _socket(remoteSocket, true);
    +      

    Emit event

          onUpgrade(remoteSocket._httpMessage, remoteSocket);
    +    });
    +  }
    +  
    +  if (typeof request.socket !== 'undefined') {
    +    request.socket.on('data', function handshake (data) {

    Handshaking

    Ok, kind of harmfull part of code +Socket.IO is sending 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 Printable

          sdata = sdata.substr(0, sdata.search(CRLF + CRLF));

    Get Non-Printable

          data = data.slice(Buffer.byteLength(sdata), data.length);

    Replace host and origin

          sdata = sdata.replace(remoteHost, options.host)
    +                   .replace(remoteHost, options.host);
    +
    +      try {

    Write printable

            socket.write(sdata);

    Write non-printable

            socket.write(data);
    +      } 
    +      catch (e) {
    +        request.end();
    +        socket.end();
    +      }

    Catch socket errors

          socket.on('error', function() {
    +        request.end();
    +      });

    Remove data listener now that the 'handshake' is complete

          request.socket.removeListener('data', handshake);
    +    });
    +  }

    Write upgrade-head

      try {
    +    request.write(head);
    +  } 
    +  catch (ex) {
    +    request.end();
    +    socket.end();
    +  }
    +  

    If we have been passed buffered data, resume it.

      if (options.buffer && !errState) {
    +    options.buffer.resume();
    +  }
     };
     
     
    \ No newline at end of file diff --git a/docs/proxy-table.html b/docs/proxy-table.html index d033647..3246477 100644 --- a/docs/proxy-table.html +++ b/docs/proxy-table.html @@ -1,4 +1,4 @@ - proxy-table.js

    proxy-table.js

    /*
    +      proxy-table.js           

    proxy-table.js

    /*
       node-http-proxy.js: Lookup table for proxy targets in node.js
     
       Copyright (c) 2010 Charlie Robbins