Skip to content

Commit

Permalink
Squashed 'vendor/whistle/' changes from e9bd8f6d5..466900ca9
Browse files Browse the repository at this point in the history
466900ca9 Release v2.9.86
bf5b1b754 feat: refine ui
752318062 feat: allow to custom key path of json view
1140b7aaf feat: add composer tag
ccadf20ad feat: inspect value
052a9bc76 feat: setActive
1c5216478 refactor: refine code
da42e8e2f feat: add context menu
7e57611c9 Release v2.9.85
b35bf640f feat: enable://captureStream
baa760b05 refactor: refine code
3b0ac1669 Release v2.9.85
0b1b335d7 feat: keep connection header
1f9a785de feat: show sse data
35eb591ae docs: weinre
32864722d feat: change cache size
7eb31ab03 feat: resType://sse
0d0b2c54e feat: refine capture ip request
593a25855 feat: update weinre2
f4690bc53 fix: util.join -> util.joinIpPort
62a2a5f73 Release v2.9.84
ea3ceeb96 feat: set rootCA.cer by default
01a5c2ca6 docs: add magisk
d1b8ca275 feat: refine --allowOrigin
ed8002e82 refactor: refine code
448e5108f refactor: refine code
7ffad6226 refactor: refine code
99fac19da feat: join ip&port
3ab1c53d4 Release v2.9.83
e2e4c498e refactor: refine code
55fd7fb31 feat: add --allowOrigin
f7e71df80 feat: set spwan.shell=true
8e213bf2a Release v2.9.82
5bb634a7b feat: -M dnsResolve|dnsResolve4|dnsResolve6
20e45f624 feat: add context menu
9c2c4d160 feat: enable://captureIp
8972fd507 Release v2.9.81
94a46ffb7 feat: allow to custom URL column
aa3850adb feat: refine https request by ip
e17c9415d Release v2.9.80
231e979b1 refactor: refine ui
2fccd78e8 fix: captureError
0ade5f347 refactor: refine ui
75091e9d0 refactor: refine ui
170c1edba Release v2.9.79
7d591547b fix: typo
985f2dc48 feat: allow to update root ca
a79e02219 feat: refine dark mode
cab8a9e3d Release v2.9.78
67ad15424 feat: save -> enable
73e56542b feat: disable://userLogin
1e4833a2f feat: refine accept-encoding
d1628812f Release v2.9.77
24b129c08 feat: refine locationHref://
175a31b57 feat: window.__WHISTLE_PATH_PREFIX__
d603633cc docs: update license badge
4a5a7d82a refactor: refine locationHref
284111891 docs: update README
34bea105f feat: update set-global-proxy
1188ce140 feat: update set-global-proxy
66e32beb7 Release v2.9.76
aa4fb265b Release v2.9.75
1acd9901b feat: remove q
4f002f017 feat: add locationHref
da9b88260 feat: refine resReplace
bf4cd8535 docs: locationHref
2622a22f6 feat: add locationHref
852d71351 Release v2.9.74
6ffd65223 refactor: refine ui
ebc7f6486 fix: avwo/whistle#1098
5a0630b77 refactor: refine code
4e8da23e3 Release v2.9.73
dd963b072 refactor: refine ui
5b5e1d0bf feat: add Verbatim、IPv4-first、IPv6-first options
d79d8549c feat: delete://query.xxx
785ceefa4 feat: set dns order

git-subtree-dir: vendor/whistle
git-subtree-split: 466900ca9f1e36d4151dbdc537fcf6f09bbc3471
  • Loading branch information
xcodebuild committed Oct 25, 2024
1 parent f44b686 commit e688071
Show file tree
Hide file tree
Showing 94 changed files with 2,758 additions and 1,721 deletions.
63 changes: 63 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,66 @@
# v2.9.86
1. feat: JSON View 右键菜单 `Inspect Value` 查看当前 key 对应的 Value 对象
2. feat: JSON Dialog 添加前进和后退键查看历史记录
3. feat: 通过 Whistle 构造的请求会在 Network 的 Order 里面加特殊标识

# v2.9.85
1. feat: 支持显示 sse 内容(默认只对非 gzip 及 content-length 头小于 2m 的请求生效,其它类型请求可以通过 `enable://captureStream` 强制开启)
2. fix: https://github.com/avwo/whistle-client/issues/60
3. fix: https://github.com/avwo/whistle/issues/1145

# v2.9.84
1. feat: 证书默认格式改成 cer 以适配更多机型(涉及:短链接,二维码,点击下载)
2. fix: 某些浏览器没有发送 `sec-fetch-site` 导致内部请求误判为跨域请求问题

