allproxy
Version:
AllProxy: MITM HTTP Debugging Tool.
187 lines • 7.91 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const SocketIoMessage_1 = __importDefault(require("./SocketIoMessage"));
const Global_1 = __importDefault(require("./Global"));
const Message_1 = require("../../common/Message");
const fs_1 = __importDefault(require("fs"));
const SocketIoManager_1 = require("./SocketIoManager");
const BoolFilter_1 = __importDefault(require("../../common/BoolFilter"));
const ConsoleLog_1 = __importDefault(require("./ConsoleLog"));
const exec = require('child_process').exec;
class LogProxy {
constructor(proxyConfig) {
this.retry = true;
this.TIMEOUT = 5000;
//RECORD_LIMIT = 50;
this.recordCount = 0;
this.buffer = '';
this.proxyConfig = proxyConfig;
this.command = proxyConfig.path;
this.boolFilter = new BoolFilter_1.default(proxyConfig.hostname);
if (this.command.length > 0) {
this.start();
}
}
static destructor(proxyConfig) {
if (proxyConfig.logProxyProcess) {
try {
const proc = proxyConfig.logProxyProcess;
proc.stdout.removeAllListeners();
proc.stderr.removeAllListeners();
proc.removeAllListeners();
proc.kill('SIGINT');
}
catch (e) {
console.error(e);
}
}
}
start() {
return __awaiter(this, void 0, void 0, function* () {
LogProxy.destructor(this.proxyConfig);
this.retry = true;
const home = process.env.HOME ? '$HOME' : '%USERPROFILE%';
this.command = this.command.replace(home, process.env.HOME);
if (fs_1.default.existsSync(this.command)) {
this.command = 'cat ' + this.command;
}
ConsoleLog_1.default.debug('LogProxy:start', this.command);
const tokens = this.command.split(' ');
// cat of entire log file?
if (tokens[0].trim() === 'cat' && tokens.length === 2) {
function delay() {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => {
setTimeout(() => resolve(true), 50);
});
});
}
// Read the entire file and process each record...
const buffer = fs_1.default.readFileSync(tokens[1]);
for (const record of buffer.toString().split('\n')) {
if (this.boolFilter.isFiltered(record))
continue;
const queueCount = yield this.processLogRecord(record);
if (queueCount >= SocketIoManager_1.BATCH_SIZE * 2) {
yield delay();
}
}
return;
}
let proc = exec(this.command);
this.proxyConfig.logProxyProcess = proc; // save so we can kill process
const startTime = Date.now();
proc.stdout.on('data', (buffer) => {
if (warmUpCompleted()) {
for (const record of buffer.toString().split('\n')) {
if (this.boolFilter.isFiltered(record))
continue;
this.processLogRecord(record);
}
}
});
proc.stderr.on('data', (buffer) => {
if (warmUpCompleted()) {
for (const record of buffer.toString().split('\n')) {
if (this.boolFilter.isFiltered(record))
continue;
this.processLogRecord(record);
}
}
});
proc.on('error', (error) => {
console.error(`error: ${error} - ${this.command}`);
});
proc.on('exit', (_rc) => {
proc.stdout.removeAllListeners();
proc.stderr.removeAllListeners();
proc.removeAllListeners();
if (this.retry) {
setTimeout(() => this.start(), 10000); // Retry in 10 seconds
this.retry = false;
}
});
const warmUpCompleted = () => {
return this.command.indexOf('tail ') !== -1 ? Date.now() > startTime + 3000 : true;
};
});
}
processLogRecord(record) {
return __awaiter(this, void 0, void 0, function* () {
let queueCount = 0;
if (this.timerHandle) {
clearInterval(this.timerHandle);
}
record = record.trim();
if (record.length === 0) {
return 0;
}
// Look for embedded JSON object
let nonJson = '';
if (!record.startsWith('{') && !record.startsWith('[')) {
const i = record.indexOf('{');
if (i !== -1) {
try {
const json = JSON.parse(record.substring(i));
nonJson = record.substring(0, i) + ' ';
record = JSON.stringify(json);
}
catch (e) { }
}
}
let json;
try {
json = JSON.parse(record);
}
catch (e) { }
if (json) {
const title = record.split('\n')[0];
queueCount = yield this.emitToBrowser(nonJson + title, json, Date.now());
}
else {
const title = record.split('\n')[0];
queueCount = yield this.emitToBrowser(title, record, Date.now());
}
return queueCount;
});
}
emitToBrowser(title, data, timeMsec) {
return __awaiter(this, void 0, void 0, function* () {
const seqNo = Global_1.default.nextSequenceNumber();
const message = yield SocketIoMessage_1.default.buildRequest(Date.now(), seqNo, {}, // headers
'', // method
title, // url
'', // endpoint
{ allproxy_inner_body: this.command }, // req body
'', // 'log:' + title, // clientIp
'', // serverHost
'', // path
0);
let elapsedTime = 0;
// if (timeMsec && this.prevTimeMsec) {
// elapsedTime = timeMsec - this.prevTimeMsec;
// }
SocketIoMessage_1.default.appendResponse(message, {}, // res headers
data, 0, // status
elapsedTime // elapsed time
);
this.prevTimeMsec = timeMsec;
message.protocol = 'log:';
return Global_1.default.socketIoManager.emitMessageToBrowser(Message_1.MessageType.REQUEST_AND_RESPONSE, message, this.proxyConfig);
});
}
}
exports.default = LogProxy;
//# sourceMappingURL=LogProxy.js.map