Nodejitsu

Save time managing and deploying your node.js app. Code faster with jitsu and npm

Updating to node-http-proxy v0.5.0

About the author

Name
Location
Worldwide
nodejitsu nodejitsu

Beyond all of the hype that you might be hearing about node.js these days at it's core it has always been about one thing: fast network programming. This aspect of node.js is why we created and have maintained node-http-proxy for almost a year now. The project has matured with contributions from notable members of the community and a lot of maintenance from yours truly; we have been working on this since node.js 0.1.98 afterall.

This article marks the release of node-http-proxy v0.5.0 which has some breaking changes to make the API more extensible for the next WebSocket and HTTPS support. We'll be reviewing changes since v0.3.0, which is still in use in many environments. tl;dr? Checkout the Changelog for the project.


Who is affected?

From the beginning, node-http-proxy has been designed with an extremely flexible API that allows you to use it as a stand-alone proxy server or in conjunction with another HTTP server (for example, a connect server). If you're using the stand-alone proxy you have nothing to worry about, that API hasn't changed at all:

  require('http-proxy').createServer(port, host, options).listen(8000);

APIs for other more-custom tailored use-cases have changed, so read on below. All of these code samples are also available as examples on GitHub.


Use http.Agent in node.js 0.3.6+

We took advantage of the new http.Agent APIs introduced in node.js v0.3.6+. This allowed us to remove the "pool" module dependency because instances of http.Agent now perform socket pooling.


No more eager request buffering

It is no longer necessary to create an instance of HttpProxy for each incoming connection. The motivation for that design choice was that we could eagerly buffer the incoming request in-case the user decides to wait before proxying (i.e. latent proxying). This turns out to be less than ideal for memory performance because not every scenario will require request buffering. The onus is therefore now on the user using the new .buffer() method:

Old (v0.3.0)

var http = require('http'),  
    httpProxy = require('http-proxy');

//
// Create a proxy server with custom application logic
//
httpProxy.createServer(function (req, res, proxy) {  
  //
  // Wait for two seconds then respond: this simulates
  // performing async actions before proxying a request
  //
  setTimeout(function () {
    proxy.proxyRequest(9000, 'localhost');      
  }, 2000);
}).listen(8000);

New (v0.5.0)

var http = require('http'),  
    httpProxy = require('http-proxy');

//
// Create a proxy server with custom application logic
//
httpProxy.createServer(function (req, res, proxy) {  
  //
  // Buffer the request first
  //
  var buffer = proxy.buffer(req);

  //
  // Wait for two seconds then respond: this simulates
  // performing async actions before proxying a request
  //
  // Note: Now we have to pass both `req` and `res` to 
  // `.proxyRequest()`.
  //
  setTimeout(function () {
    proxy.proxyRequest(req, res, {
      host: 'localhost',
      port: 9000,
      buffer: buffer
    });      
  }, 2000);
}).listen(8000);

var http = require('http'), httpProxy = require('http-proxy');

// // Create an instance of node-http-proxy // var proxy = new httpProxy.HttpProxy();

var server = http.createServer(function (req, res) {
// // Proxy normal HTTP requests // proxy.proxyRequest(req, res, { host: 'localhost', port: 8000 }) });

server.on('upgrade', function(req, socket, head) {
// // Proxy websocket requests too // proxy.proxyWebSocketRequest(req, socket, head, { host: 'localhost', port: 8000 }); });

It's also important to note in the above v0.5.0 code sample how the arguments passed to .proxyRequest() have changed from a list of arguments to the following signature: proxy.proxyRequest(req, res, options) where options must include the host and port properties.


Using WebSocket Support

Websockets are handled automatically when using the httpProxy.createServer(), but if you want to use it in conjunction with a stand-alone HTTP + WebSocket (such as socket.io) server here's how:

var http = require('http'),  
    httpProxy = require('http-proxy');

//
// Create an instance of node-http-proxy
//
var proxy = new httpProxy.HttpProxy();

var server = http.createServer(function (req, res) {  
  //
  // Proxy normal HTTP requests
  //
  proxy.proxyRequest(req, res, {
    host: 'localhost',
    port: 8000
  })
});

server.on('upgrade', function(req, socket, head) {  
  //
  // Proxy websocket requests too
  //
  proxy.proxyWebSocketRequest(req, socket, head, {
    host: 'localhost',
    port: 8000
  });
});


Proxying over HTTPS

Proxying over HTTPS is a common scenarios for reverse proxies. You want your proxy server running on HTTPS while each of your target servers is running HTTP. Both HTTPS -> HTTPS and HTTPS -> HTTP proxying is now possible in node-http-proxy v0.5.0.


Roadmap

Clearly node-http-proxy has come a long way since v0.1.0. But where do we go from here?


  1. Add Whitelist / Blacklist Support
  2. Support Gzip
  3. Proxy Authentication
  4. Add something yourself!