大量更新内容 - #693
Open
8odream wants to merge 29 commits into
Open
Conversation
- feat(gui): 新增流量监控页面,adblock 零 IP 与已拦截域名不计入错误统计 - feat(core): 支持 DEV_SIDECAR_LOG_DISABLED 完全关闭日志,设置页增加开关 - feat(overwall): 服务器支持 ID 标识,可按域名选择目标服务器 - feat(speed): 测速过滤零 IP,等待 Cloudflare 路由就绪后执行 - fix(gui): 修复安装后任务栏图标仍为 Electron 默认图标(signAndEditExecutable 改为 true,确保写入 exe 图标与版本信息) - fix(build): 平台原生可选依赖声明为直接依赖,修复安装后 sysproxy/shutdown-handler 模块缺失 - fix(proxy): DS-Proxy-Request 响应头改用实际上游路径 - fix(system-proxy): 优化系统代理开关与恢复逻辑 - chore(script): 统一 dev.ps1 启停/检查脚本 内容使用DeepSeekV4Pro0813 high+DSH完成
- feat(interceptor): 新增 retry 拦截器,收到 500 或连接失败时自动重试,支持缓存小请求体 - fix(proxy): 子资源错误页改为 text/plain,避免浏览器 ORB 拦截;错误日志精简 rOptions 输出 - feat(sni): sni 配置为空字符串时关闭上游 SNI 发送 - feat(cloudflareRoute): 预设 IP 优先级最高不参与重定向;新增 blacklist/whitelist 模式与域名名单 - fix(speed): 请求失败后从存活 IP 列表移除失败 IP,后续请求与重试自动切换 - feat(server): 新增按域名 TLS 版本设置 tlsVersionMapping,支持远程下发后用户自行启用 - feat(gui): 加速服务页新增 TLS 版本设置 UI,并为 Cloudflare 路由重定向增加模式与域名名单 UI
修复更新检查证书校验失败
Co-authored-by: 8odream <87055981+8odream@users.noreply.github.com>
Co-authored-by: 8odream <87055981+8odream@users.noreply.github.com>
Co-authored-by: 8odream <87055981+8odream@users.noreply.github.com>
0816 update
修复dns回传问题
cute-omega
reviewed
Aug 19, 2026
cute-omega
reviewed
Aug 21, 2026
Collaborator
There was a problem hiding this comment.
cute-omega
reviewed
Aug 21, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
This PR expands proxy retries, DNS/TLS and Cloudflare routing, traffic monitoring, GUI monitoring pages, and system proxy/logging workflows.
Changes:
- Added retry handling, TLS mapping, IP failover, and Cloudflare routing.
- Added traffic and GitHub status monitoring pages.
- Refactored startup, system proxy, npm environment, logging, and update flows.
Reviewed changes
Copilot reviewed 56 out of 57 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Reviewed change / final comment |
|---|---|
pnpm-workspace.yaml |
Dependency overrides. Critical (3 votes): Removing overrides may reintroduce vulnerable transitive versions; retain safe overrides or regenerate the lockfile safely. |
packages/mitmproxy/test/ipv6nettest.js |
IPv6 test. Moderate (2): Force address family 6. Critical (3): External 6.ipw.cn access can make default tests fail in offline or IPv4-only CI. Nit (2): Remove the unused setTimeout import. |
packages/mitmproxy/test/ipv6-test.mjs |
IPv6/DNS test updates. |
packages/mitmproxy/test/dnsDefaultLookupTest.mjs |
DNS regression test. Nit (2): dnsModulePath is unused; cache deletion uses dnsLookupModulePath. |
packages/mitmproxy/src/lib/traffic/TrafficMonitor.js |
Traffic statistics and aggregation. |
packages/mitmproxy/src/lib/traffic/processResolver.js |
Connection process resolution. |
packages/mitmproxy/src/lib/speed/SpeedTester.js |
Speed testing and IP failover. Moderate (2): CNAME preferred addresses are rejected by IP-only lookup; use the IP resolved by rewriteIp(). |
packages/mitmproxy/src/lib/speed/index.js |
Speed and routing coordination. |
packages/mitmproxy/src/lib/speed/config.js |
Speed configuration. |
packages/mitmproxy/src/lib/proxy/mitmproxy/index.js |
Traffic monitoring and process-resolution integration. |
packages/mitmproxy/src/lib/proxy/mitmproxy/dnsLookup.js |
DNS and Cloudflare address handling. |
packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js |
Retry handling and error responses. Critical (3): Unknown-length bodies can bypass the 1 MiB limit and be buffered without bounds. Critical (2): Request-controlled values are inserted unescaped into HTML, enabling reflected XSS. |
packages/mitmproxy/src/lib/proxy/mitmproxy/createConnectHandler.js |
CONNECT handling and connection-error recording. |
packages/mitmproxy/src/lib/proxy/middleware/overwall.js |
Overwall middleware updates. |
packages/mitmproxy/src/lib/proxy/common/util.js |
TLS version mapping. |
packages/mitmproxy/src/lib/interceptor/index.js |
Interceptor registration. |
packages/mitmproxy/src/lib/interceptor/impl/req/sni.js |
SNI request handling. |
packages/mitmproxy/src/lib/interceptor/impl/req/retry.js |
New retry interceptor. |
packages/mitmproxy/src/lib/dns/util.ip.js |
IP utility updates. |
packages/mitmproxy/src/lib/dns/tls.js |
TLS DNS utilities. |
packages/mitmproxy/src/lib/dns/tcp.js |
TCP DNS utilities. |
packages/mitmproxy/src/lib/cloudflareRoute.js |
Cloudflare preferred routing. |
packages/mitmproxy/src/index.js |
Proxy package integration. |
packages/gui/src/view/router/menu.js |
Added GUI menu entries. |
packages/gui/src/view/router/index.js |
Registered new routes. |
packages/gui/src/view/pages/traffic.vue |
Traffic monitoring page. |
packages/gui/src/view/pages/setting.vue |
Logging controls. |
packages/gui/src/view/pages/server.vue |
TLS, speed, and Cloudflare configuration. |
packages/gui/src/view/pages/plugin/overwall.vue |
Overwall settings. |
packages/gui/src/view/pages/plugin/node.vue |
npm plugin settings. |
packages/gui/src/view/pages/index.vue |
Plugin and startup UI updates. |
packages/gui/src/view/pages/github-status.vue |
GitHub status page. |
packages/gui/src/view/components/container.vue |
GUI container updates. |
packages/gui/src/utils/util.log-env.js |
Log-disable initialization. Moderate (3): Only config.json is read, ignoring the config.json5 fallback and JSON5 parsing. |
packages/gui/src/bridge/update/front.js |
Update bridge frontend. |
packages/gui/src/bridge/update/backend.js |
Update matching and downloads. Critical (1): ARM fallback can select an x64 incremental package; do not match x64 increments for ARM. |
packages/gui/src/bridge/api/backend.js |
GUI IPC backend API. |
packages/gui/src/background.js |
Startup, icon, and configuration handling. |
packages/gui/package.json |
GUI package metadata. |
packages/gui/electron-builder.config.cjs |
Electron build resources. |
packages/core/test/instanceTest.js |
Core instance tests. |
packages/core/src/utils/util.logger.js |
Logging controls. |
packages/core/src/utils/util.log-or-console.js |
Logging output behavior. |
packages/core/src/shell/scripts/set-system-proxy/index.js |
System proxy and environment handling. Critical (1): Shutdown deletes existing registry values without saving them; preserve and restore prior values. |
packages/core/src/shell/scripts/set-system-env.js |
System environment handling. |
packages/core/src/modules/server/index.js |
Proxy server lifecycle. |
packages/core/src/modules/plugin/overwall/config.js |
Overwall configuration. |
packages/core/src/modules/plugin/node/index.js |
npm environment integration. |
packages/core/src/modules/plugin/node/config.js |
Node plugin configuration. |
packages/core/src/expose.js |
Startup orchestration. Moderate (2): First server.start() omits setting, so disabled Overwall may still be written to running.json. Moderate (2): Parallel startup can enable the system proxy before the proxy listens, causing ECONNREFUSED. |
packages/core/src/config/index.js |
Logging and routing configuration. |
packages/core/src/config-api.js |
Configuration API. |
doc/wiki/加速服务使用说明.md |
Acceleration service documentation. |
.github/workflows/build-and-release.yml |
Release artifact naming. |
_script/electron-dev.mjs |
Electron development script. |
_script/dev.ps1 |
PowerShell development script. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
Suppressed comments (17)
doc/wiki/加速服务使用说明.md:173
- 这次文档更新留下了三个空章节,完全删除了 DNS 设置、IP 预设置和 IP 测速的配置说明;这些正是本 PR 新增/调整的核心能力。发布后用户只能看到标题而无法按文档配置功能,请恢复并更新这些章节,或删除空标题避免造成文档不完整。
packages/core/src/modules/plugin/node/index.js:177 - The default
envMapcontains mirror variables, so this path runs during normal Node-plugin startup on every OS.set-system-env.jsstill throws暂未实现此功能on Linux and macOS; the startup catch hides the failure, leaving npm mirror environment variables unapplied on those platforms (andsave()can reject outright). Implement the POSIX environment update or avoid calling this Windows-only helper.
if (envList.length > 0) {
await shell.setSystemEnv({ list: envList })
}
packages/gui/src/bridge/update/backend.js:337
- A full installer is downloaded under the application root. Installed Windows applications commonly live under read-only
Program Files, and the macOS root derived here is inside the.appbundle, somkdirSync/the subsequent write can fail for normal packaged installs before the user can update. Store the installer in Electron's writable temp/user-data directory instead.
const appPath = appPathUtil.getAppRootPath(app)
const fileDir = path.join(appPath, 'update')
packages/gui/src/bridge/update/backend.js:121
- The success callback is attached to the source stream's
endevent before.pipe()registers its destination finalization handler. It can therefore notify the renderer and auto-open the installer while the output file is still being flushed (and beforefinish). Trigger success from the write stream'sfinishevent and handle its errors.
.on('end', () => {
// Do something after request finishes
onSuccess(filePath)
})
.pipe(fs.createWriteStream(filePath))
packages/gui/src/view/pages/server.vue:352
- 测速结果中的 Cloudflare 元数据在这里被重新组装时丢弃了。
hasCf()和模板都依赖element.cf,所以当命中的条目没有进入alive(例如测速失败或仍在探测)时,Cloudflare 标识不会显示;cfOriginalHost也会丢失。请在标准化对象中保留这些字段。
const standardized = {
host: ipObj.host,
port: ipObj.port || 443,
dns: ipObj.dns || 'unknown',
time: ipObj.time || null
packages/mitmproxy/src/lib/proxy/common/util.js:46
- The new per-domain TLS settings are only consumed when
getOptionsFromRequest()creates a keep-alive agent. Requests withConnection: closebypass that path and setagent = false, so thistlsVersionMappinghas no effect for them. Propagate the mappedminVersion/maxVersionto direct request options as well.
packages/mitmproxy/src/lib/proxy/mitmproxy/createConnectHandler.js:44 - For intercepted HTTPS CONNECTs this branch never associates the original
cltSocketwithTrafficMonitor. The subsequent requests are observed on the socket created byconnect()to the local fake server, so process resolution sees a Dev Sidecar-owned internal port instead of the client application's port; MITM traffic is consequently attributed to the proxy process (or未知进程) rather than the originating application. Preserve the client-socket association when creating the fake-server connection and avoid double-counting the internal socket.
packages/mitmproxy/src/lib/proxy/mitmproxy/createRequestHandler.js:440 proxyRequestPromise()setscontext.retryConfig = nullwhen the method/body/headers are not retryable, but this local snapshot remains non-null. A POST, chunked, orExpect: 100-continuerequest can therefore be retried after the firstreq.pipe(proxyReq)has consumed its stream, sending an empty or incomplete body. Drive the loop from the post-validation config, or clear this snapshot whenever the request is rejected for retry.
packages/mitmproxy/src/lib/proxy/mitmproxy/index.js:160- The cleanup function returned by
startProcessResolveris discarded, whiletrafficMonitor.stop()only clears the sampling interval. If the proxy is created again in the same child process, each start adds another resolver interval that keeps querying the system until the process exits.
packages/mitmproxy/src/lib/proxy/mitmproxy/index.js:160 - This resolver is started for every platform, but it invokes Windows-only
netstat.exeandtasklist.exeevery 2.5 seconds. On Linux and macOS each poll needlessly spawns a failing process and process names can never be resolved. Start it only on Windows or provide platform-specific resolvers.
packages/mitmproxy/src/lib/traffic/TrafficMonitor.js:138 - 连接条目只按
remotePort建索引。旧 socket 关闭事件异步触发时,如果该端口已经被新 socket 复用,旧监听器会调用finalizeSocket(clientPort)并把新条目的socket置为null,造成连接数和字节统计错乱。关闭回调应携带并校验具体 socket 身份。
packages/mitmproxy/src/lib/traffic/TrafficMonitor.js:134 - On a keep-alive client socket, every request enters this
elsebranch. Resetting the byte baselines to the current counters without first adding the delta discards request/response bytes that arrive between two one-second samples, so short requests are routinely missing from the traffic totals. Accumulate the counter deltas before replacing the baselines.
packages/mitmproxy/src/lib/traffic/TrafficMonitor.js:252 - The UI labels these values as cumulative, and
domainMapkeeps request totals for the lifetime of the monitor, but deleting a closed entry after 60 seconds removes its bytes fromtotalBytesUp/totalBytesDownon the next sample. The displayed cumulative totals can therefore decrease after an idle connection expires. Keep lifetime byte counters separately (or change the UI semantics) instead of deriving them only from retained entries.
packages/mitmproxy/src/lib/traffic/TrafficMonitor.js:295 domainMapreceives a new entry for every host and is never pruned; theslice(0, 100)later only limits the payload. A long-running proxy that sees many unique domains will retain all of them indefinitely and steadily increase memory usage. Add an age/size eviction policy for domain statistics.
packages/mitmproxy/src/lib/traffic/processResolver.js:21- 此正则在第一个地址包含冒号时就停止匹配,无法解析 Windows
netstat的[::1]:port/[2001:db8::1]:port记录。IPv6 客户端连接因此不会被归属到进程,流量监控在启用 IPv6 时会显示“未知进程”;请同时支持方括号 IPv6 地址。
packages/mitmproxy/src/lib/traffic/processResolver.js:29 - 这里用单一
localPort -> PID映射覆盖所有netstat记录;同一个本地源端口可以同时出现在连接到不同目标的 TCP 四元组中,因此后读到的连接会覆盖前一个 PID。这样流量监控可能把一个端口的流量归到错误进程。应按本地/远端地址和端口关联,或使用能直接返回 owning PID 的系统 API。
packages/mitmproxy/src/lib/traffic/processResolver.js:72 startProcessResolveris started from the shared proxy path, but these commands exist only on Windows. On Linux/macOS every interval attempts to spawnnetstat.exe(and usuallytasklist.exe), catches the error, and leaves process names unresolved while adding recurring process-spawn overhead. Gate this resolver byprocess.platformor provide a native implementation for those platforms.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+107
to
+109
| // server、系统代理、各插件之间没有相互依赖,并行启动以缩短整体等待时间 | ||
| await Promise.all(tasks) | ||
| } |
Comment on lines
611
to
+614
| try { | ||
| await exec('echo \'删除环境变量 HTTPS_PROXY、HTTP_PROXY、REQUEST_CA_BUNDLE\'') | ||
| const regKey = new Registry({ // new operator is optional | ||
| hive: Registry.HKCU, // open registry hive HKEY_CURRENT_USER | ||
| key: '\\Environment', // key containing autostart programs | ||
| }) | ||
| regKey.get('HTTPS_PROXY', (err) => { | ||
| if (!err) { | ||
| regKey.remove('HTTPS_PROXY', async (err) => { | ||
| if (err) { | ||
| log.warn('删除环境变量 HTTPS_PROXY 失败:', err) | ||
| } else { | ||
| await exec('setx DS_REFRESH "1"') | ||
| } | ||
| }) | ||
| } | ||
| }) | ||
| regKey.get('HTTP_PROXY', (err) => { | ||
| if (!err) { | ||
| regKey.remove('HTTP_PROXY', async (err) => { | ||
| if (err) { | ||
| log.warn('删除环境变量 HTTP_PROXY 失败:', err) | ||
| } | ||
| }) | ||
| } | ||
| }) | ||
| regKey.get('REQUEST_CA_BUNDLE', (err) => { | ||
| if (!err) { | ||
| regKey.remove('REQUEST_CA_BUNDLE', async (err) => { | ||
| if (err) { | ||
| log.warn('删除环境变量 REQUEST_CA_BUNDLE 失败:', err) | ||
| } | ||
| }) | ||
| } | ||
| }) | ||
| await removeWindowsEnvVariables(exec, ['HTTPS_PROXY', 'HTTP_PROXY', 'REQUEST_CA_BUNDLE']) | ||
| } catch (e) { | ||
| log.error('删除环境变量 HTTPS_PROXY、HTTP_PROXY 失败:', e) | ||
| log.error('删除环境变量 HTTPS_PROXY、HTTP_PROXY、REQUEST_CA_BUNDLE 失败:', e) |
| partArch = 'arm64' | ||
| fullArch = 'arm64' | ||
| } else if (arch === 'arm') { | ||
| partArch = 'x64' // 无 arm 增量包时兜底 |
Comment on lines
+8
to
+12
| const configPath = path.join(userBase, 'config.json') | ||
|
|
||
| try { | ||
| if (fs.existsSync(configPath)) { | ||
| const userConfig = JSON.parse(fs.readFileSync(configPath, 'utf-8')) |
| // 回归测试:Node 20+ 默认开启 autoSelectFamily,会以 { all: true } 调用自定义 lookup, | ||
| // 期望回传完整地址数组。旧实现只回传单个 IP 字符串,导致 | ||
| // ERR_INVALID_IP_ADDRESS: Invalid IP address: undefined。 | ||
| const dnsModulePath = require.resolve('node:dns') |
| reject(err); | ||
| }); | ||
|
|
||
| socket.connect(TEST_PORT, TEST_HOST); |
Comment on lines
+47
to
+50
| testIPv6Connection() | ||
| .then(success => { | ||
| console.log(`IPv6连接测试结果: ${success ? '成功' : '失败'}`); | ||
| process.exit(success ? 0 : 1); |
| @@ -0,0 +1,55 @@ | |||
| const net = require('net'); | |||
| const { setTimeout } = require('timers/promises'); | |||
| qs: '>=6.15.3' | ||
| tough-cookie: '>=4.1.3 <5.0.0' | ||
|
|
||
| supportedArchitectures: |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
代理核心
新增请求重试拦截器retry(500/连接失败自动重试)
按域名设置 TLS 版本(tlsVersionMapping)
Cloudflare 路由
请求失败后自动切换存活 IP
优化响应头显示
GUI 新增
新增流量监控页面
新增 GitHub 状态监控页面
设置增加日志开关
支持 DEV_SIDECAR_LOG_DISABLED 环境变量完全关闭日志
系统代理
set-system-proxy/index.js 大幅重构
优化系统代理开关与恢复逻辑
优化npm加速开关逻辑
修复
修复检查更新时证书错误
修复安装后任务栏图标为 Electron 默认图标
修复子资源错误页被浏览器 ORB 拦截
精简错误日志输出