windows - 支持 https 的 Node.js 代理服务器

标签 windows node.js https proxy

我正在尝试编写将代理(几乎)所有 http/s 请求的代理服务器。几乎都是因为我需要捕获某些特定 https url 的请求,并且作为响应从 hdd 发送文件而不是来自网络的真实响应。

整个解决方案应该在浏览器中作为代理工作,并且必须在 Windows 7 上工作。我从基于 express.js 的自己的代理开始。它工作得很好......但不幸的是不是通过 https。然后我尝试使用来自 github(https://github.com/horaci/node-mitm-proxyhttps://github.com/Hypermediaisobar/hyperProxy 和其他一些)的几个现有 node.js 代理服务器,但它们中的任何一个都在 https 上的 Windows 环境中工作(或者我不知道如何配置它们)。

最后我在 Internet 代码中找到了某个地方(没有指向源代码的链接),它通过 https 工作(见下面的代码)。这段代码的问题是,我找不到正确的方法来检查传入的请求 url,并且根据请求 url 以不同的方式处理它们。 如果有人可以帮助我,我将不胜感激。

var http = require('http');
var net = require('net');

var debugging = 0;

var regex_hostport = /^([^:]+)(:([0-9]+))?$/;

function getHostPortFromString(hostString, defaultPort) {
  var host = hostString;
  var port = defaultPort;

  var result = regex_hostport.exec(hostString);
  if (result != null) {
    host = result[1];
    if (result[2] != null) {
      port = result[3];
    }
  }

  return( [ host, port ] );
}

// handle a HTTP proxy request
function httpUserRequest(userRequest, userResponse) {
  var httpVersion = userRequest['httpVersion'];
  var hostport = getHostPortFromString(userRequest.headers['host'], 80);

  // have to extract the path from the requested URL
  var path = userRequest.url;
  result = /^[a-zA-Z]+:\/\/[^\/]+(\/.*)?$/.exec(userRequest.url);
  if (result) {
    if (result[1].length > 0) {
      path = result[1];
    } else {
      path = "/";
    }
  }

  var options = {
    'host': hostport[0],
    'port': hostport[1],
    'method': userRequest.method,
    'path': path,
    'agent': userRequest.agent,
    'auth': userRequest.auth,
    'headers': userRequest.headers
  };

  var proxyRequest = http.request(
    options,
    function (proxyResponse) {
      userResponse.writeHead(proxyResponse.statusCode, proxyResponse.headers);

      proxyResponse.on('data', function (chunk) {
          userResponse.write(chunk);
        }
      );

      proxyResponse.on('end',
        function () {
          userResponse.end();
        }
      );
    }
  );

  proxyRequest.on('error', function (error) {
      userResponse.writeHead(500);
      userResponse.write(
        "<h1>500 Error</h1>\r\n<p>Error was <pre>" + error + "</pre></p>\r\n</body></html>\r\n";
      );
      userResponse.end();
    }
  );

  userRequest.addListener('data', function (chunk) {
      proxyRequest.write(chunk);
    }
  );

  userRequest.addListener('end', function () {
      proxyRequest.end();
    }
  );
}

    function main() {
      var port = 5555; // default port if none on command line

      // check for any command line arguments
      for (var argn = 2; argn < process.argv.length; argn++) {
        if (process.argv[argn] === '-p') {
          port = parseInt(process.argv[argn + 1]);
          argn++;
          continue;
        }

        if (process.argv[argn] === '-d') {
          debugging = 1;
          continue;
        }
      }

      if (debugging) {
        console.log('server listening on port ' + port);
      }

      // start HTTP server with custom request handler callback function
      var server = http.createServer(httpUserRequest).listen(port);

      server.addListener('checkContinue', function (request, response){
        console.log(request);
        response.writeContinue();
      });
      // add handler for HTTPS (which issues a CONNECT to the proxy)
      server.addListener(
        'connect',
        function (request, socketRequest, bodyhead) {
          var url = request['url'];
          var httpVersion = request['httpVersion'];
          var hostport = getHostPortFromString(url, 443);

          // set up TCP connection
          var proxySocket = new net.Socket();

          proxySocket.connect(
            parseInt(hostport[1]), hostport[0],
            function () {

                  console.log("ProxySocket: " + hostport[1] + " | " + hostport[0]);
                  proxySocket.write(bodyhead);

              // tell the caller the connection was successfully established
              socketRequest.write("HTTP/" + httpVersion + " 200 Connection established\r\n\r\n");
            }
          );

          proxySocket.on('data', function (chunk) {
              socketRequest.write(chunk);
            }
          );

          proxySocket.on('end', function () {
              socketRequest.end();
            }
          );

          socketRequest.on('data', function (chunk) {
              proxySocket.write(chunk);
            }
          );

          socketRequest.on('end', function () {
              proxySocket.end();
            }
          );

          proxySocket.on('error', function (err) {
              socketRequest.write("HTTP/" + httpVersion + " 500 Connection error\r\n\r\n");
              socketRequest.end();
            }
          );

          socketRequest.on('error', function (err) {
              proxySocket.end();
        }
          );
        }
      ); // HTTPS connect listener
    }

    main();

最佳答案

你问的是

http://expressjs.com/4x/api.html#req.secure req.secure -> https

http://expressjs.com/4x/api.html#req.protocol 请求协议(protocol) -> http

http://expressjs.com/4x/api.html#req.host 请求主机

请求.url

这都应该在您的用户请求中

我可能没有正确理解你的问题。

关于windows - 支持 https 的 Node.js 代理服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22619773/

相关文章:

python - 设置环境变量以用于 getenv(不是 GetEnvironmentVariable)

java - 如果我的批处理文件路径中有空格,为什么会出现错误?

node.js - Nodejs 和express 找不到公共(public)文件夹

java - 建议Windows环境下的Java Web Host

python - 错误 : No module named 'fcntl'

node.js - 将 REST API 访问限制为仅访问我的网站

node.js - NodeJS v12 重新启用 TLS 1.1 和 1.0

ruby-on-rails - Ruby on Rails - 如何通过 HTTPS 和基本身份验证保存远程文件

django over https 表单重定向问题

java - 从基于 Glassfish 的 Web-AP 访问 HTTPS Web 服务