我正在尝试编写将代理(几乎)所有http / s请求的代理服务器。几乎所有因为我需要捕获某些特定https网址的请求,并且响应从hdd发送文件而不是来自网络的真实响应。
整个解决方案应该在浏览器中充当代理,并且必须在Windows 7上工作。我从基于express.js的我自己的代理开始。它工作得很好......但不幸的是没有通过https。然后我试图使用几个来自github(https://github.com/horaci/node-mitm-proxy,https://github.com/Hypermediaisobar/hyperProxy和其他少数几个的现有node.js代理服务器,但其中任何一个都在https上的windows环境中工作(或者我不知道如何他们)。
最后,我发现互联网代码中的某个地方(没有源代码链接)通过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();
答案 0 :(得分:0)
http://expressjs.com/4x/api.html#req.secure req.secure - &gt; HTTPS
http://expressjs.com/4x/api.html#req.protocol req.protocol - &gt; HTTP
http://expressjs.com/4x/api.html#req.host req.host
req.url
这应该都在你的userRequest上
我可能没有正确理解你的问题。
答案 1 :(得分:0)
只需添加以下行: var https = require('https'); 当您定期发出http请求时,请使用http.request,对于ssl请求,请使用https.request。