mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-05-10 14:58:27 +00:00
update
This commit is contained in:
parent
5e269eac91
commit
7eea58952b
7
bin.js
7
bin.js
@ -1,5 +1,5 @@
|
|||||||
var program = require('commander'),
|
var program = require('commander'),
|
||||||
mainProxy = require("./index.js");
|
mainProxy = require("./proxy.js");
|
||||||
|
|
||||||
program
|
program
|
||||||
.option('-u, --host [value]', 'hostname for https proxy, localhost for default')
|
.option('-u, --host [value]', 'hostname for https proxy, localhost for default')
|
||||||
@ -9,12 +9,11 @@ program
|
|||||||
.parse(process.argv);
|
.parse(process.argv);
|
||||||
|
|
||||||
if(program.clear){
|
if(program.clear){
|
||||||
exec("rm -rf ./cert/tmpCert",function(){
|
require("./lib/certMgr").clearCerts(function(){
|
||||||
console.log("certificates cleared");
|
console.log("all certs cleared");
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
mainProxy.startServer(program.type,program.port, program.host);
|
mainProxy.startServer(program.type,program.port, program.host);
|
||||||
|
|
||||||
}
|
}
|
17
cert/gen-cer
17
cert/gen-cer
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#Required
|
#Required
|
||||||
domain=$1
|
domain=$1
|
||||||
|
outputPath=$2
|
||||||
commonname=$domain
|
commonname=$domain
|
||||||
|
|
||||||
#Change to your company details
|
#Change to your company details
|
||||||
@ -15,7 +16,7 @@ email=a@b.com
|
|||||||
#Optional
|
#Optional
|
||||||
password=a
|
password=a
|
||||||
|
|
||||||
if [ -z "$domain" ]
|
if [ -z "$outputPath$domain" ]
|
||||||
then
|
then
|
||||||
echo "Argument not present."
|
echo "Argument not present."
|
||||||
echo "Useage $0 [common name]"
|
echo "Useage $0 [common name]"
|
||||||
@ -23,25 +24,25 @@ then
|
|||||||
exit 99
|
exit 99
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Generating key request for $domain"
|
echo "Generating key request for $outputPath$domain"
|
||||||
|
|
||||||
#Generate a key
|
#Generate a key
|
||||||
# openssl genrsa -out host.key 2048
|
# openssl genrsa -out host.key 2048
|
||||||
# openssl genrsa -des3 -out $domain.key 2048 -noout
|
# openssl genrsa -des3 -out $outputPath$domain.key 2048 -noout
|
||||||
openssl genrsa -passout pass:$password -out ./tmpCert/$domain.key 2048
|
openssl genrsa -passout pass:$password -out $outputPath$domain.key 2048
|
||||||
|
|
||||||
|
|
||||||
#Remove passphrase from the key. Comment the line out to keep the passphrase
|
#Remove passphrase from the key. Comment the line out to keep the passphrase
|
||||||
echo "Removing passphrase from key"
|
echo "Removing passphrase from key"
|
||||||
openssl rsa -in ./tmpCert/$domain.key -passin pass:$password -out ./tmpCert/$domain.key
|
openssl rsa -in $outputPath$domain.key -passin pass:$password -out $outputPath$domain.key
|
||||||
|
|
||||||
#Create the request
|
#Create the request
|
||||||
echo "Creating CSR"
|
echo "Creating CSR"
|
||||||
openssl req -new -key ./tmpCert/$domain.key -out ./tmpCert/$domain.csr -passin pass:$password \
|
openssl req -new -key $outputPath$domain.key -out $outputPath$domain.csr -passin pass:$password \
|
||||||
-subj "/C=$country/ST=$state/L=$locality/O=$organization/OU=$organizationalunit/CN=$commonname/emailAddress=$email"
|
-subj "/C=$country/ST=$state/L=$locality/O=$organization/OU=$organizationalunit/CN=$commonname/emailAddress=$email"
|
||||||
|
|
||||||
#Generating a Self-Signed Certificate
|
#Generating a Self-Signed Certificate
|
||||||
openssl x509 -req -days 365 -in ./tmpCert/$domain.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out ./tmpCert/$domain.crt
|
openssl x509 -req -days 365 -in $outputPath$domain.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out $outputPath$domain.crt
|
||||||
#-signkey ./tmpCert/$domain.key
|
#-signkey $outputPath$domain.key
|
||||||
#openssl x509 -req -in host.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out host.crt -days 365
|
#openssl x509 -req -in host.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out host.crt -days 365
|
||||||
echo "Finished"
|
echo "Finished"
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
outputPath=$1
|
||||||
|
cd $outputPath
|
||||||
openssl genrsa -out rootCA.key 2048
|
openssl genrsa -out rootCA.key 2048
|
||||||
openssl req -x509 -new -nodes -key rootCA.key -days 36500 -out rootCA.crt
|
openssl req -x509 -new -nodes -key rootCA.key -days 36500 -out rootCA.crt
|
123
index.js
123
index.js
@ -1,123 +0,0 @@
|
|||||||
var http = require('http'),
|
|
||||||
https = require('https'),
|
|
||||||
fs = require('fs'),
|
|
||||||
net = require('net'),
|
|
||||||
async = require("async"),
|
|
||||||
url = require('url'),
|
|
||||||
exec = require('child_process').exec,
|
|
||||||
serverMgr = require("./lib/serverMgr"),
|
|
||||||
createCert= require("./lib/createCert"),
|
|
||||||
program = require('commander');
|
|
||||||
|
|
||||||
var T_TYPE_HTTP = 0,
|
|
||||||
T_TYPE_HTTPS = 1,
|
|
||||||
DEFAULT_PORT = 8001,
|
|
||||||
DEFAULT_HOST = "localhost",
|
|
||||||
DEFAULT_TYPE = T_TYPE_HTTP;
|
|
||||||
|
|
||||||
var serverMgrInstance = new serverMgr(),
|
|
||||||
httpProxyServer;
|
|
||||||
|
|
||||||
function startServer(type, port, hostname){
|
|
||||||
var proxyType = /https/i.test(type || DEFAULT_TYPE) ? T_TYPE_HTTPS : T_TYPE_HTTP ,
|
|
||||||
proxyPort = port || DEFAULT_PORT,
|
|
||||||
proxyHost = hostname || DEFAULT_HOST;
|
|
||||||
|
|
||||||
async.series([
|
|
||||||
//creat server
|
|
||||||
function(callback){
|
|
||||||
if(proxyType == T_TYPE_HTTPS){
|
|
||||||
var keyFile = "./cert/tmpCert/__hostname.key".replace(/__hostname/,proxyHost),
|
|
||||||
crtFile = "./cert/tmpCert/__hostname.crt".replace(/__hostname/,proxyHost);
|
|
||||||
|
|
||||||
if(!fs.existsSync(keyFile) || !fs.existsSync(crtFile)){
|
|
||||||
createCert(proxyHost,function(){
|
|
||||||
httpProxyServer = https.createServer({
|
|
||||||
key : fs.readFileSync(keyFile),
|
|
||||||
cert: fs.readFileSync(crtFile)
|
|
||||||
},dealProxyUserHttpReq);
|
|
||||||
callback(null);
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
httpProxyServer = https.createServer({
|
|
||||||
key : fs.readFileSync(keyFile),
|
|
||||||
cert: fs.readFileSync(crtFile)
|
|
||||||
},dealProxyUserHttpReq);
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
|
||||||
httpProxyServer = http.createServer(dealProxyUserHttpReq);
|
|
||||||
callback(null);
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
function(callback){
|
|
||||||
//listen CONNECT method for https over http
|
|
||||||
httpProxyServer.on('connect',dealProxyConnectReq);
|
|
||||||
httpProxyServer.listen(proxyPort);
|
|
||||||
callback(null);
|
|
||||||
|
|
||||||
}],
|
|
||||||
|
|
||||||
//final callback
|
|
||||||
function(err,result){
|
|
||||||
if(!err){
|
|
||||||
console.log( (proxyType == T_TYPE_HTTP ? "Http" : "Https") + " proxy started at port " + proxyPort);
|
|
||||||
}else{
|
|
||||||
console.log("err when start proxy server :(");
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function dealProxyUserHttpReq(req,res){
|
|
||||||
var urlPattern = url.parse(req.url);
|
|
||||||
var options = {
|
|
||||||
hostname : urlPattern.host,
|
|
||||||
port : urlPattern.port || 80,
|
|
||||||
path : urlPattern.path,
|
|
||||||
method : req.method,
|
|
||||||
headers : req.headers
|
|
||||||
};
|
|
||||||
|
|
||||||
//forward to real server
|
|
||||||
var directReq = http.request(options,function(directRes){
|
|
||||||
res.writeHead(directRes.statusCode , directRes.headers);
|
|
||||||
directRes.pipe(res);
|
|
||||||
});
|
|
||||||
|
|
||||||
directReq.on("error",function(e){
|
|
||||||
console.log("err with request :" + req.url);
|
|
||||||
res.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
directReq.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
function dealProxyConnectReq(req, socket, head){
|
|
||||||
var hostname = req.url.split(":")[0];
|
|
||||||
|
|
||||||
//forward the https-request to local https server
|
|
||||||
serverMgrInstance.fetchPort(hostname,function(err,port){
|
|
||||||
if(!err && port){
|
|
||||||
try{
|
|
||||||
var conn = net.connect(port, 'localhost', function(){
|
|
||||||
socket.write('HTTP/' + req.httpVersion + ' 200 OK\r\n\r\n', 'UTF-8', function() {
|
|
||||||
conn.pipe(socket);
|
|
||||||
socket.pipe(conn);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}catch(e){
|
|
||||||
console.log("err when connect to local https server (__hostname)".replace(/__hostname/,hostname));//TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
}else{
|
|
||||||
console.log("err fetch HTTPS server for host:" + hostname);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.startServer = startServer;
|
|
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);
|
|
||||||
}
|
|
@ -1,8 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "http-proxy",
|
"name": "anyproxy",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "https proxy over http",
|
"description": "https proxy over http",
|
||||||
"main": "index.js",
|
"main": "proxy.js",
|
||||||
|
"bin": "bin.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"async": "~0.9.0",
|
"async": "~0.9.0",
|
||||||
"commander": "~2.3.0"
|
"commander": "~2.3.0"
|
||||||
|
94
proxy.js
Normal file
94
proxy.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
var http = require('http'),
|
||||||
|
https = require('https'),
|
||||||
|
fs = require('fs'),
|
||||||
|
net = require('net'),
|
||||||
|
async = require("async"),
|
||||||
|
url = require('url'),
|
||||||
|
exec = require('child_process').exec,
|
||||||
|
httpsServerMgr = require("./lib/httpsServerMgr"),
|
||||||
|
certMgr = require("./lib/certMgr"),
|
||||||
|
program = require('commander'),
|
||||||
|
requestHandler = require("./lib/requestHandler");
|
||||||
|
|
||||||
|
var T_TYPE_HTTP = 0,
|
||||||
|
T_TYPE_HTTPS = 1,
|
||||||
|
DEFAULT_PORT = 8001,
|
||||||
|
DEFAULT_HOST = "localhost",
|
||||||
|
DEFAULT_TYPE = T_TYPE_HTTP;
|
||||||
|
|
||||||
|
var httpsServerMgrInstance = new httpsServerMgr(),
|
||||||
|
httpProxyServer;
|
||||||
|
|
||||||
|
function startServer(type, port, hostname){
|
||||||
|
var proxyType = /https/i.test(type || DEFAULT_TYPE) ? T_TYPE_HTTPS : T_TYPE_HTTP ,
|
||||||
|
proxyPort = port || DEFAULT_PORT,
|
||||||
|
proxyHost = hostname || DEFAULT_HOST;
|
||||||
|
|
||||||
|
async.series([
|
||||||
|
|
||||||
|
//creat server
|
||||||
|
function(callback){
|
||||||
|
if(proxyType == T_TYPE_HTTPS){
|
||||||
|
httpsServerMgr.getCertificate(proxyHost,function(err,keyContent,crtContent){
|
||||||
|
if(err){
|
||||||
|
callback(err);
|
||||||
|
}else{
|
||||||
|
httpProxyServer = https.createServer({
|
||||||
|
key : keyContent,
|
||||||
|
cert: crtContent
|
||||||
|
},requestHandler);
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}else{
|
||||||
|
httpProxyServer = http.createServer(requestHandler);
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//listen CONNECT method for https over http
|
||||||
|
function(callback){
|
||||||
|
httpProxyServer.on('connect',dealProxyConnectReq);
|
||||||
|
httpProxyServer.listen(proxyPort);
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
//final callback
|
||||||
|
function(err,result){
|
||||||
|
if(!err){
|
||||||
|
console.log( (proxyType == T_TYPE_HTTP ? "Http" : "Https") + " proxy started at port " + proxyPort);
|
||||||
|
}else{
|
||||||
|
console.log("err when start proxy server :(");
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dealProxyConnectReq(req, socket, head){
|
||||||
|
var hostname = req.url.split(":")[0];
|
||||||
|
|
||||||
|
//forward the https-request to local https server
|
||||||
|
httpsServerMgrInstance.fetchPort(hostname,function(err,port){
|
||||||
|
if(!err && port){
|
||||||
|
try{
|
||||||
|
var conn = net.connect(port, 'localhost', function(){
|
||||||
|
socket.write('HTTP/' + req.httpVersion + ' 200 OK\r\n\r\n', 'UTF-8', function() {
|
||||||
|
conn.pipe(socket);
|
||||||
|
socket.pipe(conn);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}catch(e){
|
||||||
|
console.log("err when connect to local https server (__hostname)".replace(/__hostname/,hostname));//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
console.log("err fetch HTTPS server for host:" + hostname);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.startServer = startServer;
|
21
testCert.js
Normal file
21
testCert.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
var certMgr = require("./lib/certMgr");
|
||||||
|
|
||||||
|
certMgr.clearCerts(function(){
|
||||||
|
console.log(arguments);
|
||||||
|
});
|
||||||
|
|
||||||
|
certMgr.getCertificate("www.test3.com",function(){
|
||||||
|
console.log(arguments);
|
||||||
|
});
|
||||||
|
|
||||||
|
certMgr.getCertificate("www.test2.com",function(){
|
||||||
|
console.log(arguments);
|
||||||
|
});
|
||||||
|
|
||||||
|
certMgr.getCertificate("www.test3.com",function(){
|
||||||
|
console.log(arguments);
|
||||||
|
});
|
||||||
|
|
||||||
|
certMgr.getCertificate("www.test3.com",function(){
|
||||||
|
console.log(arguments);
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user