mirror of
https://github.com/alibaba/anyproxy.git
synced 2025-07-27 07:45:41 +00:00
update post body recorder
This commit is contained in:
@@ -82,6 +82,7 @@ function normalizeInfo(id,info){
|
||||
//req
|
||||
singleRecord.reqHeader = info.req.headers;
|
||||
singleRecord.startTime = info.startTime;
|
||||
singleRecord.reqBody = info.reqBody || "";
|
||||
|
||||
//res
|
||||
if(info.endTime){
|
||||
@@ -105,7 +106,6 @@ function normalizeInfo(id,info){
|
||||
singleRecord.duration = "";
|
||||
}
|
||||
|
||||
|
||||
return singleRecord;
|
||||
}
|
||||
|
||||
|
@@ -8,10 +8,12 @@ var http = require("http"),
|
||||
async = require('async'),
|
||||
color = require("colorful"),
|
||||
Buffer = require('buffer').Buffer,
|
||||
util = require("./util"),
|
||||
httpsServerMgr = require("./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){
|
||||
var host = req.headers.host,
|
||||
@@ -19,7 +21,8 @@ function userRequestHandler(req,userRes){
|
||||
path = urlPattern.path,
|
||||
protocol = (!!req.connection.encrypted && !/http:/.test(req.url)) ? "https" : "http",
|
||||
resourceInfo,
|
||||
resourceInfoId = -1;
|
||||
resourceInfoId = -1,
|
||||
reqData;
|
||||
|
||||
//record
|
||||
resourceInfo = {
|
||||
@@ -30,84 +33,113 @@ function userRequestHandler(req,userRes){
|
||||
req : req,
|
||||
startTime : new Date().getTime()
|
||||
};
|
||||
|
||||
try{
|
||||
if(GLOBAL.recorder){
|
||||
resourceInfoId = GLOBAL.recorder.appendRecord(resourceInfo);
|
||||
}catch(e){}
|
||||
}
|
||||
|
||||
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)){
|
||||
console.log("==>use local rules");
|
||||
userRule.dealLocalResponse(req,function(statusCode,resHeader,resBody){
|
||||
//get request body and route to local or remote
|
||||
async.series([fetchReqData,routeReq],function(){});
|
||||
|
||||
//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
|
||||
resourceInfo.endTime = new Date().getTime();
|
||||
resourceInfo.res = { //construct a self-defined res object
|
||||
statusCode : statusCode || "",
|
||||
headers : resHeader || {}
|
||||
headers : resHeader || {}
|
||||
}
|
||||
resourceInfo.resBody = resBody;
|
||||
resourceInfo.length = resBody.length;
|
||||
|
||||
try{
|
||||
GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
|
||||
}catch(e){}
|
||||
resourceInfo.resHeader = resHeader || {};
|
||||
resourceInfo.resBody = resBody;
|
||||
resourceInfo.length = resBody.length;
|
||||
resourceInfo.statusCode = statusCode;
|
||||
|
||||
GLOBAL.recorder && GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
|
||||
|
||||
userRes.writeHead(statusCode,resHeader);
|
||||
userRes.end(resBody);
|
||||
callback && callback();
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}else{
|
||||
console.log("==>will forward to real server by proxy");
|
||||
function dealWithRemoteResonse(callback){
|
||||
var options;
|
||||
|
||||
//modify protocol if needed
|
||||
//modify request protocol
|
||||
protocol = userRule.replaceRequestProtocol(req,protocol) || protocol;
|
||||
|
||||
var options = {
|
||||
//modify request options
|
||||
options = {
|
||||
hostname : urlPattern.hostname || req.headers.host,
|
||||
port : urlPattern.port || req.port || (/https/.test(protocol) ? 443 : 80),
|
||||
path : path,
|
||||
method : req.method,
|
||||
headers : req.headers
|
||||
};
|
||||
|
||||
//modify request 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) {
|
||||
|
||||
//deal response header
|
||||
var statusCode = res.statusCode;
|
||||
statusCode = userRule.replaceResponseStatusCode(req,res,statusCode) || statusCode;
|
||||
|
||||
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']);
|
||||
delete resHeader['content-encoding'];
|
||||
delete resHeader['content-length'];
|
||||
|
||||
userRes.writeHead(statusCode, resHeader);
|
||||
|
||||
//waiting for data
|
||||
var resData = [],
|
||||
length;
|
||||
//deal response data
|
||||
var length,
|
||||
resData = [];
|
||||
|
||||
res.on("data",function(chunk){
|
||||
resData.push(chunk);
|
||||
});
|
||||
|
||||
res.on("end",function(){
|
||||
|
||||
var serverResData,
|
||||
userCustomResData;
|
||||
var serverResData;
|
||||
|
||||
async.series([
|
||||
|
||||
@@ -125,9 +157,7 @@ function userRequestHandler(req,userRes){
|
||||
|
||||
//get custom response
|
||||
},function(callback){
|
||||
|
||||
userCustomResData = userRule.replaceServerResData(req,res,serverResData);
|
||||
serverResData = userCustomResData || serverResData;
|
||||
serverResData = userRule.replaceServerResData(req,res,serverResData) || serverResData;
|
||||
callback();
|
||||
|
||||
//delay
|
||||
@@ -152,15 +182,13 @@ function userRequestHandler(req,userRes){
|
||||
resourceInfo.resBody = serverResData;
|
||||
resourceInfo.length = serverResData.length;
|
||||
|
||||
try{
|
||||
GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
|
||||
}catch(e){}
|
||||
GLOBAL.recorder && GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
|
||||
|
||||
callback();
|
||||
}
|
||||
|
||||
],function(err,result){
|
||||
|
||||
callback && callback();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -175,7 +203,7 @@ function userRequestHandler(req,userRes){
|
||||
userRes.end();
|
||||
});
|
||||
|
||||
req.pipe(proxyReq);
|
||||
proxyReq.end(reqData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,9 +283,7 @@ function connectReqHandler(req, socket, head){
|
||||
resourceInfo.resBody = "";
|
||||
resourceInfo.length = 0;
|
||||
|
||||
try{
|
||||
GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
|
||||
}catch(e){}
|
||||
GLOBAL.recorder && GLOBAL.recorder.updateRecord(resourceInfoId,resourceInfo);
|
||||
|
||||
callback();
|
||||
}
|
||||
@@ -269,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){
|
||||
if(!newRule){
|
||||
return;
|
||||
}else{
|
||||
userRule = newRule;
|
||||
userRule = util.merge(defaultRule,newRule);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.userRequestHandler = userRequestHandler;
|
||||
module.exports.connectReqHandler = connectReqHandler;
|
||||
module.exports.setRules = setRules;
|
||||
|
||||
/*
|
||||
note
|
||||
req.url is wired
|
||||
in http server : http://www.example.com/a/b/c
|
||||
in https server : /work/alibaba
|
||||
*/
|
||||
|
@@ -1,14 +1,17 @@
|
||||
module.exports = {
|
||||
shouldUseLocalResponse : function(req){
|
||||
shouldUseLocalResponse : function(req,reqBody){
|
||||
},
|
||||
|
||||
dealLocalResponse : function(req,callback){
|
||||
dealLocalResponse : function(req,reqBody,callback){
|
||||
},
|
||||
|
||||
replaceRequestProtocol:function(req,protocol){
|
||||
},
|
||||
|
||||
replaceRequestOption : function(req,option){
|
||||
},
|
||||
|
||||
replaceRequestProtocol:function(req,protocol){
|
||||
replaceRequestData: function(req,data){
|
||||
},
|
||||
|
||||
replaceResponseStatusCode: function(req,res,statusCode){
|
||||
|
20
lib/util.js
Normal file
20
lib/util.js
Normal 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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user