fix conflicts

This commit is contained in:
想当当 2014-09-02 22:07:31 +08:00
commit 87f4f00ade
19 changed files with 238 additions and 287 deletions

View File

@ -29,32 +29,28 @@ How to write your own rule file
* you may learn how it works by our samples: [https://github.com/alipay-ct-wd/anyproxy/tree/master/rule_sample](https://github.com/alipay-ct-wd/anyproxy/tree/master/rule_sample) * you may learn how it works by our samples: [https://github.com/alipay-ct-wd/anyproxy/tree/master/rule_sample](https://github.com/alipay-ct-wd/anyproxy/tree/master/rule_sample)
* rule file scheme * rule file scheme
```javascript ```javascript
module.exports = { module.exports = {
/* /*
these functions are required these functions will overwrite the default ones, write your own when necessary.
you may leave their bodies blank if necessary
*/ */
//whether to intercept this request by local logic //whether to intercept this request by local logic
//if the return value is true, anyproxy will call dealLocalResponse to get response data and will not send request to remote server anymore //if the return value is true, anyproxy will call dealLocalResponse to get response data and will not send request to remote server anymore
shouldUseLocalResponse : function(req){ shouldUseLocalResponse : function(req,reqBody){
return false; if(/hello/.test(reqBody.toString())){
return true;
}else{
return false;
}
}, },
//you may deal the response locally instead of sending it to server //you may deal the response locally instead of sending it to server
//this function be called when shouldUseLocalResponse returns true //this function be called when shouldUseLocalResponse returns true
//callback(statusCode,resHeader,responseData) //callback(statusCode,resHeader,responseData)
//e.g. callback(200,{"content-type":"text/html"},"hello world") //e.g. callback(200,{"content-type":"text/html"},"hello world")
dealLocalResponse : function(req,callback){ dealLocalResponse : function(req,reqBody,callback){
//callback(statusCode,resHeader,responseData) callback(statusCode,resHeader,responseData)
},
//req is user's request sent to the proxy server
// option is how the proxy server will send request to the real server. i.e. require("http").request(option,function(){...})
//you may return a customized option to replace the original option
replaceRequestOption : function(req,option){
var newOption = option;
return newOption;
}, },
//replace the request protocol when sending to the real server //replace the request protocol when sending to the real server
@ -64,6 +60,20 @@ module.exports = {
return newProtocol; return newProtocol;
}, },
//req is user's request sent to the proxy server
//option is how the proxy server will send request to the real server. i.e. require("http").request(option,function(){...})
//you may return a customized option to replace the original option
//you should not write content-length header in options, since anyproxy will handle it for you
replaceRequestOption : function(req,option){
var newOption = option;
return newOption;
},
//replace the request body
replaceRequestData: function(req,data){
return data;
},
//replace the statusCode before it's sent to the user //replace the statusCode before it's sent to the user
replaceResponseStatusCode: function(req,res,statusCode){ replaceResponseStatusCode: function(req,res,statusCode){
var newStatusCode = statusCode; var newStatusCode = statusCode;
@ -96,6 +106,7 @@ module.exports = {
} }
}; };
``` ```
Using https features Using https features

View File

@ -82,6 +82,7 @@ function normalizeInfo(id,info){
//req //req
singleRecord.reqHeader = info.req.headers; singleRecord.reqHeader = info.req.headers;
singleRecord.startTime = info.startTime; singleRecord.startTime = info.startTime;
singleRecord.reqBody = info.reqBody || "";
//res //res
if(info.endTime){ if(info.endTime){
@ -105,7 +106,6 @@ function normalizeInfo(id,info){
singleRecord.duration = ""; singleRecord.duration = "";
} }
return singleRecord; return singleRecord;
} }

View File

@ -8,11 +8,12 @@ var http = require("http"),
async = require('async'), async = require('async'),
color = require("colorful"), color = require("colorful"),
Buffer = require('buffer').Buffer, Buffer = require('buffer').Buffer,
iconv = require('iconv-lite'), util = require("./util"),
httpsServerMgr = require("./httpsServerMgr"); httpsServerMgr = require("./httpsServerMgr");
var httpsServerMgrInstance = new httpsServerMgr(), var httpsServerMgrInstance = new httpsServerMgr(),
userRule = require("./rule_default.js"); //default rule file defaultRule = require("./rule_default.js"),
userRule = defaultRule; //init
function userRequestHandler(req,userRes){ function userRequestHandler(req,userRes){
var host = req.headers.host, var host = req.headers.host,
@ -20,7 +21,8 @@ function userRequestHandler(req,userRes){
path = urlPattern.path, path = urlPattern.path,
protocol = (!!req.connection.encrypted && !/http:/.test(req.url)) ? "https" : "http", protocol = (!!req.connection.encrypted && !/http:/.test(req.url)) ? "https" : "http",
resourceInfo, resourceInfo,
resourceInfoId = -1; resourceInfoId = -1,
reqData;
//record //record
resourceInfo = { resourceInfo = {
@ -31,84 +33,113 @@ function userRequestHandler(req,userRes){
req : req, req : req,
startTime : new Date().getTime() startTime : new Date().getTime()
}; };
if(GLOBAL.recorder){
try{
resourceInfoId = GLOBAL.recorder.appendRecord(resourceInfo); resourceInfoId = GLOBAL.recorder.appendRecord(resourceInfo);
}catch(e){} }
console.log(color.green("\nreceived request to : " + host + path)); console.log(color.green("\nreceived request to : " + host + path));
/*
req.url is wired
in http server : http://www.example.com/a/b/c
in https server : /work/alibaba
*/
if(userRule.shouldUseLocalResponse(req)){ //get request body and route to local or remote
console.log("==>use local rules"); async.series([fetchReqData,routeReq],function(){});
userRule.dealLocalResponse(req,function(statusCode,resHeader,resBody){
//get request body
function fetchReqData(callback){
var postData = [];
req.on("data",function(chunk){
postData.push(chunk);
});
req.on("end",function(){
reqData = Buffer.concat(postData);
resourceInfo.reqBody = reqData.toString();
GLOBAL.recorder && GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
callback();
});
}
//route to dealing function
function routeReq(callback){
if(userRule.shouldUseLocalResponse(req,reqData)){
console.log("==>use local rules");
dealWithLocalResponse(callback);
}else{
console.log("==>will forward to real server by proxy");
dealWithRemoteResonse(callback);
}
}
function dealWithLocalResponse(callback){
userRule.dealLocalResponse(req,reqData,function(statusCode,resHeader,resBody){
//update record info //update record info
resourceInfo.endTime = new Date().getTime(); resourceInfo.endTime = new Date().getTime();
resourceInfo.res = { //construct a self-defined res object resourceInfo.res = { //construct a self-defined res object
statusCode : statusCode || "", statusCode : statusCode || "",
headers : resHeader || {} headers : resHeader || {}
} }
resourceInfo.resBody = resBody; resourceInfo.resHeader = resHeader || {};
resourceInfo.length = resBody.length; resourceInfo.resBody = resBody;
resourceInfo.length = resBody.length;
try{ resourceInfo.statusCode = statusCode;
GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
}catch(e){} GLOBAL.recorder && GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
userRes.writeHead(statusCode,resHeader); userRes.writeHead(statusCode,resHeader);
userRes.end(resBody); userRes.end(resBody);
callback && callback();
}); });
return; return;
}
}else{ function dealWithRemoteResonse(callback){
console.log("==>will forward to real server by proxy"); var options;
//modify protocol if needed //modify request protocol
protocol = userRule.replaceRequestProtocol(req,protocol) || protocol; protocol = userRule.replaceRequestProtocol(req,protocol) || protocol;
var options = { //modify request options
options = {
hostname : urlPattern.hostname || req.headers.host, hostname : urlPattern.hostname || req.headers.host,
port : urlPattern.port || req.port || (/https/.test(protocol) ? 443 : 80), port : urlPattern.port || req.port || (/https/.test(protocol) ? 443 : 80),
path : path, path : path,
method : req.method, method : req.method,
headers : req.headers headers : req.headers
}; };
//modify request options
options = userRule.replaceRequestOption(req,options) || options; options = userRule.replaceRequestOption(req,options) || options;
//update quest data
reqData = userRule.replaceRequestData(req,reqData) || reqData;
options.headers = util.lower_keys(options.headers);
options.headers["content-length"] = reqData.length; //rewrite content length info
//send request
var proxyReq = ( /https/.test(protocol) ? https : http).request(options, function(res) { var proxyReq = ( /https/.test(protocol) ? https : http).request(options, function(res) {
//deal response header
var statusCode = res.statusCode; var statusCode = res.statusCode;
statusCode = userRule.replaceResponseStatusCode(req,res,statusCode) || statusCode; statusCode = userRule.replaceResponseStatusCode(req,res,statusCode) || statusCode;
var resHeader = userRule.replaceResponseHeader(req,res,res.headers) || res.headers; var resHeader = userRule.replaceResponseHeader(req,res,res.headers) || res.headers;
resHeader = lower_keys(resHeader); resHeader = util.lower_keys(resHeader);
/* remove gzip related header, and ungzip the content */ // remove gzip related header, and ungzip the content
var ifServerGzipped = /gzip/i.test(resHeader['content-encoding']); var ifServerGzipped = /gzip/i.test(resHeader['content-encoding']);
delete resHeader['content-encoding']; delete resHeader['content-encoding'];
delete resHeader['content-length']; delete resHeader['content-length'];
userRes.writeHead(statusCode, resHeader); userRes.writeHead(statusCode, resHeader);
//waiting for data //deal response data
var resData = [], var length,
length; resData = [];
res.on("data",function(chunk){ res.on("data",function(chunk){
resData.push(chunk); resData.push(chunk);
}); });
res.on("end",function(){ res.on("end",function(){
var serverResData;
var serverResData,
userCustomResData;
async.series([ async.series([
@ -126,9 +157,7 @@ function userRequestHandler(req,userRes){
//get custom response //get custom response
},function(callback){ },function(callback){
serverResData = userRule.replaceServerResData(req,res,serverResData) || serverResData;
userCustomResData = userRule.replaceServerResData(req,res,serverResData);
serverResData = userCustomResData || serverResData;
callback(); callback();
//delay //delay
@ -153,15 +182,13 @@ function userRequestHandler(req,userRes){
resourceInfo.resBody = serverResData; resourceInfo.resBody = serverResData;
resourceInfo.length = serverResData.length; resourceInfo.length = serverResData.length;
try{ GLOBAL.recorder && GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
}catch(e){}
callback(); callback();
} }
],function(err,result){ ],function(err,result){
callback && callback();
}); });
}); });
@ -176,7 +203,7 @@ function userRequestHandler(req,userRes){
userRes.end(); userRes.end();
}); });
req.pipe(proxyReq); proxyReq.end(reqData);
} }
} }
@ -256,9 +283,7 @@ function connectReqHandler(req, socket, head){
resourceInfo.resBody = ""; resourceInfo.resBody = "";
resourceInfo.length = 0; resourceInfo.length = 0;
try{ GLOBAL.recorder && GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
}catch(e){}
callback(); callback();
} }
@ -270,26 +295,21 @@ function connectReqHandler(req, socket, head){
}); });
} }
// {"Content-Encoding":"gzip"} --> {"content-encoding":"gzip"}
function lower_keys(obj){
for(var key in obj){
var val = obj[key];
delete obj[key];
obj[key.toLowerCase()] = val;
}
return obj;
}
function setRules(newRule){ function setRules(newRule){
if(!newRule){ if(!newRule){
return; return;
}else{ }else{
userRule = newRule; userRule = util.merge(defaultRule,newRule);
} }
} }
module.exports.userRequestHandler = userRequestHandler; module.exports.userRequestHandler = userRequestHandler;
module.exports.connectReqHandler = connectReqHandler; module.exports.connectReqHandler = connectReqHandler;
module.exports.setRules = setRules; module.exports.setRules = setRules;
/*
note
req.url is wired
in http server : http://www.example.com/a/b/c
in https server : /work/alibaba
*/

