add replaceServerResDataAsync

This commit is contained in:
加里 2014-10-21 11:18:55 +08:00
parent 025a6803ea
commit c6c2355d17
12 changed files with 78 additions and 159 deletions

View File

@ -157,9 +157,10 @@ module.exports = {
//replace the response from the server before it's sent to the user //replace the response from the server before it's sent to the user
//you may return either a Buffer or a string //you may return either a Buffer or a string
//serverResData is a Buffer, you may get its content by calling serverResData.toString() //serverResData is a Buffer, you may get its content by calling serverResData.toString()
replaceServerResData: function(req,res,serverResData){ replaceServerResDataAsync: function(req,res,serverResData,callback){
return serverResData; callback(serverResData);
}, },
//replaceServerResData is deprecated
//在请求返回给用户前的延迟时间 //在请求返回给用户前的延迟时间
//add a pause before sending response to user //add a pause before sending response to user

View File

@ -1,122 +0,0 @@
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'),
asyncTask = require("async-task-mgr");
var certDir = path.join(util.getUserHome(),"/.anyproxy_certs/"),
cmdDir = path.join(__dirname,"..","./cert/"),
asyncTaskMgr = new asyncTask();
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(cb){
createCert(hostname,function(err){
cb(err ? err : null);
});
},function(err){
if(!err){
cb(null , fs.readFileSync(keyFile) , fs.readFileSync(crtFile) );
}else{
cb(err);
}
});
}else{
cb(null , fs.readFileSync(keyFile) , fs.readFileSync(crtFile) );
}
}
function createCert(hostname,callback){
console.log(hostname);
checkRootCA();
var cmd = "./gen-cer __host __path".replace(/__host/,hostname).replace(/__path/,certDir);
exec(cmd,{ cwd : cmdDir },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);
console.log(color.yellow(color.bold("[internal https]")) + color.yellow(tipText));
callback(null);
}
});
}
function clearCerts(cb){
exec("rm *.key *.csr *.crt",{cwd : certDir},cb);
}
function isRootCAFileExists(){
var crtFile = path.join(cmdDir,"rootCA.crt"),
keyFile = path.join(cmdDir,"rootCA.key");
return (fs.existsSync(crtFile) && fs.existsSync(keyFile));
}
function checkRootCA(){
if(!isRootCAFileExists()){
console.log(color.red("can not find rootCA.crt or rootCA.key"));
console.log(color.red("you may generate one by the following methods"));
console.log(color.red("\twhen using globally : anyproxy --root"));
console.log(color.red("\twhen using as a module : require(\"anyproxy\").generateRootCA();"));
process.exit(0);
}
}
function generateRootCA(){
if(isRootCAFileExists()){
console.log(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{
console.log("will not generate a new one");
process.exit(0);
}
rl.close();
});
}else{
startGenerating();
}
function startGenerating(){
var spawnSteam = spawn("./gen-rootCA",['.'],{cwd:cmdDir,stdio: 'inherit'});
spawnSteam.on('close', function (code) {
if(code == 0){
console.log(color.green("rootCA generated"));
console.log(color.green(color.bold("please trust the rootCA.crt in " + cmdDir)));
clearCerts(function(){
console.log(color.green("temp certs cleared"));
process.exit(0);
});
}else{
console.log(color.red("fail to generate root CA"));
}
});
}
}
module.exports.generateRootCA = generateRootCA;
module.exports.getCertificate = getCertificate;
module.exports.createCert = createCert;
module.exports.clearCerts = clearCerts;
module.exports.isRootCAFileExists = isRootCAFileExists;

View File

