Skip to content

Commit

Permalink
⬆️ upgrade whistle
Browse files Browse the repository at this point in the history
  • Loading branch information
xcodebuild committed Mar 1, 2021
2 parents 18cfb31 + 367fce1 commit f30e25f
Show file tree
Hide file tree
Showing 36 changed files with 357 additions and 188 deletions.
15 changes: 15 additions & 0 deletions vendor/whistle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
# v2.6.7
1. fix: https://github.com/avwo/whistle/issues/540

# v2.6.6
1. fix: 管理界面 CGI 路径可以随意拼接问题

# v2.6.5
1. fix: 部分 Node 版本可能卡死问题
2. fix: [pipe](http://wproxy.org/whistle/rules/pipe.html) 可能导致数据丢失问题

# v2.6.4
1. fix: 编辑器高亮显示插件规则的一些问题
2. feat: 本地文件替换的响应头头默认加入 `content-length` 字段,可以通过 `delete://resH.content-length` 禁用
3. feat: 支持通过 CGI 或 API 获取当前处理的请求总数

# v2.6.3
1. style: 支持预览 SVG 文件
2. feat: 支持通过 `process.on('pforkError', (info) => {})` 获取插件抛出的异常信息
Expand Down
8 changes: 7 additions & 1 deletion vendor/whistle/bin/whistle.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ function showStartupInfo(err, options, debugMode, restart) {
error(err.stack ? 'Date: ' + new Date().toLocaleString() + '\n' + err.stack : err);
}

function getName() {
if (/[/\\](\w+)$/.test(process.argv[1])) {
return RegExp.$1;
}
}

program.setConfig({
main: function(options) {
var cmd = process.argv[2];
Expand All @@ -41,7 +47,7 @@ program.setConfig({
var hash = options && options.storage && encodeURIComponent(options.storage);
return path.join(__dirname, '../index.js') + (hash ? '#' + hash + '#' : '');
},
name: config.name,
name: getName() || config.name,
version: config.version,
runCallback: function(err, options) {
if (err) {
Expand Down
3 changes: 0 additions & 3 deletions vendor/whistle/biz/webui/cgi-bin/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ exports.getServerInfo = function(req) {
var info = {
pid: PID,
pInfo: proc,
http: util.httpRequests,
ws: util.wsRequests,
tunnel: util.tunnelRequests,
version: config.version,
cmdName: config.cmdName,
hideLeftMenu: config.hideLeftMenu,
Expand Down
2 changes: 1 addition & 1 deletion vendor/whistle/biz/webui/htdocs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,6 @@
</head>
<body>
<div id="container" class="main"></div>
<script src="js/index.js?v=2.6.3"></script>
<script src="js/index.js?v=2.6.4"></script>
</body>
</html>
24 changes: 12 additions & 12 deletions vendor/whistle/biz/webui/htdocs/js/index.js

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion vendor/whistle/biz/webui/htdocs/src/js/data-center.js
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,8 @@ function setReqData(item) {
}
}
}

req._hasError = item.reqError;
res._hasError = item.resError;
req.rawHeaders = getRawHeaders(req.headers, req.rawHeaderNames);
res.rawHeaders = getRawHeaders(res.headers, res.rawHeaderNames);
res.rawTrailers = getRawHeaders(res.trailers, res.rawTrailerNames);
Expand Down
102 changes: 59 additions & 43 deletions vendor/whistle/biz/webui/htdocs/src/js/online.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ require('../css/online.css');
var $ = window.jQuery = require('jquery'); //for bootstrap
require('bootstrap/dist/js/bootstrap.js');
var React = require('react');
var ReactDOM = require('react-dom');

var Dialog = require('./dialog');
var dataCenter = require('./data-center');
Expand Down Expand Up @@ -96,6 +97,7 @@ var Online = React.createClass({
if (!server) {
return;
}
this.state.server = server;
var info = [];
var username = util.escape(server.username);
if (username) {
Expand Down Expand Up @@ -161,23 +163,28 @@ var Online = React.createClass({
var uptimeElem = dialog.find('#whistleUptime');
uptimeElem.text(util.formatTime(pInfo.uptime));
uptimeElem.parent().attr('title', pInfo.uptime);
reqElem.parent().attr('title', 'HTTP[S]: ' + info.http + '\nWS[S]: ' + info.ws + '\nTUNNEL: ' + info.tunnel);
reqElem.parent().attr('title', 'HTTP[S]: ' + pInfo.httpRequests + ' (Total: ' + pInfo.totalHttpRequests + ')'
+ '\nWS[S]: ' + pInfo.wsRequests + ' (Total: ' + pInfo.totalWsRequests + ')'
+ '\nTUNNEL: ' + pInfo.tunnelRequests + ' (Total: ' + pInfo.totalTunnelRequests + ')');
memElem.parent().attr('title', Object.keys(pInfo.memUsage).map(function(key) {
return key + ': ' + pInfo.memUsage[key];
}).join('\n'));
if (!curServerInfo || !curServerInfo.pInfo) {
reqElem.text(info.http + info.ws + info.tunnel);
reqElem.text(pInfo.httpRequests + pInfo.wsRequests + pInfo.tunnelRequests +
' (Total: ' + (pInfo.totalHttpRequests + pInfo.totalWsRequests + pInfo.totalTunnelRequests) + ')');
cpuElem.text(pInfo.cpuPercent);
memElem.text(util.getSize(pInfo.memUsage.rss));
} else {
var curPInfo = curServerInfo.pInfo;
if (pInfo.memUsage !== curPInfo.memUsage) {
memElem.text(util.getSize(pInfo.memUsage.rss));
}
var totalCount = info.http + info.ws + info.tunnel;
var totalCount = pInfo.httpRequests + pInfo.wsRequests + pInfo.tunnelRequests;
var allCount = pInfo.totalHttpRequests + pInfo.totalWsRequests + pInfo.totalTunnelRequests;
pInfo.totalCount = totalCount;
if (totalCount !== curPInfo.totalCount) {
reqElem.text(totalCount);
pInfo.allCount = allCount;
if (totalCount !== curPInfo.totalCount || allCount !== curPInfo.allCount) {
reqElem.text(totalCount + ' (Total: ' + allCount + ')');
}
if (pInfo.cpuPercent !== curPInfo.cpuPercent) {
cpuElem.text(pInfo.cpuPercent || '-');
Expand All @@ -190,48 +197,57 @@ var Online = React.createClass({
reload: function() {
location.reload();
},
render: function() {
getTitle: function(server) {
if (!server) {
return;
}
var info = [];
var server = this.state.server;
if (server) {
if (server.host) {
info.push('Host: ' + server.host);
}
if (server.pid) {
info.push('PID: ' + server.pid);
}
var port = server.realPort || server.port;
if (port) {
info.push('Port: ' + port);
}
if (server.socksPort) {
info.push('SOCKS Port: ' + server.socksPort);
}
if (server.httpPort) {
info.push('HTTP Port: ' + server.httpPort);
}
if (server.httpsPort) {
info.push('HTTPS Port: ' + server.httpsPort);
}
if (server.host) {
info.push('Host: ' + server.host);
}
if (server.pid) {
info.push('PID: ' + server.pid);
}
var port = server.realPort || server.port;
if (port) {
info.push('Port: ' + port);
}
if (server.socksPort) {
info.push('SOCKS Port: ' + server.socksPort);
}
if (server.httpPort) {
info.push('HTTP Port: ' + server.httpPort);
}
if (server.httpsPort) {
info.push('HTTPS Port: ' + server.httpsPort);
}

if (server.ipv4.length) {
info.push('IPv4:');
info.push.apply(info, addIndent(server.ipv4));
}
if (server.ipv6.length) {
info.push('IPv6:');
info.push.apply(info, addIndent(server.ipv6));
}
var pInfo = server.pInfo;
if (pInfo) {
info.push('Uptime: ' + util.formatTime(pInfo.uptime));
info.push('Requests: ' + (server.http + server.ws + server.tunnel));
pInfo.cpuPercent && info.push('CPU: ' + pInfo.cpuPercent);
info.push('Memory: ' + util.getSize(pInfo.memUsage.rss));
}
if (server.ipv4.length) {
info.push('IPv4:');
info.push.apply(info, addIndent(server.ipv4));
}
if (server.ipv6.length) {
info.push('IPv6:');
info.push.apply(info, addIndent(server.ipv6));
}
var pInfo = server.pInfo;
if (pInfo) {
info.push('Uptime: ' + util.formatTime(pInfo.uptime));
info.push('Requests: ' + (pInfo.httpRequests + pInfo.wsRequests + pInfo.tunnelRequests
+ ' (Total: ' + (pInfo.totalHttpRequests + pInfo.totalWsRequests + pInfo.totalTunnelRequests) + ')'));
pInfo.cpuPercent && info.push('CPU: ' + pInfo.cpuPercent);
info.push('Memory: ' + util.getSize(pInfo.memUsage.rss));
}
return info.join('\n');
},
setTitle: function() {
var server = dataCenter.getServerInfo() || this.state.server;
ReactDOM.findDOMNode(this.refs.onlineMenu).title = this.getTitle(server);
},
render: function() {
var server = this.state.server;
return (
<a title={info.join('\n')} draggable="false"
<a ref="onlineMenu" draggable="false" onMouseEnter={this.setTitle}
className={'w-online-menu w-online' + (server ? '' : ' w-offline')} onClick={this.showServerInfo}>
<span className="glyphicon glyphicon-stats"></span>{server ? 'Online' : 'Offline'}
<Dialog ref="confirmReload" wstyle="w-confirm-reload-dialog">
Expand Down
2 changes: 1 addition & 1 deletion vendor/whistle/biz/webui/htdocs/src/js/overview.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ var Overview = React.createClass({
<a href="https://avwo.github.io/whistle/rules/" target="_blank"><span className="glyphicon glyphicon-question-sign"></span></a>All Rules:
<label><input checked={showOnlyMatchRules} onChange={this.showOnlyMatchRules} type="checkbox" />Only show matching rules</label>
</p>
<Properties onHelp={this.onHelp} className={showOnlyMatchRules ? 'w-hide-no-value' : undefined} modal={rulesModal} title={titleModal} />
<Properties onHelp={this.onHelp} className={showOnlyMatchRules ? 'w-hide-no-value' : undefined} modal={rulesModal} title={titleModal} enableCopyValue name="Rules" />
</div>
);
}
Expand Down
28 changes: 19 additions & 9 deletions vendor/whistle/biz/webui/htdocs/src/js/properties.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,25 @@ var Properties = React.createClass({
render: function() {
var props = this.props;
var sourceText = props.enableViewSource;
var copyValue = props.enableCopyValue;
var viewSource = this.state.viewSource;
var onHelp = props.onHelp;
var modal = props.modal || {};
var title = props.title || {};
var keys = Object.keys(modal);
sourceText = sourceText && keys.map(function(name) {
var value = modal[name];
return (Array.isArray(value) ?
value.map(function(val, i) {
return name + ': ' + util.toString(val);
}).join('\n')
: name + ': ' + util.toString(value)
);
}).join('\n');
if (sourceText || copyValue) {
var result = [];
keys.forEach(function(name) {
var value = modal[name];
name = sourceText ? name + ': ' : '';
result.push(Array.isArray(value) ?
value.map(function(val) {
return name + util.toString(val);
}).join('\n') : name + util.toString(value));
});
sourceText = sourceText && result.join('\n');
copyValue = copyValue && result.join('\n').trim();
}
if (this.textStr !== sourceText) {
this.textStr = sourceText;
try {
Expand All @@ -48,6 +53,11 @@ var Properties = React.createClass({
<a onClick={this.toggle}>{ viewSource ? 'Form' : 'Text' }</a>
</div> : undefined
}
{ copyValue ?
<div className="w-textarea-bar">
<CopyBtn value={copyValue} name={props.name} />
</div> : undefined
}
{ sourceText ? (<pre className="w-properties-source">
{ sourceText.length >= 2100 ? <ExpandCollapse text={sourceText} /> : sourceText}
</pre>) : undefined }
Expand Down
23 changes: 14 additions & 9 deletions vendor/whistle/biz/webui/htdocs/src/js/protocols.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,21 @@ var allRules = allInnerRules = allInnerRules.map(function (name) {
});
allRules.splice(allRules.indexOf('filter://'), 1, 'excludeFilter://', 'includeFilter://');
allRules.push('lineProps://');
var plugins = {};
var pluginsOptions = [];

exports.setPlugins = function (pluginsState) {
var pluginsOptions = pluginsState.pluginsOptions;
var disabledPlugins = pluginsState.disabledPlugins;
plugins = {};
pluginsOptions = pluginsState.pluginsOptions;
pluginRules = [];
forwardRules = innerRules.slice();
allRules = allInnerRules.slice();

if (!pluginsState.disabledAllPlugins && !pluginsState.disabledAllRules) {
if (!pluginsState.disabledAllPlugins) {
pluginsOptions.forEach(function (plugin, i) {
if (!i) {
return;
}
var name = plugin.name;
plugins[name] = plugin;
if (!disabledPlugins[name]) {
if (!plugin.hideShortProtocol) {
forwardRules.push(name);
Expand Down Expand Up @@ -73,6 +71,16 @@ exports.getAllRules = function () {
return allRules;
};

function getPlugin(rule) {
rule = rule.substring(rule.indexOf('.') + 1);
for (var i = 0, len = pluginsOptions.length; i < len; i++) {
var plugin = pluginsOptions[i];
if (plugin.name === rule) {
return plugin;
}
}
}

var ROOT_HELP_URL = 'https://avwo.github.io/whistle/rules/';
exports.getHelpUrl = function (rule) {
if (!rule || rule === 'rule') {
Expand All @@ -99,10 +107,7 @@ exports.getHelpUrl = function (rule) {
if (PROTOCOLS.indexOf(rule) !== -1) {
return ROOT_HELP_URL + rule.replace(/^x/, '') + '.html';
}
if (pluginRules.indexOf(rule) !== -1) {
rule = rule.substring(rule.indexOf('.') + 1);
}
rule = plugins[rule];
rule= getPlugin(rule);
if (rule && rule.homepage) {
return rule.homepage;
}
Expand Down
2 changes: 1 addition & 1 deletion vendor/whistle/biz/webui/htdocs/src/js/res-detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ var ResDetail = React.createClass({
headersStr = ['HTTP/' + (modal.req.httpVersion || '1.1'), status, util.getStatusMessage(res)].join(' ')
+ '\r\n' + headersStr;
raw = headersStr + '\r\n\r\n' + body;
var rawType = util.getRawType(headers);
var rawType = !modal.resError && util.getRawType(headers);
var type = util.getContentType(rawType);
isJson = type === 'JSON';
// 对 SVG 做特殊处理, 利用 base64 ,图片标签展示 svg 元素
Expand Down
2 changes: 1 addition & 1 deletion vendor/whistle/biz/webui/htdocs/src/js/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -1095,7 +1095,7 @@ function initData(data, isReq) {
delete data.text;
}
}
if (!data.base64) {
if (!data.base64 || data._hasError) {
return;
}
}
Expand Down
4 changes: 4 additions & 0 deletions vendor/whistle/biz/webui/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var proxyEvent, util, pluginMgr;
var MAX_AGE = 60 * 60 * 24 * 3;
var MENU_HTML = fs.readFileSync(path.join(__dirname, '../../../assets/menu.html'));
var MENU_URL = '???_WHISTLE_PLUGIN_EXT_CONTEXT_MENU_' + config.port + '???';
var UP_PATH_REGEXP = /(?:^|[\\/])\.\.(?:[\\/]|$)/;

function doNotCheckLogin(req) {
var path = req.path;
Expand Down Expand Up @@ -179,6 +180,9 @@ app.use(function(req, res, next) {
});

function cgiHandler(req, res) {
if (UP_PATH_REGEXP.test(req.path)) {
return res.status(403).end('Forbidden');
}
if (req.headers.origin) {
res.setHeader('access-control-allow-origin', req.headers.origin);
res.setHeader('access-control-allow-credentials', true);
Expand Down
Loading

0 comments on commit f30e25f

Please sign in to comment.