anyproxy/lib/recorder.js

183 lines
4.9 KiB
JavaScript
Raw Normal View History

2014-08-27 17:42:42 +08:00
//start recording and share a list when required
var zlib = require('zlib'),
Datastore = require('nedb'),
util = require("util"),
2014-10-23 11:07:02 +08:00
fs = require("fs"),
events = require('events'),
2015-04-20 09:39:27 +08:00
iconv = require('iconv-lite'),
logUtil = require("./log");
2014-08-27 17:42:42 +08:00
2014-10-23 11:07:02 +08:00
//option.filename
function Recorder(option){
2014-08-27 17:42:42 +08:00
var self = this,
2014-10-23 11:07:02 +08:00
id = 1,
db;
option = option || {};
2014-10-23 13:31:44 +08:00
if(option.filename && typeof option.filename == "string"){
2014-10-23 11:07:02 +08:00
try{
if(fs.existsSync(option.filename)){
fs.writeFileSync(option.filename,""); //empty original file
}
db = new Datastore({
filename : option.filename,
autoload :true
});
db.persistence.setAutocompactionInterval(5001);
logUtil.printLog("db file : " + option.filename);
2014-10-23 11:07:02 +08:00
}catch(e){
logUtil.printLog(e, logUtil.T_ERR);
logUtil.printLog("Failed to load on-disk db file. Will use in-meomory db instead.", logUtil.T_ERR);
2014-10-23 11:07:02 +08:00
db = new Datastore();
}
}else{
//in-memory db
db = new Datastore();
}
2014-08-27 17:42:42 +08:00
self.recordBodyMap = []; // id - body
self.updateRecord = function(id,info){
if(id < 0 ) return;
var finalInfo = normalizeInfo(id,info);
db.update({_id:id},finalInfo);
self.updateRecordBody(id,info);
self.emit("update",finalInfo);
};
self.appendRecord = function(info){
if(info.req.headers.anyproxy_web_req){ //request from web interface
return -1;
}
var thisId = id++,
finalInfo = normalizeInfo(thisId,info);
db.insert(finalInfo);
self.updateRecordBody(id,info);
self.emit("update",finalInfo);
return thisId;
};
//update recordBody if exits
self.updateRecordBody =function(id,info){
if(id == -1) return;
if(!id || !info.resBody) return;
//add to body map
2015-01-28 15:33:00 +08:00
//ignore image data
if(/image/.test(info.resHeader['content-type'])){
2014-08-27 17:42:42 +08:00
self.recordBodyMap[id] = "(image)";
}else{
2015-01-28 15:33:00 +08:00
self.recordBodyMap[id] = info.resBody;
2014-08-27 17:42:42 +08:00
}
};
self.getBody = function(id){
if(id < 0){
return "";
}
return self.recordBodyMap[id] || "";
};
2015-04-20 09:39:27 +08:00
self.getBodyUTF8 = function(id,cb){
var bodyContent = self.getBody(id),
result = "";
GLOBAL.recorder.getSingleRecord(id,function(err,doc){
//check whether this record exists
if(!doc || !doc[0]){
cb(new Error("failed to find record for this id"));
return;
}
if(!bodyContent){
cb(null,result);
}
var record = doc[0],
resHeader = record['resHeader'] || {};
try{
var charsetMatch = JSON.stringify(resHeader).match(/charset="?([a-zA-Z0-9\-]+)"?/);
if(charsetMatch && charsetMatch.length > 1){
var currentCharset = charsetMatch[1].toLowerCase();
if(currentCharset != "utf-8" && iconv.encodingExists(currentCharset)){
bodyContent = iconv.decode(bodyContent, currentCharset);
}
}
}catch(e){}
cb(null,bodyContent.toString());
});
}
2015-01-28 15:33:00 +08:00
self.getSingleRecord = function(id,cb){
db.find({_id:parseInt(id)},cb);
}
2014-08-27 17:42:42 +08:00
self.getSummaryList = function(cb){
db.find({},cb);
};
2014-10-23 11:07:02 +08:00
self.db = db;
2014-08-27 17:42:42 +08:00
}
util.inherits(Recorder, events.EventEmitter);
function normalizeInfo(id,info){
var singleRecord = {};
//general
singleRecord._id = id;
singleRecord.id = id;
2014-08-27 17:42:42 +08:00
singleRecord.url = info.url;
singleRecord.host = info.host;
singleRecord.path = info.path;
singleRecord.method = info.method;
//req
singleRecord.reqHeader = info.req.headers;
singleRecord.startTime = info.startTime;
2014-09-02 14:54:45 +08:00
singleRecord.reqBody = info.reqBody || "";
2014-12-08 17:13:41 +08:00
singleRecord.protocol = info.protocol || "";
2014-08-27 17:42:42 +08:00
//res
if(info.endTime){
singleRecord.statusCode= info.statusCode;
2014-08-27 17:42:42 +08:00
singleRecord.endTime = info.endTime;
singleRecord.resHeader = info.resHeader;
2014-08-27 17:42:42 +08:00
singleRecord.length = info.length;
if(info.resHeader['content-type']){
singleRecord.mime = info.resHeader['content-type'].split(";")[0];
2014-08-27 17:42:42 +08:00
}else{
singleRecord.mime = "";
}
singleRecord.duration = info.endTime - info.startTime;
}else{
singleRecord.statusCode= "";
singleRecord.endTime = "";
singleRecord.resHeader = "";
singleRecord.length = "";
singleRecord.mime = "";
singleRecord.duration = "";
}
return singleRecord;
}
module.exports = Recorder;