nodejs node-proxy,使用路由表并修改响应

时间:2012-12-03 12:51:54

标签: node.js reverse-proxy

我们在实验室中有一个简单的nodejs流程用于测试/开发工作。我们正在使用node-proxy设置反向代理,允许我们使用http(即http - > https)与https服务器进行通信。作为其中的一部分,我们有一些用于修改响应的代码。以下是我们正在做的事情:

var http = require('http'),
    httpProxy = require('http-proxy'), 
    endserver = 'server.local',
    endport = 8443;

var proxy = new httpProxy.HttpProxy({ 
  target: {
    https: true,
    host: endserver,
    port: endport
  } 
});

http.createServer(function (req, res) {
  //our code for modifying response is here...
  proxy.proxyRequest(req, res);
}).listen(8001);

我想设置一个节点代理路由表,就像这个例子here一样,所以我可以根据请求中的主机名将请求转发到不同的https服务器(我将在我们的服务器上设置多个主机名) dns指向运行nodejs代理的同一服务器。)

如何拥有节点代理路由表并修改响应?

(我对node.js很新,但不是javascript)

1 个答案:

答案 0 :(得分:2)

如果我正确地阅读了您的问题,您只需要知道如何使用节点代理路由表根据请求对象路由不同主机的请求。这实际上是由node-http-proxy文档解决的:Proxy requests using a ProxyTable

将其粘贴,您只需在JS对象中配置路径,如下所示:

var options = {
  router: {
    'foo.com/baz': '127.0.0.1:8001',
    'foo.com/buz': '127.0.0.1:8002',
    'bar.com/buz': '127.0.0.1:8003'
  }
};

然后在创建代理服务器时传递此对象:

var proxyServer = httpProxy.createServer(options);
proxyServer.listen(80);

为您的代码指定此结果会产生以下结果:

var http = require('http'),
    httpProxy = require('http-proxy'), 
    endserver = 'server.local',
    endport = 8443;

var options = {
  router: {
    endserver + '/foo': '127.0.0.1:8081',
    endserver + '/bar': '127.0.0.1:8082',
    endserver + '/baz': '127.0.0.1:8083'
  }
};

var proxyServer = httpProxy.createServer(options);
proxyServer.listen(endport);

http.createServer(function (req, res) {
  // your code for modifying response is here...
  proxy.proxyRequest(req, res);
}).listen(8001);

使用路由器选项时,无需自己设置目标。似乎也处理了https的区别,但我不确定。我从proxy-table.js source获得了这些信息。特别是:

ProxyTable.prototype.setRoutes = function (router) {
  if (!router) {
    throw new Error('Cannot update ProxyTable routes without router.');
  }

  var self = this;
  this.router = router;

  if (this.hostnameOnly === false) {
    this.routes = [];

    Object.keys(router).forEach(function (path) {
      if (!/http[s]?/.test(router[path])) {
        router[path] = (self.target.https ? 'https://' : 'http://')
          + router[path];
      }

      var target = url.parse(router[path]),
          defaultPort = self.target.https ? 443 : 80;

      //
      // Setup a robust lookup table for the route:
      //
      // {
      // source: {
      // regexp: /^foo.com/i,
      // sref: 'foo.com',
      // url: {
      // protocol: 'http:',
      // slashes: true,
      // host: 'foo.com',
      // hostname: 'foo.com',
      // href: 'http://foo.com/',
      // pathname: '/',
      // path: '/'
      // }
      // },
      // {
      // target: {
      // sref: '127.0.0.1:8000/',
      // url: {
      // protocol: 'http:',
      // slashes: true,
      // host: '127.0.0.1:8000',
      // hostname: '127.0.0.1',
      // href: 'http://127.0.0.1:8000/',
      // pathname: '/',
      // path: '/'
      // }
      // },
      //
      self.routes.push({
        source: {
          regexp: new RegExp('^' + path, 'i'),
          sref: path,
          url: url.parse('http://' + path)
        },
        target: {
          sref: target.hostname + ':' + (target.port || defaultPort) + target.path,
          url: target
        }
      });
    });
  }
};