# v2.9.83
1. fix: https://github.com/nodejs/node/issues/52681
2. fix: https://github.com/avwo/whistle/issues/1137
3. feat: 新增参数 `--allowOrigin` 用于设置允许哪些第三方页面访问 Whistle 的内部接口
4. feat: 插件的 rules.txt 文件支持引入 3 个远程规则 `@path`,之前版本只支持1个

# v2.9.82
1. feat: Overview、Inpsectors 支持自定义右键菜单
2. feat: 支持通过 `-M` `dnsResolve``dnsResolve4``dnsResolve6` 改 dns 方法
3. refactor: 优化界面,`dns.lookup` 失败使用 `dns.resolve``dns.resolve6` 重试

# v2.9.81
1. feat: 支持设置 URL 列不显示请求参数
2. feat: 域名为 IP 的 HTTPS 请求不解包

# v2.9.80
1. fix: 远程部署可能出现 `captureError` 问题
2. feat: 优化界面

# v2.9.79
1. feat: 优化 Dark 模式样式,并重新调整为默认不跟随系统的 Dark 模式
2. feat: 根证书过期后,可以通过 `w2 ca` 更新根证书

# v2.9.78
1. feat: 保留无法识别的 `accept-encoding` 请求头
2. feat: Rules 里面的规则如果未发生改变,点击 Save 也可以启用规则
3. feat: `statusCode://401` 默认会弹出输入用户名和密码的登录框,可以通过 `disable://userLogin``lineProps://disableUserLogin` 去掉登录框

# v2.9.77
1. feat: `locationHref://url``redirect://url` 自动去重
2. feat: 支持通过 `jsPrepend://` 设置 `window.__WHISTLE_PATH_PREFIX__ = '/path/to';`(可以配置规则或集成在插件) 修改 Whistle 内部路径 `/.whistle-path.5b6af7b9884e1165/` 改成 `${window.__WHISTLE_PATH_PREFIX__}/.whistle-path.5b6af7b9884e1165/`,方便通过 ngnix 转发(ngnix 可以把 `/path/to` 路径去掉再发送给 Whistle)

# v2.9.76
1. refactor: 删除所有 q 模块,解决安装告警问题

# v2.9.75
1. refactor: 优化 sse 请求的 `resReplace` 逻辑
2. fix: 界面 `Enable HTTP/2` 报错问题
3. feat: 新增 `locationHref://url``locationHref://js:url` 协议,相当于在 html 页面或 js 文件返回 `window.location.href = url`

# v2.9.74
1.fix: https://github.com/avwo/whistle/issues/1098

