Skip to content

Commit

Permalink
Merge branch '3.10.3beta1' into 'master'
Browse files Browse the repository at this point in the history
Add test cases for the proxy, and do some tiny fixes.

the fixes are:
1. add "content-type" in headers for when dealing with localresponse
2. make a more accurate tip for throttle rate when lower than 1
3. make the crtMgr funcionality a more independent one
4. uppercase the request header before sending it out

update the tip

See merge request !2
  • Loading branch information
codingfishman committed Aug 31, 2016
2 parents a925cbe + e489e18 commit 530491d
Show file tree
Hide file tree
Showing 31 changed files with 1,954 additions and 193 deletions.
6 changes: 6 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"presets": [
"es2015",
"stage-0"
]
}
245 changes: 245 additions & 0 deletions .eslintrc.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ coverage
.grunt
build/Release
node_modules
.lock-wscript
.lock-wscript
temp
12 changes: 12 additions & 0 deletions jasmine.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"spec_dir": "test",
"spec_files": [
"**/*[sS]pec.js"
],
"helpers": [
"../node_modules/babel-register/lib/node.js",
"../node_modules/babel-polyfill/dist/polyfill.js"
],
"stopSpecOnExpectationFailure": false,
"random": false
}
229 changes: 68 additions & 161 deletions lib/certMgr.js
Original file line number Diff line number Diff line change
@@ -1,174 +1,81 @@
var exec = require('child_process').exec,
spawn = require('child_process').spawn,
path = require("path"),
fs = require("fs"),
os = require("os"),
color = require('colorful'),
readline = require('readline'),
util = require('./util'),
logUtil = require("./log"),
certGenerator = require("./certGenerator"),
asyncTask = require("async-task-mgr");

var isWin = /^win/.test(process.platform),
certDir = path.join(util.getUserHome(),"/.anyproxy_certs/"),
rootCAcrtFilePath = path.join(certDir,"rootCA.crt"),
rootCAkeyFilePath = path.join(certDir,"rootCA.key"),
createCertTaskMgr = new asyncTask();

if(!fs.existsSync(certDir)){
try{
fs.mkdirSync(certDir,0777);
}catch(e){
logUtil.printLog("===========", logUtil.T_ERR);
logUtil.printLog("failed to create cert dir ,please create one by yourself - " + certDir, logUtil.T_ERR);
logUtil.printLog("this error will not block main thread unless you use https-related features in anyproxy", logUtil.T_ERR);
logUtil.printLog("===========", logUtil.T_ERR);
}
}

