2011-11-17 105 views
17

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

我目前使用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); 

设置我的浏览器使用HTTP代理上localhost:8000和它的作品。我也想抓HTTPS请求(即设置我的浏览器使用localhost:8000作为HTTPS代理以及捕获我的应用程序中的请求)。你能帮我吗我该怎么做?

PS

如果我订阅upgrade事件httpProxy服务器对象的我能得到请求,但我不知道如何将请求转发和发送响应客户端:

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 
}); 

任何帮助,将不胜感激。

回答

2

node-http-proxy文档包含此示例。请在https://github.com/nodejitsu/node-http-proxy处寻找“从HTTPS接近HTTPS”每个浏览器的配置过程略有不同。有些可以选择使用所有协议的代理设置;有些需要单独配置SSL代理。

7

我创建了一个HTTP/HTTPS代理与http-proxy模块的帮助:https://gist.github.com/ncthis/6863947

守则截至目前:

var fs = require('fs'), 
    http = require('http'), 
    https = require('https'), 
    httpProxy = require('http-proxy'); 

var isHttps = true; // do you want a https proxy? 

var options = { 
    https: { 
    key: fs.readFileSync('key.pem'), 
    cert: fs.readFileSync('key-cert.pem') 
    } 
}; 

// this is the target server 
var proxy = new httpProxy.HttpProxy({ 
    target: { 
    host: '127.0.0.1', 
    port: 8080 
    } 
}); 

if (isHttps) 
    https.createServer(options.https, function(req, res) { 
    console.log('Proxying https request at %s', new Date()); 
    proxy.proxyRequest(req, res); 
    }).listen(443, function(err) { 
    if (err) 
     console.log('Error serving https proxy request: %s', req); 

    console.log('Created https proxy. Forwarding requests from %s to %s:%s', '443', proxy.target.host, proxy.target.port); 
    }); 
else 
    http.createServer(options.https, function(req, res) { 
    console.log('Proxying http request at %s', new Date()); 
    console.log(req); 
    proxy.proxyRequest(req, res); 
    }).listen(80, function(err) { 
    if (err) 
     console.log('Error serving http proxy request: %s', req); 

    console.log('Created http proxy. Forwarding requests from %s to %s:%s', '80', proxy.target.host, proxy.target.port); 
    }); 
+1

该要点的链接已过时。我已经更新到https://gist.github.com/ncthis/6863947 – david

+1

@david再次过时 – fidev

+0

'httpProxy.HttpProxy不是函数' –

15

解决方案几乎不存在这一点,和文档是穷人充其量用于在一台服务器上支持。这里的技巧是了解客户端代理配置可能会将https请求发送到http代理服务器。如果您指定一个HTTP代理,然后选中“对所有协议相同”,那么对于Firefox来说就是这样。

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

在此解决方案中,您不必制作自己的证书,因此不会有证书冲突。流量只是被代理,不会被截取并被不同的证书重写。

// Install npm dependencies first 
// npm init 
// npm install --save [email protected] 
// npm install --save [email protected] 

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(); 
    }); 

}); 
+0

爱你的例子。我想知道你怎么可以增加它来处理websocket升级连接 – lzc

+0

@ y3sh你会请检查我的问题在这里http://stackoverflow.com/questions/43908640/node-js-http-proxy-with-https?我认为你的例子可以帮助我,但我不知道如何实现它.. – Valip

+0

我如何添加用户和密码认证,以便我只转发来自我和我的动态IP地址的请求? – koampapapa

相关问题