UNPKG

whistle

Version:

HTTP, HTTP2, HTTPS, Websocket debugging proxy

99 lines (93 loc) 3.48 kB
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; var LOG_ID_RE = /^log:\/\/(\{[^\s]{1,36}\}|[^/\\{}()<>\s]{1,36})$/; 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 = ''; var isValue; if (LOG_ID_RE.test(log.matcher)) { logId = RegExp.$1; if (logId[0] === '{') { logId = logId.slice(1, -1); isValue = true; } try { logId = encodeURIComponent(logId); } catch (e) {} } util.getRuleValue( logId && !isValue ? null : log, function (script) { topScript = topScript.replace('$LOG_ID', 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); } }); } };