mirror of
https://github.com/avwo/whistle.git
synced 2026-10-29 07:06:36 +08:00
80 lines
3.0 KiB
JavaScript
80 lines
3.0 KiB
JavaScript
var fs = require('fs');
|
|
var path = require('path');
|
|
var Transform = require('pipestream').Transform;
|
|
var util = require('../util');
|
|
var config = require('../config');
|
|
var logScriptFile = path.join(config.ASSESTS_PATH, 'js/log.js');
|
|
var logScript = fs.readFileSync(logScriptFile, { encoding: 'utf8' });
|
|
var logScriptTag = '<script>' + logScript + '</script>\r\n';
|
|
var logHtmlScript = '<!DOCTYPE html>\r\n' + logScriptTag;
|
|
|
|
function wrapScript(script, isHtml) {
|
|
return isHtml
|
|
? '\r\n<script>' + script + '</script>\r\n'
|
|
: '\r\n' + script + '\r\n';
|
|
}
|
|
|
|
function getScript(host, isHtml, req, noDoctype) {
|
|
host = util.getInternalHost(req, host);
|
|
var logCgiPath =
|
|
config.WEBUI_PATH + 'log.' + config.port + '/cgi-bin/log/set';
|
|
var result = isHtml ? (noDoctype ? logScriptTag : logHtmlScript) : logScript;
|
|
var baseUrl = (req.isHttps ? 'https://' : 'http://') + host;
|
|
return result.replace('$BASE_URL', baseUrl).replace('$LOG_CGI', logCgiPath);
|
|
}
|
|
|
|
module.exports = function (req, res) {
|
|
var log = req.rules.log;
|
|
if (log) {
|
|
util.disableReqCache(req.headers);
|
|
var host = req.headers.host;
|
|
delete req.rules.log;
|
|
res.on('src', function (_res) {
|
|
if (!(log = req.rules.log) || !util.hasBody(_res)) {
|
|
return;
|
|
}
|
|
var topScript, isHtml;
|
|
if (util.supportHtmlTransform(_res, req)) {
|
|
isHtml = true;
|
|
topScript = getScript(host, isHtml, req, util.isDisable(req, 'logDoctype'));
|
|
} else if (util.getContentType(_res.headers) == 'JS') {
|
|
topScript = getScript(host, isHtml, req, util.isDisable(req, 'logDoctype'));
|
|
}
|
|
|
|
if (topScript) {
|
|
var enable = req.enable;
|
|
topScript = topScript.split('$INTERCEPT_CONSOLE').join(!req.disable.interceptConsole || !!enable.interceptConsole);
|
|
!util.isEnable(req, 'keepAllCSP') && util.disableCSP(_res.headers);
|
|
!req._customCache && util.disableResStore(_res.headers);
|
|
var userScript;
|
|
var transform = new Transform();
|
|
var added;
|
|
transform._transform = function (chunk, _, callback) {
|
|
if (!added) {
|
|
added = true;
|
|
var logId = util.removeProtocol(log.matcher, true);
|
|
util.getRuleValue(!logId || /^[^/\\{}()<>]+$/.test(logId) ? null : log, function (script) {
|
|
topScript = topScript.replace('$LOG_ID', logId && util.encodeURIComponent(logId));
|
|
var buf = [util.toBuffer(topScript)];
|
|
userScript = script || null;
|
|
if (userScript) {
|
|
userScript = util.toBuffer(wrapScript(userScript, isHtml));
|
|
if (isHtml || !chunk) {
|
|
buf.push(userScript);
|
|
userScript = null;
|
|
}
|
|
}
|
|
chunk && buf.push(chunk);
|
|
callback(null, Buffer.concat(buf));
|
|
}, null, null, null, req);
|
|
} else {
|
|
callback(null, chunk || userScript);
|
|
}
|
|
};
|
|
|
|
res.addZipTransform(transform, false, true);
|
|
}
|
|
});
|
|
}
|
|
};
|