var cache_rootCACrtFileContent, cache_rootCAKeyFileContent;
function getCertificate(hostname,certCallback){
checkRootCA();
var keyFile = path.join(certDir , "__hostname.key".replace(/__hostname/,hostname) ),
crtFile = path.join(certDir , "__hostname.crt".replace(/__hostname/,hostname) );

if(!cache_rootCACrtFileContent || !cache_rootCAKeyFileContent){
cache_rootCACrtFileContent = fs.readFileSync(rootCAcrtFilePath, {encoding: 'utf8'});
cache_rootCAKeyFileContent = fs.readFileSync(rootCAkeyFilePath, {encoding: 'utf8'});
}

createCertTaskMgr.addTask(hostname,function(callback){
if(!fs.existsSync(keyFile) || !fs.existsSync(crtFile)){
try{
var result = certGenerator.generateCertsForHostname(hostname, {
cert: cache_rootCACrtFileContent,
key: cache_rootCAKeyFileContent
});
fs.writeFileSync(keyFile, result.privateKey);
fs.writeFileSync(crtFile, result.certificate);
callback(null, result.privateKey, result.certificate);

}catch(e){
callback(e);
}
}else{
callback(null , fs.readFileSync(keyFile) , fs.readFileSync(crtFile));
var logUtil = require('./log');
var util = require('./util');
var color = require('colorful');
var EasyCert = require('node-easy-cert');
var exec = require('child_process').exec;
var path = require('path');
var readline = require('readline');

var isWin = /^win/.test(process.platform);
var options = {
rootDirPath: util.getUserHome() + '/.anyproxy_certs',
defaultCertAttrs: [
{ name: 'countryName', value: 'CN' },
{ name: 'organizationName', value: 'AnyProxy' },
{ shortName: 'ST', value: 'SH' },
{ shortName: 'OU', value: 'AnyProxy SSL Proxy' }
]
};

var easyCert = new EasyCert(options);
var crtMgr = util.merge({}, easyCert);

// catch specified error, such as ROOT_CA_NOT_EXISTS
crtMgr.getCertificate = function (host, cb) {
easyCert.getCertificate(host, (error, keyContent, crtContent) => {
if (error === 'ROOT_CA_NOT_EXISTS') {
util.showRootInstallTip();
process.exit(0);
return;
}

},function(err,keyContent,crtContent){
if(!err){
certCallback(null ,keyContent,crtContent);
}else{
certCallback(err);
}
});
}

function createCert(hostname,callback){
checkRootCA();

var cmd = cmd_genCert + " __host __path".replace(/__host/,hostname).replace(/__path/,certDir);
exec(cmd,{ cwd : certDir },function(err,stdout,stderr){
if(err){
callback && callback(new Error("error when generating certificate"),null);
}else{
var tipText = "certificate created for __HOST".replace(/__HOST/,hostname);
logUtil.printLog(color.yellow(color.bold("[internal https]")) + color.yellow(tipText)) ;
callback(null);
}
cb(error, keyContent, crtContent);
});
}

function clearCerts(cb){
if(isWin){
exec("del * /q",{cwd : certDir},cb);
}else{
exec("rm *.key *.csr *.crt *.srl",{cwd : certDir},cb);
}
}

function isRootCAFileExists(){
return (fs.existsSync(rootCAcrtFilePath) && fs.existsSync(rootCAkeyFilePath));
}

var rootCAExists = false;
function checkRootCA(){
if(rootCAExists) return;
if(!isRootCAFileExists()){
logUtil.printLog(color.red("can not find rootCA.crt or rootCA.key"), logUtil.T_ERR);
logUtil.printLog(color.red("you may generate one by the following methods"), logUtil.T_ERR);
logUtil.printLog(color.red("\twhen using globally : anyproxy --root"), logUtil.T_ERR);
logUtil.printLog(color.red("\twhen using as a module : require(\"anyproxy\").generateRootCA();"), logUtil.T_ERR);
logUtil.printLog(color.red("\tmore info : https://github.com/alibaba/anyproxy/wiki/How-to-config-https-proxy"), logUtil.T_ERR);
process.exit(0);
} else{
rootCAExists = true;
}
}

function generateRootCA(){

if(isRootCAFileExists()){
logUtil.printLog(color.yellow("rootCA exists at " + certDir));
var rl = readline.createInterface({
input : process.stdin,
output: process.stdout
});

rl.question("do you really want to generate a new one ?)(yes/NO)", function(answer) {
if(/yes/i.test(answer)){
startGenerating();
}else{
logUtil.printLog("will not generate a new one");
process.exit(0);
};

// set default common name of the cert
crtMgr.generateRootCA = function (cb) {
doGenerate(false);

function doGenerate(overwrite) {
const rootOptions = {
commonName: 'AnyProxy',
overwrite: !!overwrite
};

easyCert.generateRootCA(rootOptions, (error, keyPath, crtPath) => {
if (!error) {
const certDir = path.dirname(keyPath);
logUtil.printLog(color.cyan('The cert is generated at "' + certDir + '"'));
if(isWin){
exec("start .",{ cwd : certDir });
}else{
exec("open .",{ cwd : certDir });
}
}

rl.close();
});
}else{
startGenerating();
}

function startGenerating(){
//clear old certs
clearCerts(function(){
logUtil.printLog(color.green("temp certs cleared"));
try{
var result = certGenerator.generateRootCA();
fs.writeFileSync(rootCAkeyFilePath, result.privateKey);
fs.writeFileSync(rootCAcrtFilePath, result.certificate);
if (error === 'ROOT_CA_EXISTED') {
var rl = readline.createInterface({
input : process.stdin,
output: process.stdout
});

logUtil.printLog(color.green("rootCA generated"));
logUtil.printLog(color.green(color.bold("please trust the rootCA.crt in " + certDir)));
logUtil.printLog(color.green(color.bold("or you may get it via anyproxy webinterface")));
rl.question("do you really want to generate a new one ?)(yes/NO)", function(answer) {
if(/yes/i.test(answer)){
doGenerate(true);
}else{
console.log("will not generate a new one");

if(isWin){
exec("start .",{cwd : certDir});
}else{
exec("open .",{cwd : certDir});
}
}
rl.close();
});

}catch(e){
logUtil.printLog(color.red(e));
logUtil.printLog(color.red(e.stack));
logUtil.printLog(color.red("fail to generate root CA"),logUtil.T_ERR);
return;
}
cb(error, keyPath, crtPath);
});
}
}

function getRootCAFilePath(){
if(isRootCAFileExists()){
return rootCAcrtFilePath;
}else{
return "";
}
}
};

module.exports.getRootCAFilePath = getRootCAFilePath;
module.exports.generateRootCA = generateRootCA;
module.exports.getCertificate = getCertificate;
module.exports.createCert = createCert;
module.exports.clearCerts = clearCerts;
module.exports.isRootCAFileExists = isRootCAFileExists;
module.exports = crtMgr;
Loading

0 comments on commit 530491d

Please sign in to comment.