mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-07-27 07:45:41 +00:00
update
This commit is contained in:
51
lib/asyncTaskMgr.js
Normal file
51
lib/asyncTaskMgr.js
Normal file
@@ -0,0 +1,51 @@
|
||||
function asyncTaskMgr(){
|
||||
var self = this;
|
||||
|
||||
self.callbackList = {
|
||||
sampleName:{
|
||||
status:0, /* 0,stopped,will not callback / 1,loading / 2,loaded */
|
||||
result:null,
|
||||
callbackList:[]
|
||||
}
|
||||
}
|
||||
|
||||
self.addTask = function(name,cb,action){
|
||||
if(self.callbackList[name]){
|
||||
var task = self.callbackList[name];
|
||||
|
||||
if(task.status == 2){ //done
|
||||
cb && cb.apply(null,task.result);
|
||||
|
||||
}else if(task.status == 1){ //pending
|
||||
task.callbackList.push(cb);
|
||||
|
||||
}else if(task.status == 0){ //stopped
|
||||
return; //do nothing
|
||||
}
|
||||
}else{
|
||||
var task;
|
||||
task = self.callbackList[name] = {
|
||||
status : 1,
|
||||
result : null,
|
||||
callbackList : [cb]
|
||||
};
|
||||
|
||||
action && action.call(null,function(){ //action应该带一个回调
|
||||
if(arguments && arguments[0] === -1){ //返回第一个参数为-1,为停止任务
|
||||
task.status = 0;
|
||||
task.callbackList = [];
|
||||
}else{
|
||||
task.result = arguments;
|
||||
task.status = 2;
|
||||
var tmpCb;
|
||||
while(tmpCb = task.callbackList.shift()){
|
||||
tmpCb && tmpCb.apply(null,task.result);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = asyncTaskMgr;
|
60
lib/certMgr.js
Normal file
60
lib/certMgr.js
Normal file
@@ -0,0 +1,60 @@
|
||||
var exec = require('child_process').exec,
|
||||
path = require("path"),
|
||||
fs = require("fs"),
|
||||
os = require("os"),
|
||||
asyncTaskMgr = require("./asyncTaskMgr");
|
||||
|
||||
var certDir = path.join(getUserHome(),"/.anyproxy_certs/"),
|
||||
asyncTaskMgr = new asyncTaskMgr();
|
||||
|
||||
if(!fs.existsSync(certDir)){
|
||||
fs.mkdirSync(certDir);
|
||||
}
|
||||
|
||||
function getCertificate(hostname,cb){
|
||||
var keyFile = path.join(certDir , "__hostname.key".replace(/__hostname/,hostname) ),
|
||||
crtFile = path.join(certDir , "__hostname.crt".replace(/__hostname/,hostname) );
|
||||
|
||||
if(!fs.existsSync(keyFile) || !fs.existsSync(crtFile)){
|
||||
asyncTaskMgr.addTask(hostname,function(err){
|
||||
if(!err){
|
||||
cb(null , fs.readFileSync(keyFile) , fs.readFileSync(crtFile) );
|
||||
}else{
|
||||
cb(err);
|
||||
}
|
||||
},function(cb){
|
||||
createCert(hostname,function(err){
|
||||
cb(err ? -1 : null);
|
||||
});
|
||||
});
|
||||
|
||||
}else{
|
||||
cb(null , fs.readFileSync(keyFile) , fs.readFileSync(crtFile) );
|
||||
}
|
||||
}
|
||||
|
||||
function getUserHome() {
|
||||
return process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
|
||||
}
|
||||
|
||||
function createCert(hostname,callback){
|
||||
console.log("creating cert for :" + hostname);
|
||||
|
||||
var cmd = "./gen-cer __host __path".replace(/__host/,hostname).replace(/__path/,certDir);
|
||||
exec(cmd,{cwd:"./cert/"},function(err,stdout,stderr){
|
||||
if(err){
|
||||
callback && callback(new Error("error when generating certificate"),null);
|
||||
}else{
|
||||
console.log("certificate created for __HOST".replace(/__HOST/,hostname));
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function clearCerts(cb){
|
||||
exec("rm *.key *.csr *.crt",{cwd : certDir},cb);
|
||||
}
|
||||
|
||||
module.exports.getCertificate = getCertificate;
|
||||
module.exports.createCert = createCert;
|
||||
module.exports.clearCerts = clearCerts;
|
@@ -1,16 +0,0 @@
|
||||
//TODO : move to the tmp/ dir
|
||||
var exec = require('child_process').exec;
|
||||
|
||||
module.exports = function(hostname,callback){
|
||||
console.log("creating cert for :" + hostname);
|
||||
|
||||
var cmd = "./gen-cer "+hostname;
|
||||
exec(cmd,{cwd:"./cert/"},function(err,stdout,stderr){
|
||||
if(err){
|
||||
callback && callback(new Error("error when generating certificate"),null);
|
||||
}else{
|
||||
console.log("certificate created for __HOST".replace(/__HOST/,hostname));
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
}
|
95
lib/httpsServerMgr.js
Normal file
95
lib/httpsServerMgr.js
Normal file
@@ -0,0 +1,95 @@
|
||||
//manage https servers
|
||||
var getPort = require('./getPort'),
|
||||
async = require("async"),
|
||||
http = require('http'),
|
||||
https = require('https'),
|
||||
fs = require('fs'),
|
||||
net = require('net'),
|
||||
url = require('url'),
|
||||
certMgr = require("./certMgr"),
|
||||
requestHandler = require("./requestHandler");
|
||||
|
||||
if(!fs.existsSync("cert/tmpCert")){
|
||||
fs.mkdirSync("cert/tmpCert");
|
||||
}
|
||||
|
||||
var DEFAULT_RELEASE_TIME = 120*1000;
|
||||
|
||||
module.exports =function(){
|
||||
var self = this;
|
||||
self.serverList = {
|
||||
/* schema sample
|
||||
"www.alipay.com":{
|
||||
port:123,
|
||||
server : serverInstance,
|
||||
lastestUse: 99999 //unix time stamp
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
//fetch a port for https server with hostname
|
||||
this.fetchPort = function(hostname,userCB){
|
||||
var serverInfo = self.serverList[hostname],
|
||||
port;
|
||||
|
||||
//server exists
|
||||
if(serverInfo){
|
||||
console.log("exists :" + hostname );
|
||||
serverInfo.lastestUse = new Date().getTime();
|
||||
port = serverInfo.port;
|
||||
userCB && userCB(null,port);
|
||||
|
||||
//create server with corresponding CA
|
||||
}else{
|
||||
console.log("creating :" + hostname );
|
||||
async.series([
|
||||
//find a clean port
|
||||
function(callback){
|
||||
getPort(function(cleanPort){
|
||||
port = cleanPort;
|
||||
callback(null,port);
|
||||
});
|
||||
}
|
||||
|
||||
//create server
|
||||
,function(callback){
|
||||
certMgr.getCertificate(hostname,function(err,keyContent,crtContent){
|
||||
var server = createHttpsServer(port,keyContent,crtContent);
|
||||
self.serverList[hostname] = {
|
||||
port : port,
|
||||
server : server,
|
||||
lastestUse : new Date().getTime()
|
||||
};
|
||||
console.log("https server @port __portNum for __HOST established".replace(/__portNum/,port).replace(/__HOST/,hostname));
|
||||
callback && callback(null,port);
|
||||
|
||||
});
|
||||
}
|
||||
],function(err,result){
|
||||
userCB && userCB(err,result[result.length - 1]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//clear servers which have been idle for some time
|
||||
setInterval(function(){
|
||||
var timeNow = new Date().getTime();
|
||||
for(var serverName in self.serverList){
|
||||
var item = self.serverList[serverName];
|
||||
if( (timeNow - item.lastestUse) > DEFAULT_RELEASE_TIME){
|
||||
item.server.close();
|
||||
delete self.serverList[serverName];
|
||||
console.log("https server released : " + serverName);
|
||||
}
|
||||
}
|
||||
|
||||
},DEFAULT_RELEASE_TIME);
|
||||
}
|
||||
|
||||
function createHttpsServer(port,keyContent,crtContent){
|
||||
return https.createServer({
|
||||
key : keyContent,
|
||||
cert: crtContent
|
||||
},requestHandler).listen(port);
|
||||
}
|
||||
|
28
lib/requestHandler.js
Normal file
28
lib/requestHandler.js
Normal file
@@ -0,0 +1,28 @@
|
||||
var http = require("http"),
|
||||
https = require("https");
|
||||
|
||||
function handler(req,userRes){
|
||||
|
||||
var ifHttps = !!req.connection.encrypted;
|
||||
|
||||
var options = {
|
||||
hostname : req.headers.host,
|
||||
port : req.port || (ifHttps ? 443 : 80),
|
||||
path : req.url,
|
||||
method : req.method,
|
||||
headers : req.headers
|
||||
};
|
||||
|
||||
var proxyReq = (ifHttps ? https : http).request(options, function(res) {
|
||||
userRes.writeHead(res.statusCode,res.headers);
|
||||
res.pipe(userRes);
|
||||
});
|
||||
|
||||
proxyReq.on("error",function(e){
|
||||
console.log("err with request :" + req.url);
|
||||
userRes.end();
|
||||
});
|
||||
proxyReq.end();
|
||||
}
|
||||
|
||||
module.exports = handler;
|
100
lib/serverMgr.js
100
lib/serverMgr.js
@@ -1,100 +0,0 @@
|
||||
//manage https servers
|
||||
var getPort = require('./getPort'),
|
||||
async = require("async"),
|
||||
http = require('http'),
|
||||
https = require('https'),
|
||||
fs = require('fs'),
|
||||
net = require('net'),
|
||||
url = require('url'),
|
||||
createCert= require("./createCert");
|
||||
|
||||
if(!fs.existsSync("cert/tmpCert")){
|
||||
fs.mkdirSync("cert/tmpCert");
|
||||
}
|
||||
|
||||
module.exports =function(){
|
||||
var self = this;
|
||||
self.serverList = {
|
||||
/* schema sample
|
||||
"www.alipay.com":{
|
||||
port:123,
|
||||
server : serverInstance
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
//fetch a port for https server with hostname
|
||||
this.fetchPort = function(hostname,userCB){
|
||||
var serverInfo = self.serverList[hostname],
|
||||
port;
|
||||
|
||||
//server exists
|
||||
if(serverInfo){
|
||||
port = serverInfo.port;
|
||||
userCB && userCB(null,port);
|
||||
|
||||
//create server with corresponding CA
|
||||
}else{
|
||||
var keyFile = "./cert/tmpCert/__hostname.key".replace(/__hostname/,hostname),
|
||||
crtFile = "./cert/tmpCert/__hostname.crt".replace(/__hostname/,hostname);
|
||||
|
||||
async.series([
|
||||
//find a clean port
|
||||
function(callback){
|
||||
getPort(function(cleanPort){
|
||||
port = cleanPort;
|
||||
callback(null,port);
|
||||
});
|
||||
},
|
||||
|
||||
//create a cert for this hostname if not exists
|
||||
function(callback){
|
||||
if(!fs.existsSync(keyFile) || !fs.existsSync(crtFile)){
|
||||
createCert(hostname,callback)
|
||||
}else{
|
||||
callback(null);
|
||||
}
|
||||
|
||||
//create server
|
||||
},function(callback){
|
||||
var server = createHttpsServer(port,keyFile,crtFile);
|
||||
self.serverList[hostname] = {
|
||||
port : port,
|
||||
server : server
|
||||
};
|
||||
console.log("https server @port __portNum for __HOST established".replace(/__portNum/,port).replace(/__HOST/,hostname));
|
||||
callback && callback(null,port);
|
||||
}
|
||||
],function(err,result){
|
||||
userCB && userCB(err,result[result.length - 1]);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createHttpsServer(port,keyFile,crtFile){
|
||||
return https.createServer({
|
||||
key : fs.readFileSync(keyFile),
|
||||
cert: fs.readFileSync(crtFile)
|
||||
},function(req,userRes){
|
||||
var options = {
|
||||
hostname: req.headers.host,
|
||||
port: req.port || 443,
|
||||
path: req.url,
|
||||
method: req.method,
|
||||
headers:req.headers
|
||||
};
|
||||
|
||||
var proxyReq = https.request(options, function(res) {
|
||||
userRes.writeHead(res.statusCode,res.headers);
|
||||
res.pipe(userRes);
|
||||
});
|
||||
|
||||
proxyReq.on("error",function(e){
|
||||
console.log("err with request :" + req.url);
|
||||
userRes.end();
|
||||
});
|
||||
proxyReq.end();
|
||||
|
||||
}).listen(port);
|
||||
}
|
Reference in New Issue
Block a user