我正在开发一个 node.js
代理服务器应用程序,我希望它支持 HTTP
和 HTTPS(SSL)
协议(protocol)(作为服务器)。
我目前正在使用 node-http-proxy
像这样:
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
代理,并在我的应用)。你能帮我怎么做吗?
PS:
如果我订阅 httpProxy
服务器对象的 upgrade
事件,我可以获得请求,但我不知道如何转发请求并将响应发送给客户端:
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
});
任何帮助将不胜感激。
最佳答案
解决方案几乎不存在,而且文档充其量只能在一台服务器上支持 both。这里的诀窍是了解客户端代理配置可能会将 https 请求发送到 http 代理服务器。如果您指定 HTTP 代理,然后选中“所有协议(protocol)相同”,则对于 Firefox 也是如此。
您可以通过监听“connect”事件来处理发送到 HTTP 服务器的 https 连接。请注意,您将无法访问连接事件的响应对象,只能访问套接字和 bodyhead。作为代理服务器,通过此套接字发送的数据将保持加密状态。
在此解决方案中,您不必制作自己的证书,因此不会出现证书冲突。流量只是被代理,不会被截获并用不同的证书重写。
// 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\r\n\r\n");
}
);
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\r\n\r\n");
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 代理服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8165570/