node.js 中的 HTTPS 代理服务器 [英] HTTPS Proxy Server in node.js

查看:51
本文介绍了node.js 中的 HTTPS 代理服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个 node.js 代理服务器应用程序,我希望它支持 HTTPHTTPS(SSL) 协议(作为服务器).

I am developing a node.js proxy server application and I want it to support HTTP and HTTPS(SSL) protocols (as server).

我目前正在使用 node-http-proxy,如下所示:

I'm currently using node-http-proxy like this:

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

var server = httpProxy.createServer(9000, 'localhost', function(req, res, proxy) {
    console.log(req.url);
    proxy.proxyRequest(req, res);
});

http.createServer(function(req, res) {
    res.end('hello!');
}).listen(9000);

server.listen(8000);

我将我的浏览器设置为在 localhost:8000 上使用 HTTP 代理并且它工作正常.我还想捕获 HTTPS 请求(即设置我的浏览器以使用 localhost:8000 作为 HTTPS 代理,并在我的应用).你能帮我怎么做吗?

I setup my browser to use HTTP proxy on localhost:8000 and it works. I also want to catch HTTPS requests (ie. setup my browser to use localhost:8000 as HTTPS proxy as well and catch the requests in my application). Could you please help me how can I do that?

附注:

如果我订阅了 httpProxy 服务器对象的 upgrade 事件,我可以获得请求,但我不知道如何转发请求并向客户端发送响应:

If I subscribe to upgrade event of httpProxy server object I can get the requests but I don't know how to forward the request and send response to client:

server.on('upgrade', function(req, socket, head) {
    console.log(req.url);
    // I don't know how to forward the request and send the response to client
});

任何帮助将不胜感激.

推荐答案

几乎不存在此问题的解决方案,而且文档对于在一台服务器上同时支持两者 来说也很糟糕.这里的技巧是了解客户端代理配置可能会将 https 请求发送到 http 代理服务器.如果您指定一个 HTTP 代理,然后选中所有协议都相同",那么 Firefox 就是如此.

Solutions barely exist for this, and the documentation is poor at best for supporting both on one server. The trick here is to understand that client proxy configurations may send https requests to an http proxy server. This is true for Firefox if you specify an HTTP proxy and then check "same for all protocols".

您可以通过侦听connect"事件来处理发送到 HTTP 服务器的 https 连接.请注意,您将无法访问连接事件上的响应对象,只能访问套接字和 bodyhead.作为代理服务器,通过此套接字发送的数据将保持加密状态.

You can handle https connections sent to an HTTP server by listening for the "connect" event. Note that you won't have access to the response object on the connect event, only the socket and bodyhead. Data sent over this socket will remain encrypted to you as the proxy server.

在此解决方案中,您不必制作自己的证书,也不会因此产生证书冲突.流量只是被代理,不会被拦截并用不同的证书重写.

In this solution, you don't have to make your own certificates, and you won't have certificate conflicts as a result. The traffic is simply proxied, not intercepted and rewritten with different certificates.

//  Install npm dependencies first
//  npm init
//  npm install --save url@0.10.3
//  npm install --save http-proxy@1.11.1

var httpProxy = require("http-proxy");
var http = require("http");
var url = require("url");
var net = require('net');

var server = http.createServer(function (req, res) {
  var urlObj = url.parse(req.url);
  var target = urlObj.protocol + "//" + urlObj.host;

  console.log("Proxy HTTP request for:", target);

  var proxy = httpProxy.createProxyServer({});
  proxy.on("error", function (err, req, res) {
    console.log("proxy error", err);
    res.end();
  });

  proxy.web(req, res, {target: target});
}).listen(8080);  //this is the port your clients will connect to

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

var getHostPortFromString = function (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] );
};

server.addListener('connect', function (req, socket, bodyhead) {
  var hostPort = getHostPortFromString(req.url, 443);
  var hostDomain = hostPort[0];
  var port = parseInt(hostPort[1]);
  console.log("Proxying HTTPS request for:", hostDomain, port);

  var proxySocket = new net.Socket();
  proxySocket.connect(port, hostDomain, function () {
      proxySocket.write(bodyhead);
      socket.write("HTTP/" + req.httpVersion + " 200 Connection established

");
    }
  );

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

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

  proxySocket.on('error', function () {
    socket.write("HTTP/" + req.httpVersion + " 500 Connection error

");
    socket.end();
  });

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

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

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

});

这篇关于node.js 中的 HTTPS 代理服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