spec/shared/setup.js
function configureLanProxy(options, config, done) {
  var portfinder = require('portfinder'),
      request = require('request'),
      credentials = config.proxy.gateway.auth,
      gatewayPort,
      expectedAuthorizationHeader,
      requestViaHeader,
      responseViaHeader;

  handles = handles || {};

  handles.gatewayServer = require('http').createServer(function (req, res) {
    expectedAuthorizationHeader = 'Basic ' + new Buffer(credentials).toString('base64');

    // HACK: node 0.12.x appears to inject a slash at the front
    //       of absolute URLs
    //       ex., GET http://www.example.com --> GET /http://www.exampel.com
    if (req.url.charAt(0) === '/') {
      req.url = req.url.substr(1);
    }

    // validate the proxy target
    if (req.url !== req.headers['x-forwarded-url']) {
        res.writeHead(500);
        res.end('{ "error": 500, "message": "invalid proxy request, expected X-Forwarded-Url header ' + req.headers['x-forwarded-url'] + '" }');
        return;
    }

    // validate the proxy credentials
    if (req.headers['authorization'] !== expectedAuthorizationHeader) {
      res.writeHead(401);
      res.end('{ "error": 401, "message": "invalid proxy credentials, expected ' + expectedAuthorizationHeader + '" }');
      return;
    }

    // determine if we are using a proxy that is not RFC compliant
    requestViaHeader = options.headers['Via'] ||
                        '127.0.0.1:' + handles.port;

    responseHostHeader = options.headers['Host'] ||
                        req.headers['host'];

    responseViaHeader = options.headers['Via'] ||
                        'http://localhost:' + gatewayPort;

    // validate the via header was injected and points to 127.0.0.1 in either ipv4 or ipv6 format
    if (req.headers['via'] === undefined || req.headers['via'] === null || req.headers['via'].indexOf(requestViaHeader) === -1) {
      res.writeHead(400);
      res.end('{ "error": 400, "message": "invalid via header, expected ' + requestViaHeader + '" }');
      return;
    }

    // strip the proxy credentials header
    req.headers['authorization'] = null;
    // simulate the behavior of x-forwarded-for with multiple proxies
    req.headers['x-forwarded-for'] = [req.headers['x-forwarded-for'], req.headers['via']].join(', ');
    // change the via header to this server
    req.headers['via'] = responseViaHeader;
    req.headers['host'] = responseHostHeader;

    var errorCallback = function errorCallback(err, repsonse, body) {
      if (err) {
        res.writeHead(500);
        res.end(JSON.stringify({ "error": 500, "message": err.message  }));
        return;
      }
    }

    request(req, errorCallback).pipe(res);
  });

  portfinder.getPort(function (err, port) {
    if (err) done(err);

    config.proxy.gateway.port = port;
    gatewayPort = port;

    handles.gatewayServer.listen(port, function() {
      done(null);
    });
  });
}
function configureLanProxy(options, config, done) {
  var portfinder = require('portfinder'),
      request = require('request'),
      credentials = config.proxy.gateway.auth,
      gatewayPort,
      expectedAuthorizationHeader,
      requestViaHeader,
      responseViaHeader;

  handles = handles || {};

  handles.gatewayServer = require('http').createServer(function (req, res) {
    expectedAuthorizationHeader = 'Basic ' + new Buffer(credentials).toString('base64');

    // HACK: node 0.12.x appears to inject a slash at the front
    //       of absolute URLs
    //       ex., GET http://www.example.com --> GET /http://www.exampel.com
    if (req.url.charAt(0) === '/') {
      req.url = req.url.substr(1);
    }

    // validate the proxy target
    if (req.url !== req.headers['x-forwarded-url']) {
        res.writeHead(500);
        res.end('{ "error": 500, "message": "invalid proxy request, expected X-Forwarded-Url header ' + req.headers['x-forwarded-url'] + '" }');
        return;
    }

    // validate the proxy credentials
    if (req.headers['authorization'] !== expectedAuthorizationHeader) {
      res.writeHead(401);
      res.end('{ "error": 401, "message": "invalid proxy credentials, expected ' + expectedAuthorizationHeader + '" }');
      return;
    }

    // determine if we are using a proxy that is not RFC compliant
    requestViaHeader = options.headers['Via'] ||
                        '127.0.0.1:' + handles.port;

    responseHostHeader = options.headers['Host'] ||
                        req.headers['host'];

    responseViaHeader = options.headers['Via'] ||
                        'http://localhost:' + gatewayPort;

    // validate the via header was injected and points to 127.0.0.1 in either ipv4 or ipv6 format
    if (req.headers['via'] === undefined || req.headers['via'] === null || req.headers['via'].indexOf(requestViaHeader) === -1) {
      res.writeHead(400);
      res.end('{ "error": 400, "message": "invalid via header, expected ' + requestViaHeader + '" }');
      return;
    }

    // strip the proxy credentials header
    req.headers['authorization'] = null;
    // simulate the behavior of x-forwarded-for with multiple proxies
    req.headers['x-forwarded-for'] = [req.headers['x-forwarded-for'], req.headers['via']].join(', ');
    // change the via header to this server
    req.headers['via'] = responseViaHeader;
    req.headers['host'] = responseHostHeader;

    var errorCallback = function errorCallback(err, repsonse, body) {
      if (err) {
        res.writeHead(500);
        res.end(JSON.stringify({ "error": 500, "message": err.message  }));
        return;
      }
    }

    request(req, errorCallback).pipe(res);
  });

  portfinder.getPort(function (err, port) {
    if (err) done(err);

    config.proxy.gateway.port = port;
    gatewayPort = port;

    handles.gatewayServer.listen(port, function() {
      done(null);
    });
  });
}
Creates a simple LAN proxy using a vanilla HTTP server
that verifies the state of the proxy credentials and the x-forwarded-url
are correct.

@param  {Object.<string, string>} options  the options for configuring this
test suite
@param  {Object.<string, string>} config   the config of the json-proxy for
this test suite
@param  {Function} done