@ -158,8 +158,18 @@ function userRequestHandler(req,userRes){
//get custom response //get custom response
},function(callback){ },function(callback){
serverResData = userRule.replaceServerResData(req,res,serverResData) || serverResData; if(userRule.replaceServerResData){
callback(); console.log(color.red("replaceServerResData is deprecated, and will be unavilable soon. Use replaceServerResDataAsync instead."));
serverResData = userRule.replaceServerResData(req,res,serverResData) || serverResData;
callback();
}else if(userRule.replaceServerResDataAsync){
userRule.replaceServerResDataAsync(req,res,serverResData,function(newRes){
serverResData = newRes;
callback();
});
}else{
callback();
}
//delay //delay
},function(callback){ },function(callback){

View File

@ -40,8 +40,13 @@ module.exports = {
return mergeCORSHeader(req.headers, header); return mergeCORSHeader(req.headers, header);
}, },
replaceServerResData: function(req,res,serverResData){ // Deprecated
return serverResData; // replaceServerResData: function(req,res,serverResData){
// return serverResData;
// },
replaceServerResDataAsync: function(req,res,serverResData,callback){
callback(serverResData);
}, },
pauseBeforeSendingResponse : function(req,res){ pauseBeforeSendingResponse : function(req,res){

View File

@ -1,6 +1,6 @@
{ {
"name": "anyproxy", "name": "anyproxy",
"version": "2.4.7", "version": "2.5.0",
"description": "A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.", "description": "A fully configurable proxy in NodeJS, which can handle HTTPS requests perfectly.",
"main": "proxy.js", "main": "proxy.js",
"bin": { "bin": {
@ -17,6 +17,7 @@
"ip": "^0.3.2", "ip": "^0.3.2",
"juicer": "^0.6.6-stable", "juicer": "^0.6.6-stable",
"nedb": "^0.11.0", "nedb": "^0.11.0",
"qrcode-npm": "0.0.3",
"socks5-http-client": "^0.1.6", "socks5-http-client": "^0.1.6",
"socks5-https-client": "^0.2.2", "socks5-https-client": "^0.2.2",
"ws": "^0.4.32" "ws": "^0.4.32"

View File

@ -135,12 +135,16 @@ function proxyServer(option){
var configServer = new UIConfigServer(proxyConfigPort); var configServer = new UIConfigServer(proxyConfigPort);
configServer.on("rule_changed",function() { configServer.on("rule_changed",function() {
console.log(arguments); // console.log(arguments);
}) })
var tipText = "web interface started at port " + proxyWebPort; var tipText,webUrl;
webUrl = "http://" + ip.address() + ":" + proxyWebPort +"/";
tipText = "web interface started at : " + webUrl;
console.log(color.green(tipText)); console.log(color.green(tipText));
tipText = "[alpha]qr code to for iOS client: " + webUrl + "qr";
console.log(color.green(tipText));
callback(null); callback(null);
} }
], ],

View File

@ -96,10 +96,15 @@ module.exports = {
//replace the response from the server before it's sent to the user //replace the response from the server before it's sent to the user
//you may return either a Buffer or a string //you may return either a Buffer or a string
//serverResData is a Buffer, you may get its content by calling serverResData.toString() //serverResData is a Buffer, you may get its content by calling serverResData.toString()
replaceServerResData: function(req,res,serverResData){ replaceServerResDataAsync: function(req,res,serverResData,callback){
return serverResData; callback(serverResData);
}, },
//Deprecated
// replaceServerResData: function(req,res,serverResData){
// return serverResData;
// },
//在请求返回给用户前的延迟时间 //在请求返回给用户前的延迟时间
//add a pause before sending response to user //add a pause before sending response to user
pauseBeforeSendingResponse : function(req,res){ pauseBeforeSendingResponse : function(req,res){

View File

@ -3,12 +3,12 @@
module.exports = { module.exports = {
replaceServerResData: function(req,res,serverResData){ replaceServerResDataAsync: function(req,res,serverResData,callback){
//add "hello github" to all github pages //add "hello github" to all github pages
if(req.headers.host == "github.com"){ if(req.headers.host == "github.com"){
serverResData += "hello github"; serverResData += "hello github";
} }
return serverResData; callback(serverResData);
}, },
shouldInterceptHttpsReq :function(req){ shouldInterceptHttpsReq :function(req){

View File

@ -2,15 +2,15 @@
module.exports = { module.exports = {
replaceServerResData: function(req,res,serverResData){ replaceServerResDataAsync: function(req,res,serverResData,callback){
//append "hello world" to all web pages //append "hello world" to all web pages
if(/html/i.test(res.headers['content-type'])){ if(/html/i.test(res.headers['content-type'])){
var newDataStr = serverResData.toString(); var newDataStr = serverResData.toString();
newDataStr += "hello world!"; newDataStr += "hello world!";
return newDataStr; callback(newDataStr);
}else{ }else{
return serverResData; callback(serverResData);
} }
} }

View File

@ -36,9 +36,6 @@ define("./detail",['$', 'gallery/underscore/1.6.0/underscore.js'],function(requi
' <h4 class="subTitle">response body</h4>'+ ' <h4 class="subTitle">response body</h4>'+
' <div class="detail">'+ ' <div class="detail">'+
' <div class="J_responseBody resBodyContent"></div>'+ ' <div class="J_responseBody resBodyContent"></div>'+
// ' <form class="uk-form">'+
// ' <textarea class="J_responseBody">loading...</textarea>'+
// ' </form>'+
' </div>'+ ' </div>'+
' </section>'+ ' </section>'+
' <% } %>'; ' <% } %>';

View File

@ -93,7 +93,7 @@ seajs.use(['$', 'Underscore', 'Backbone',"./detail"], function($, _, Backbone,De
if(!isInApp){ if(!isInApp){
self.detailPanel.showDetail(detailData); self.detailPanel.showDetail(detailData);
}else{ }else{
window.webkit.messageHandlers.list.postMessage(JSON.stringify(detailData)) window.webkit.messageHandlers.list.postMessage(JSON.stringify(detailData));
} }
} }
}, },
@ -174,7 +174,7 @@ seajs.use(['$', 'Underscore', 'Backbone',"./detail"], function($, _, Backbone,De
var data = JSON.parse(event.data); var data = JSON.parse(event.data);
var reqDate = new Date(data.startTime); var reqDate = new Date(data.startTime);
data.startTimeStr = reqDate.toLocaleTimeString() + ""; data.startTimeStr = reqDate.format("hh:mm:ss") + "";
var previous; var previous;
if(previous = recList.get(data.id)){ if(previous = recList.get(data.id)){
@ -238,19 +238,19 @@ seajs.use(['$', 'Underscore', 'Backbone',"./detail"], function($, _, Backbone,De
})(); })();
// Date.prototype.Format = function (fmt) { });
// var o = {
// "M+": this.getMonth() + 1, //月份
// "d+": this.getDate(), //日
// "h+": this.getHours(), //小时
// "m+": this.getMinutes(), //分
// "s+": this.getSeconds(), //秒
// "q+": Math.floor((this.getMonth() + 3) / 3), //季度
// "S": this.getMilliseconds() //毫秒
// };
// if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
// for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
// return fmt;
// }
}); Date.prototype.format = function (fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}

View File

@ -6,10 +6,12 @@ var express = require("express"),
events = require("events"), events = require("events"),
inherits = require("util").inherits, inherits = require("util").inherits,
entities = require("entities"), entities = require("entities"),
qrCode = require('qrcode-npm'),
WebSocketServer = require('ws').Server; WebSocketServer = require('ws').Server;
function proxyWebServer(port,webSocketPort,proxyConfigPort,ruleSummary,ipAddress){ function proxyWebServer(port,webSocketPort,proxyConfigPort,ruleSummary,ipAddress){
var self = this; var self = this,
myAbsAddress = "http://" + ipAddress + ":" + port +"/";
if(arguments.length < 3){ if(arguments.length < 3){
throw new Error("please assign ports"); throw new Error("please assign ports");
@ -44,6 +46,22 @@ function proxyWebServer(port,webSocketPort,proxyConfigPort,ruleSummary,ipAddress
}); });
}); });
//make qr code
app.get("/qr",function(req,res){
var qr = qrCode.qrcode(4, 'M'),
targetUrl = myAbsAddress,
qrImageTag,
resDom;
qr.addData(targetUrl);
qr.make();
qrImageTag = qr.createImgTag(4);
resDom = '<a href="__url"> __img <br> click or scan qr code to start client </a>'.replace(/__url/,targetUrl).replace(/__img/,qrImageTag);
res.setHeader("Content-Type", "text/html");
res.end(resDom);
});
app.use(function(req,res,next){ app.use(function(req,res,next){
var indexHTML = fs.readFileSync(__dirname + "/web/index.html",{encoding:"utf8"}); var indexHTML = fs.readFileSync(__dirname + "/web/index.html",{encoding:"utf8"});