View File

@ -1,20 +1,33 @@
module.exports = { module.exports = {
shouldUseLocalResponse : function(req){ shouldUseLocalResponse : function(req,reqBody){
//intercept all options request
if(req.method == "OPTIONS"){
return true;
}else{
return false;
}
}, },
dealLocalResponse : function(req,callback){ dealLocalResponse : function(req,reqBody,callback){
if(req.method == "OPTIONS"){
callback(200,mergeCORSHeader(req.headers),"");
}
},
replaceRequestProtocol:function(req,protocol){
}, },
replaceRequestOption : function(req,option){ replaceRequestOption : function(req,option){
}, },
replaceRequestProtocol:function(req,protocol){ replaceRequestData: function(req,data){
}, },
replaceResponseStatusCode: function(req,res,statusCode){ replaceResponseStatusCode: function(req,res,statusCode){
}, },
replaceResponseHeader: function(req,res,header){ replaceResponseHeader: function(req,res,header){
return mergeCORSHeader(req.headers, header);
}, },
replaceServerResData: function(req,res,serverResData){ replaceServerResData: function(req,res,serverResData){
@ -25,4 +38,20 @@ module.exports = {
shouldInterceptHttpsReq :function(req){ shouldInterceptHttpsReq :function(req){
} }
}; };
function mergeCORSHeader(reqHeader,originHeader){
var targetObj = originHeader || {};
delete targetObj["Access-Control-Allow-Credentials"];
delete targetObj["Access-Control-Allow-Origin"];
delete targetObj["Access-Control-Allow-Methods"];
delete targetObj["Access-Control-Allow-Headers"];
targetObj["access-control-allow-credentials"] = "true";
targetObj["access-control-allow-origin"] = reqHeader['origin'] || "-___-||";
targetObj["access-control-allow-methods"] = "GET, POST, PUT";
targetObj["access-control-allow-headers"] = reqHeader['access-control-request-headers'] || "-___-||";
return targetObj;
}

20
lib/util.js Normal file
View File

@ -0,0 +1,20 @@
// {"Content-Encoding":"gzip"} --> {"content-encoding":"gzip"}
module.exports.lower_keys = function(obj){
for(var key in obj){
var val = obj[key];
delete obj[key];
obj[key.toLowerCase()] = val;
}
return obj;
}
module.exports.merge = function(baseObj, extendObj){
for(var key in extendObj){
baseObj[key] = extendObj[key];
}
return baseObj;
}

View File

@ -1,6 +1,6 @@
{ {
"name": "anyproxy", "name": "anyproxy",
"version": "2.0.0", "version": "2.1.1",
"description": "a charles/fiddler like proxy written in NodeJs, which can handle HTTPS requests and CROS perfectly.", "description": "a charles/fiddler like proxy written in NodeJs, which can handle HTTPS requests and CROS perfectly.",
"main": "proxy.js", "main": "proxy.js",
"bin": { "bin": {
@ -13,6 +13,7 @@
"commander": "~2.3.0", "commander": "~2.3.0",
"entities": "^1.1.1", "entities": "^1.1.1",
"express": "^4.8.5", "express": "^4.8.5",
"iconv-lite": "^0.4.4",
"nedb": "^0.11.0", "nedb": "^0.11.0",
"ws": "^0.4.32", "ws": "^0.4.32",
"iconv-lite": "^0.4.4" "iconv-lite": "^0.4.4"

View File

@ -15,6 +15,12 @@ var http = require('http'),
GLOBAL.recorder = new Recorder(); GLOBAL.recorder = new Recorder();
//mix some modules to global.util
try{
GLOBAL.util = {};
GLOBAL.util['iconv-lite'] = require("iconv-lite");
}catch(e){}
var T_TYPE_HTTP = 0, var T_TYPE_HTTP = 0,
T_TYPE_HTTPS = 1, T_TYPE_HTTPS = 1,
DEFAULT_PORT = 8001, DEFAULT_PORT = 8001,
@ -138,9 +144,7 @@ function startWebServer(port){
//web socket interface //web socket interface
var wss = new WebSocketServer({port: DEFAULT_WEBSOCKET_PORT}); var wss = new WebSocketServer({port: DEFAULT_WEBSOCKET_PORT});
wss.on("connection",function(ws){ wss.on("connection",function(ws){});
console.log("wss connection");
});
wss.broadcast = function(data) { wss.broadcast = function(data) {
for(var i in this.clients){ for(var i in this.clients){
this.clients[i].send(data); this.clients[i].send(data);

View File

@ -1,31 +1,26 @@
module.exports = { module.exports = {
/* /*
these functions are required these functions will overwrite the default ones, write your own when necessary.
you may leave their bodies blank if necessary
*/ */
//whether to intercept this request by local logic //whether to intercept this request by local logic
//if the return value is true, anyproxy will call dealLocalResponse to get response data and will not send request to remote server anymore //if the return value is true, anyproxy will call dealLocalResponse to get response data and will not send request to remote server anymore
shouldUseLocalResponse : function(req){ shouldUseLocalResponse : function(req,reqBody){
return false; if(/hello/.test(reqBody.toString())){
return true;
}else{
return false;
}
}, },
//you may deal the response locally instead of sending it to server //you may deal the response locally instead of sending it to server
//this function be called when shouldUseLocalResponse returns true //this function be called when shouldUseLocalResponse returns true
//callback(statusCode,resHeader,responseData) //callback(statusCode,resHeader,responseData)
//e.g. callback(200,{"content-type":"text/html"},"hello world") //e.g. callback(200,{"content-type":"text/html"},"hello world")
dealLocalResponse : function(req,callback){ dealLocalResponse : function(req,reqBody,callback){
//callback(statusCode,resHeader,responseData) callback(statusCode,resHeader,responseData)
}, },
//req is user's request sent to the proxy server
// option is how the proxy server will send request to the real server. i.e. require("http").request(option,function(){...})
//you may return a customized option to replace the original option
replaceRequestOption : function(req,option){
var newOption = option;
return newOption;
},
//replace the request protocol when sending to the real server //replace the request protocol when sending to the real server
//protocol : "http" or "https" //protocol : "http" or "https"
replaceRequestProtocol:function(req,protocol){ replaceRequestProtocol:function(req,protocol){
@ -33,6 +28,20 @@ module.exports = {
return newProtocol; return newProtocol;
}, },
//req is user's request sent to the proxy server
//option is how the proxy server will send request to the real server. i.e. require("http").request(option,function(){...})
//you may return a customized option to replace the original option
//you should not write content-length header in options, since anyproxy will handle it for you
replaceRequestOption : function(req,option){
var newOption = option;
return newOption;
},
//replace the request body
replaceRequestData: function(req,data){
return data;
},
//replace the statusCode before it's sent to the user //replace the statusCode before it's sent to the user
replaceResponseStatusCode: function(req,res,statusCode){ replaceResponseStatusCode: function(req,res,statusCode){
var newStatusCode = statusCode; var newStatusCode = statusCode;

View File

@ -1,34 +1,10 @@
//rule scheme : //rule scheme :
module.exports = { module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){ pauseBeforeSendingResponse : function(req,res){
//delay all the response for 1500ms //delay all the response for 1500ms
return 1500; return 1500;
},
shouldInterceptHttpsReq :function(req){
} }
}; };

View File

@ -2,7 +2,7 @@
// Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
module.exports = { module.exports = {
shouldUseLocalResponse : function(req){ shouldUseLocalResponse : function(req,reqBody){
//intercept all options request //intercept all options request
if(req.method == "OPTIONS"){ if(req.method == "OPTIONS"){
return true; return true;
@ -11,33 +11,16 @@ module.exports = {
} }
}, },
dealLocalResponse : function(req,callback){ dealLocalResponse : function(req,reqBody,callback){
if(req.method == "OPTIONS"){ if(req.method == "OPTIONS"){
callback(200,mergeCORSHeader(req.headers),""); callback(200,mergeCORSHeader(req.headers),"");
} }
}, },
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){ replaceResponseHeader: function(req,res,header){
return mergeCORSHeader(req.headers, header); return mergeCORSHeader(req.headers, header);
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
} }
}; };
function mergeCORSHeader(reqHeader,originHeader){ function mergeCORSHeader(reqHeader,originHeader){

View File

@ -1,24 +1,7 @@
//rule scheme : //rule scheme :
module.exports = { module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
},
replaceServerResData: function(req,res,serverResData){ replaceServerResData: function(req,res,serverResData){
//add "hello github" to all github pages //add "hello github" to all github pages
@ -28,9 +11,6 @@ module.exports = {
return serverResData; return serverResData;
}, },
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){ shouldInterceptHttpsReq :function(req){
//intercept https://github.com/ //intercept https://github.com/
//otherwise, all the https traffic will not go through this proxy //otherwise, all the https traffic will not go through this proxy

View File

@ -1,21 +1,6 @@
//rule scheme : //rule scheme :
module.exports = { module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){ replaceResponseHeader: function(req,res,header){
header = header || {}; header = header || {};
header["Cache-Control"] = "no-cache, no-store, must-revalidate"; header["Cache-Control"] = "no-cache, no-store, must-revalidate";
@ -23,17 +8,7 @@ module.exports = {
header["Expires"] = 0; header["Expires"] = 0;
return header; return header;
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
} }
}; };
function disableCacheHeader(header){ function disableCacheHeader(header){

View File

@ -1,11 +1,6 @@
//rule scheme : //rule scheme :
module.exports = { module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){ replaceRequestOption : function(req,option){
//replace request towards http://www.taobao.com //replace request towards http://www.taobao.com
@ -24,25 +19,5 @@ module.exports = {
if(option.hostname == "www.taobao.com" && option.path == "/"){ if(option.hostname == "www.taobao.com" && option.path == "/"){
option.path = "/about/"; option.path = "/about/";
} }
console.log(option);
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
} }
}; };

View File

@ -1,24 +1,6 @@
//rule scheme : //rule scheme :
module.exports = { module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
},
replaceServerResData: function(req,res,serverResData){ replaceServerResData: function(req,res,serverResData){
@ -31,11 +13,5 @@ module.exports = {
return serverResData; return serverResData;
} }
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
} }
}; };

View File

@ -1,18 +1,6 @@
//rule scheme : //rule scheme :
module.exports = { module.exports = {
shouldUseLocalResponse : function(req){
},
dealLocalResponse : function(req,callback){
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){ replaceResponseStatusCode: function(req,res,statusCode){
//redirect requests toward http://www.taobao.com/* //redirect requests toward http://www.taobao.com/*
@ -32,14 +20,5 @@ module.exports = {
} }
return header; return header;
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
} }
}; };

View File

@ -1,9 +1,9 @@
//replace all the images with local one //replace all the images with local one
var url = require("url"), var url = require("url"),
path = require("path"), path = require("path"),
fs = require("fs"), fs = require("fs"),
buffer = require("buffer"); buffer = require("buffer");
var map = [ var map = [
{ {
@ -15,7 +15,7 @@ var map = [
]; ];
module.exports = { module.exports = {
shouldUseLocalResponse : function(req){ shouldUseLocalResponse : function(req,reqBody){
var host = req.headers.host, var host = req.headers.host,
urlPattern = url.parse(req.url), urlPattern = url.parse(req.url),
path = urlPattern.path; path = urlPattern.path;
@ -45,31 +45,10 @@ module.exports = {
return false; return false;
}, },
dealLocalResponse : function(req,callback){ dealLocalResponse : function(req,reqBody,callback){
if(req.replaceLocalFile){ if(req.replaceLocalFile){
callback(200, {"content-type":"image/png"}, fs.readFileSync(req.replaceLocalFile) ); callback(200, {"content-type":"image/png"}, fs.readFileSync(req.replaceLocalFile) );
} }
},
replaceRequestOption : function(req,option){
},
replaceRequestProtocol:function(req,protocol){
},
replaceResponseStatusCode: function(req,res,statusCode){
},
replaceResponseHeader: function(req,res,header){
},
replaceServerResData: function(req,res,serverResData){
},
pauseBeforeSendingResponse : function(req,res){
},
shouldInterceptHttpsReq :function(req){
} }
}; };

View File

@ -13,6 +13,10 @@
margin: 0 5px; margin: 0 5px;
} }
.topHead .btn_disable{
color: #777;
}
.mainTableWrapper{ .mainTableWrapper{
margin-top: 0; margin-top: 0;
} }

View File

@ -9,6 +9,8 @@
<div class="topHead"> <div class="topHead">
<h1>Anyproxy</h1> <h1>Anyproxy</h1>
<a href="#" class="J_clearBtn"><span class="topBtn">Clear Logs(Ctrl+X)</span></a> <a href="#" class="J_clearBtn"><span class="topBtn">Clear Logs(Ctrl+X)</span></a>
<a href="#" class="J_statusBtn"><span class="topBtn">Stop</span></a>
<a href="#" class="J_statusBtn btn_disable"><span class="topBtn">Resume</span></a>
</div> </div>
<div class="mainTableWrapper J_mainTable"> <div class="mainTableWrapper J_mainTable">
@ -58,6 +60,13 @@
</div> </div>
</section> </section>
<section class="reqBody">
<h4 class="subTitle">request body</h4>
<div class="detail">
<p><%= reqBody %></p>
</div>
</section>
<% if(statusCode) { %> <% if(statusCode) { %>
<section class="resHeader"> <section class="resHeader">
<h4 class="subTitle">response header</h4> <h4 class="subTitle">response header</h4>

View File

@ -13,7 +13,6 @@ seajs.use(['$','Underscore' ,'Backbone'], function($, _, Backbone) {
$(function(){ $(function(){
//record detail //record detail
//backbone太麻烦了这里手写拉倒..
var DetailView = function(){ var DetailView = function(){
var self = this, var self = this,
$detailEl = $(".J_recordDetailOverlay"), $detailEl = $(".J_recordDetailOverlay"),
@ -153,13 +152,35 @@ seajs.use(['$','Underscore' ,'Backbone'], function($, _, Backbone) {
recList.reset(); recList.reset();
} }
//pause btn
var ifPause = false;
(function(){
var statusBtn = $(".J_statusBtn");
statusBtn.on("click",function(e){
e.stopPropagation();
e.preventDefault();
$(".J_statusBtn").removeClass("btn_disable");
$(this).addClass("btn_disable");
if(/stop/i.test($(this).html()) ){
ifPause = true;
}else{
ifPause = false;
}
});
})();
//data via web socket //data via web socket
var dataSocket = new WebSocket("ws://127.0.0.1:8003"); if(!WebSocket){
dataSocket.onopen = function(){ alert("WebSocket is required. Please use a modern browser.");
console.log("dataSocket open"); return;
} }
var dataSocket = new WebSocket("ws://127.0.0.1:8003");
dataSocket.onopen = function(){}
dataSocket.onmessage = function(event){ dataSocket.onmessage = function(event){
if(ifPause) return;
var data = JSON.parse(event.data); var data = JSON.parse(event.data);
var reqDate = new Date(data.startTime); var reqDate = new Date(data.startTime);