# v2.9.73
1. feat: 新增启动参数 `-M ipv4first|ipv6first` 用于设置 [dns.lookup的 options.order 参数](https://nodejs.org/docs/latest/api/dns.html#dnslookuphostname-options-callback)
2. feat: `localhost` 的 dns.lookup 默认使用 `ipv4first`
3. feat: Online 支持设置 `Verbatim``IPv4-first``IPv6-first`
4. feat: 支持 `delete://query.xxx` 删除请求 url 里面的参数

# v2.9.72
1. fix: socks 代理无法获取 clientIp 及 IPv6 转发问题

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[![Test coverage](https://codecov.io/gh/avwo/whistle/branch/master/graph/badge.svg?style=flat-square)](https://codecov.io/gh/avwo/whistle)
[![npm download](https://img.shields.io/npm/dm/whistle.svg?style=flat-square)](https://npmjs.org/package/whistle)
[![NPM count](https://img.shields.io/npm/dt/whistle.svg?style=flat-square)](https://www.npmjs.com/package/whistle)
[![License](https://img.shields.io/npm/l/whistle.svg?style=flat-square)](https://www.npmjs.com/package/whistle)
[![License](https://img.shields.io/aur/license/whistle?style=flat-square)](https://www.npmjs.com/package/whistle)

**Mac 或 Windows 系统推荐使用客户端版本:https://github.com/avwo/whistle-client**

Expand All @@ -29,7 +29,8 @@ Whistle 是基于 Node 实现的跨平台抓包调试工具,其主要特点:
* 项目可以自带代理规则配置并一键设置到本地 Whistle 代理,也可以通过定制插件简化操作

# 一键安装
> 已安装 `brew` 的 PC,可以省略以下 1、2 步骤,直接通过以下方式一键安装:`brew install whistle && w2 start --init`(arm64 平台尝试用 `brew install node && npm i -g whistle && w2 start --init`
> 已安装 `brew` 的 PC,可以省略以下 1、2 步骤,直接通过以下方式一键安装:`brew install whistle && w2 start --init`
1. 安装 Node(建议安装**最新的 LTS 版本**,如已安装忽略此步骤):https://nodejs.org/
2. 一键安装,在命令行执行以下命令:
``` sh
Expand Down
19 changes: 18 additions & 1 deletion assets/js/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,22 @@

return obj === undefined ? 'undefined' : obj;
}
var prefixPath;
function getPathPrefix() {
if (prefixPath) {
return prefixPath;
}
prefixPath = window.__WHISTLE_PATH_PREFIX__;
if (/^\/[\w./-]+$/.test(prefixPath) && prefixPath.length <= 128) {
var len = prefixPath.length - 1;
if (prefixPath[len] === '/') {
prefixPath = prefixPath.substring(0, len);
}
} else {
prefixPath = '';
}
return prefixPath;
}

var index = 0;
var MAX_LEN = 1024 * 56;
Expand All @@ -237,7 +253,8 @@
logStr = logStr.substring(0, percIndex);
}
}
img.src ='$LOG_CGI?id=$LOG_ID&level=' + level + '&text=' + logStr
var baseUrl = '$BASE_URL' + getPathPrefix();
img.src = baseUrl + '$LOG_CGI?id=$LOG_ID&level=' + level + '&text=' + logStr
+ '&t=' + new Date().getTime() + '&' + ++index;
var preventGC = function() {
img.onload = img.onerror = null;
Expand Down
14 changes: 12 additions & 2 deletions assets/js/weinre.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,22 @@
if (typeof window === 'undefined' || window.WeinreServerURL) {
return;
}
window.WeinreServerURL = '$WEINRE_PATH';
var prefixPath = window.__WHISTLE_PATH_PREFIX__;
if (/^\/[\w./-]+$/.test(prefixPath) && prefixPath.length <= 128) {
var len = prefixPath.length - 1;
if (prefixPath[len] === '/') {
prefixPath = prefixPath.substring(0, len);
}
} else {
prefixPath = '';
}
var baseUrl = '$BASE_URL' + prefixPath;
window.WeinreServerURL = baseUrl + '$WEINRE_PATH';
var head = document.head || document.getElementsByTagName('head')[0] || document.documentElement;
var script = document.createElement('script');
script.async = true;
script.charset = 'utf8';
script.src = '$WEINRE_URL';
script.src = baseUrl + '$WEINRE_URL';
if (head.firstChild) {
head.insertBefore(script, head.firstChild);
} else {
Expand Down
2 changes: 1 addition & 1 deletion bin/ca/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ module.exports = function(argv) {
if (!options.addr) {
var host = options.host || '127.0.0.1';
var port = options.port || util.getDefaultPort();
options.addr = { url: 'http://' + host + ':' + port + '/cgi-bin/rootca' };
options.addr = { url: 'http://' + util.joinIpPort(host, + port) + '/cgi-bin/rootca' };
}
install(options.addr);
};
18 changes: 12 additions & 6 deletions bin/plugin.js
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
var os = require('os');
var cp = require('child_process');
var fs = require('fs');
var path = require('path');
Expand Down Expand Up @@ -39,6 +38,13 @@ function getTempName(name) {
return name.join('/');
}

function formatCmdOpions(options) {
if (CMD_SUFFIX) {
options.shell = true;
}
return options;
}

function getInstallDir(argv) {
argv = argv.slice();
var result = { argv: argv };
Expand Down Expand Up @@ -87,10 +93,10 @@ function install(cmd, name, argv, ver, pluginsCache, callback) {
fs.writeFileSync(path.join(installPath, 'README.md'), RESP_URL);
argv.unshift('install', name);
pluginsCache[pkgName] = 1;
cp.spawn(cmd, argv, {
cp.spawn(cmd, argv, formatCmdOpions({
stdio: 'inherit',
cwd: installPath
}).once('exit', function(code) {
})).once('exit', function(code) {
if (code) {
removeDir(installPath);
callback();
Expand Down Expand Up @@ -248,10 +254,10 @@ exports.run = function(cmd, argv) {
}
});
process.env.PATH && newPath.push(process.env.PATH);
newPath = newPath.join(os.platform() === 'win32' ? ';' : ':');
newPath = newPath.join(CMD_SUFFIX ? ';' : ':');
process.env.PATH = newPath;
cp.spawn(cmd + CMD_SUFFIX, argv, {
cp.spawn(cmd + CMD_SUFFIX, argv, formatCmdOpions({
stdio: 'inherit',
env: process.env
});
}));
};
5 changes: 3 additions & 2 deletions bin/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ function showError(msg) {

function enableProxy(options) {
try {
var host = util.joinIpPort(options.host, options.port);
if (proxy.enableProxy(options)) {
showInfo('Setting global proxy (' + options.host + ':' + options.port + ') successful.');
showInfo('Setting global proxy (' + host + ') successful.');
} else {
showError('Failed to set global proxy (' + options.host + ':' + options.port + ').');
showError('Failed to set global proxy (' + host + ').');
}
} catch (e) {
showError(e.message);
Expand Down
12 changes: 5 additions & 7 deletions bin/status.js
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
var Q = require('q');

var util = require('./util');
var pkg = require('../package.json');
var colors = require('colors/safe');
Expand All @@ -12,13 +10,13 @@ var info = util.info;

function showAll(byStop) {
var list = readConfigList().map(function(config) {
var deferred = Q.defer();
isRunning(config.pid, function(running) {
deferred.resolve(running && config);
return new Promise(function(resolve) {
isRunning(config.pid, function(running) {
resolve(running && config);
});
});
return deferred.promise;
});
Q.all(list).then(function(confList) {
Promise.all(list).then(function(confList) {
confList = confList.filter(function(conf) {
return conf;
});
Expand Down
4 changes: 2 additions & 2 deletions bin/use.js
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function getBody(res, callback) {
var reqOptions;
function request(body, callback) {
if (!reqOptions) {
reqOptions = url.parse('http://' + (options.host || '127.0.0.1') + ':' + options.port + '/cgi-bin/rules/project');
reqOptions = url.parse('http://' + util.joinIpPort(options.host || '127.0.0.1', options.port) + '/cgi-bin/rules/project');
reqOptions.headers = {
'content-type': 'application/x-www-form-urlencoded'
};
Expand Down Expand Up @@ -193,7 +193,7 @@ module.exports = function(filepath, storage, force, isClient) {
'groupName=' + encodeURIComponent(groupName.trim())
].join('&');
request(body, function() {
info('Setting whistle' + (isClient ? ' client' : '') + ' (' + (options.host || '127.0.0.1') + ':' + port + ') rules successful.');
info('Setting whistle' + (isClient ? ' client' : '') + ' (' + util.joinIpPort(options.host || '127.0.0.1', port) + ') rules successful.');
});
};
if (force) {
Expand Down
11 changes: 6 additions & 5 deletions bin/util.js
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ var os = require('os');
var fs = require('fs');
var fse = require('fs-extra2');
var config = require('../lib/config');
var common = require('../lib/util/common');
var colors = require('colors/safe');
var path = require('path');
var createHmac = require('crypto').createHmac;

var joinIpPort = common.joinIpPort;

exports.joinIpPort = joinIpPort;
/*eslint no-console: "off"*/
var CHECK_RUNNING_CMD = process.platform === 'win32' ?
'tasklist /fi "PID eq %s" | findstr /i "node.exe"'
Expand All @@ -24,6 +28,7 @@ function isRunning(pid, callback) {

exports.isRunning = isRunning;


function getIpList() {
var ipList = [];
var ifaces = os.networkInterfaces();
Expand Down Expand Up @@ -64,10 +69,6 @@ function showKillError() {

exports.showKillError = showKillError;

function getIpHost(ip) {
return ip.indexOf(':') === -1 ? ip : '[' + ip + ']';
}

function showUsage(isRunning, options, restart) {
options = formatOptions(options);
if (isRunning) {
Expand All @@ -83,7 +84,7 @@ function showUsage(isRunning, options, restart) {
var list = options.host && typeof options.host === 'string' ? [options.host] : getIpList();
info('[i] 1. use your device to visit the following URL list, gets the ' + colors.bold('IP') + ' of the URL you can access:');
info(list.map(function(ip) {
return ' http://' + colors.bold(getIpHost(ip)) + (port && port != 80 ? ':' + port : '') + '/';
return ' http://' + colors.bold(joinIpPort(ip, port != 80 && port)) + '/';
}).join('\n'));

warn(' Note: If all the above URLs are unable to access, check the firewall settings');
Expand Down
6 changes: 4 additions & 2 deletions bin/whistle.js
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function handleEnd(err, options, restart) {
if (!options) {
return;
}
var host = options.host + ':' + options.port;
var host = util.joinIpPort(options.host, options.port);
var argv = [host];
if (options.bypass) {
argv.push('-x', options.bypass);
Expand All @@ -33,7 +33,8 @@ function showStartupInfo(err, options, debugMode, restart) {
}
if (/listen EADDRINUSE/.test(err)) {
options = util.formatOptions(options);
error('[!] Failed to bind proxy port ' + (options.host ? options.host + ':' : '') + (options.port || config.port) + ': The port is already in use');
var port = options.port || config.port;
error('[!] Failed to bind proxy port ' + (options.host ? util.joinIpPort(options.host, port) : port) + ': The port is already in use');
info('[i] Please check if ' + config.name + ' is already running, you can ' + (debugMode ? 'stop whistle with `w2 stop` first' : 'restart whistle with `w2 restart`'));
info(' or if another application is using the port, you can change the port with ' + (debugMode ? '`w2 run -p newPort`\n' : '`w2 start -p newPort`\n'));
} else if (err.code == 'EACCES' || err.code == 'EPERM') {
Expand Down Expand Up @@ -140,6 +141,7 @@ program
.option('--socksPort [socksPort]', 'set the socksv5 server port', String, undefined)
.option('--httpPort [httpPort]', 'set the http server port', String, undefined)
.option('--httpsPort [httpsPort]', 'set the https server port', String, undefined)
.option('--allowOrigin [originList]', 'list of cross origin allowed to access webui (as: a.b.c,x.y.z or *)', String, undefined)
.option('--no-global-plugins', 'do not load any globally installed plugins')
.option('--no-prev-options', 'do not reuse the previous options when restarting')
.option('--inspect [[host:]port]', 'activate inspector on host:port (127.0.0.1:9229 by default)')
Expand Down
5 changes: 5 additions & 0 deletions biz/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ module.exports = function(req, res, next) {
req.isPluginReq = true;
req._isProxyReq = true;
}
if (isWebUI) {
req.fromInternalPath = true;
var hostname = (req._fwdHost && util.parseHost(req._fwdHost)[0]) || host;
req.headers['x-whistle-origin-host'] = hostname || '*';
}
}
} else {
isWebUI = req.headers[config.WEBUI_HEAD];
Expand Down
1 change: 0 additions & 1 deletion biz/webui/cgi-bin/composer.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ module.exports = function(req, res) {
headers['sec-websocket-key'] = crypto.randomBytes(16).toString('base64');
}
} else {
headers.connection = 'close';
delete headers.upgrade;
if (!isConn && ((useH2 && (protocol === 'https:' || protocol === 'http:')) || protocol === 'h2:' || protocol === 'http2:')) {
req.body.useH2 = true;
Expand Down
5 changes: 5 additions & 0 deletions biz/webui/cgi-bin/get-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ module.exports = function(req, res) {
var data = req.query;
if (data.ids && typeof data.ids == 'string') {
data.ids = data.ids.split(',');
if (data.status && typeof data.status == 'string') {
data.status = data.status.split(',');
} else {
data.status = null;
}
} else {
data.ids = null;
}
Expand Down
4 changes: 2 additions & 2 deletions biz/webui/cgi-bin/rootca.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ var getRootCAFile = require('../../../lib/https/ca').getRootCAFile;

module.exports = function(req, res) {
var type = req.query.type;
if (type !== 'cer' && type !== 'pem') {
type = 'crt';
if (type !== 'crt' && type !== 'pem') {
type = 'cer';
}
res.download(getRootCAFile(), 'rootCA.' + type);
};
7 changes: 7 additions & 0 deletions biz/webui/cgi-bin/set-dns-order.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
var properties = require('../../../lib/rules/util').properties;
var config = require('../../../lib/config');

module.exports = function(req, res) {
properties.setDnsOrder(req.body.order);
res.json({ec: 0, order: config.dnsOrder});
};
2 changes: 2 additions & 0 deletions biz/webui/cgi-bin/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ exports.getServerInfo = function(req) {
var info = {
pid: PID,
pInfo: proc,
verbatim: config.verbatim,
dnsOrder: config.dnsOrder,
ipv6Only: config.ipv6Only,
dcc: config.disableCustomCerts,
dns: dnsOverHttps || config.dnsServer,
Expand Down
Binary file modified biz/webui/htdocs/img/qrcode-cer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added biz/webui/htdocs/img/qrcode-crt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified biz/webui/htdocs/img/qrcode-pem.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed biz/webui/htdocs/img/qrcode.png
Binary file not shown.
2 changes: 1 addition & 1 deletion biz/webui/htdocs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
</head>
<body style="overscroll-behavior-x: none;">
<div id="container" class="main"></div>
<script src="js/index.js?v=2.9.72"></script>
<script src="js/index.js?v=2.9.86"></script>
</body>
</html>
53 changes: 27 additions & 26 deletions biz/webui/htdocs/js/index.js

Large diffs are not rendered by default.

Loading

0 comments on commit e688071

Please sign in to comment.