我想寫代理服務器,將代理(幾乎)所有http/s請求。幾乎所有,因爲我需要一些特定的https url的catch請求,並作爲響應從hdd發送文件,而不是從web的真實迴應。Node.js代理服務器與https支持
整個解決方案應該在瀏覽器中作爲代理工作,並且必須在Windows 7上工作。我開始使用基於express.js的自己的代理。它工作得很好......但不幸的是不通過https。然後我試着用github中的幾個現有的node.js代理服務器(https://github.com/horaci/node-mitm-proxy,https://github.com/Hypermediaisobar/hyperProxy和其他幾個),但他們中的任何一個都在https環境下工作(或者我不知道如何控制它們)。
最後我在互聯網代碼(沒有鏈接到源代碼)找到某個地方,它通過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://stackoverflow.com/a/32104777/786389 – y3sh