Skip to content

fix(instance): 修复实例窗口 431 与认证失效 - #45

Merged
Gu-ZT merged 2 commits into
dsh-plugins:mainfrom
mmyddd:main
Sep 14, 2026
Merged

Gu-ZT merged 2 commits into
dsh-plugins:mainfrom
mmyddd:main

Conversation

@mmyddd

@mmyddd mmyddd commented Sep 12, 2026

Copy link
Copy Markdown
Contributor
  • 每个实例使用独立浏览器数据目录:Windows/Linux 走 WebView2 data_directory,macOS 走 WKWebView data store id,避免按 authority 命名、有效期 30 天的 dsh-auth cookie 随实例换端口无限累积,撑破 node:http 16 KiB maxHeaderSize 后所有请求(含携带 token 的)直接返回 431
  • 打开已存在的实例窗口时重新导航到最新的 dsh web 令牌 URL,并记录每个窗口最后使用的地址,实例重启后不再停留在过期的认证失败页面
  • 导航前清除该实例自身的失效 dsh-auth cookie;Windows 上 cookie 读取放在工作线程,规避 wry 记录的同步命令/事件处理器死锁
  • 无可用地址且实例已不在运行时清理该实例浏览器数据并报错,实例仍在启动中则保留窗口不导航
  • 删除实例时一并清理其浏览器数据目录
  • 新增 loopback_origin 与 dsh-auth cookie 名派生单测

mmyddd and others added 2 commits September 12, 2026 19:22
- 每个实例使用独立浏览器数据目录:Windows/Linux 走 WebView2 data_directory,macOS 走 WKWebView data store id,避免按 authority 命名、有效期 30 天的 dsh-auth cookie 随实例换端口无限累积,撑破 node:http 16 KiB maxHeaderSize 后所有请求(含携带 token 的)直接返回 431
- 打开已存在的实例窗口时重新导航到最新的 dsh web 令牌 URL,并记录每个窗口最后使用的地址,实例重启后不再停留在过期的认证失败页面
- 导航前清除该实例自身的失效 dsh-auth cookie;Windows 上 cookie 读取放在工作线程,规避 wry 记录的同步命令/事件处理器死锁
- 无可用地址且实例已不在运行时清理该实例浏览器数据并报错,实例仍在启动中则保留窗口不导航
- 删除实例时一并清理其浏览器数据目录
- 新增 loopback_origin 与 dsh-auth cookie 名派生单测
- macOS/iOS 走 clear_all_browsing_data 分支,该目录级 helper 在该平台无调用点,
  clippy -D warnings 以 never used 报错导致 Quality (macos) 失败
- 按仓库既有约定(wsl.rs 的 cfg_attr(not(windows), allow(dead_code)))为 Apple
  平台加 cfg_attr allow(dead_code),行为与三平台语义均不变
@Gu-ZT

Gu-ZT commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

评审结论:可以合入(CI 失败已由我修复)

已修复:Quality (macos) 门禁失败

https://github.com/dsh-plugins/dsh-launcher/actions/runs/34691494745/job/103547412131 的根因是 -D warnings 下的 dead code:

error: function `clear_instance_webview_data_from` is never used
error: could not compile `dsh-launcher` (lib) due to 1 previous error

clear_webview_datasrc-tauri/src/windows.rs:127-143)在 Apple 平台走 win.clear_all_browsing_data() 分支,非 Apple 平台才调用 clear_instance_webview_data_from,所以 macOS 编译时该函数没有任何调用点。按仓库既有约定(src-tauri/src/wsl.rs:169#[cfg_attr(not(windows), allow(dead_code))])加了同样的 cfg 守卫:

#[cfg_attr(any(target_os = "macos", target_os = "ios"), allow(dead_code))]
pub(crate) fn clear_instance_webview_data_from(app: &AppHandle, instance_id: &str) {

已推送到本 PR 分支(663e852)。三平台 Quality 现在 4/4 通过(macos 1m46s ✅),本地 cargo fmt --check / clippy -D warnings / cargo test(114 passed)均通过。

修复内容复核(均为正确且必要)

  • 每实例独立浏览器数据目录apply_window_store 在非 Apple 平台用 data_directory,Apple 平台用 data_store_identifier(SHA-256 前 16 字节)。已核对 tauri 2.11.5 文档:data_directory 明确标注 WKWebView 不可用,data_store_identifier 则是 macOS ≥14 / iOS ≥17 的对应能力,两者的平台配对是正确的。
  • 431 根因分析成立:DSH 的 cookie 名带 authority(dsh-auth-<base64url(sha256(host:port))>)且 30 天有效,共享 store 会随端口累积,最终撑破 node:http 的 16 KiB maxHeaderSizedsh_auth_cookie_name_follows_the_origin_authority 这条测试把这个命名契约钉住了(含固定期望值 dsh-auth-k320QAAWVPdxfnOxhyOWdX-dQ03IEKrIdtzGoIirIUY),很有价值——上游改名会立刻暴露。
  • 重开窗口重新导航到最新 token URLcurrent_instance_url 的三级回退(运行中记录的 URL → window_urls 上次导航 → spawn 时传入)与 stale 判定合理;commands.rs 放宽「无 URL 且窗口不存在才报错」的处理,修掉了「窗口还开着却因注册表已清除而拒绝重开」的边角。
  • cookie 读取放工作线程:规避 wry 记录的同步命令/事件处理器死锁,符合 tauri 的已知约束。
  • loopback_origin 只接受纯 loopback HTTP:WSL 转发与其它 origin 不参与 cookie 处理,边界清晰,且 3 条断言把 WSL/https/localhost 的排除行为钉住了。

非阻塞建议

  1. AppState.window_urls 只在导航时写入、从不清理(windows.rs:remember_window_url):delete_instancecommands.rs:351-364)清了 webview 数据目录但没清该表,窗口关闭路径也没有移除条目。虽然实例 id 唯一、影响仅限内存中的一条 URL 字符串,但建议在 delete_instancewindow_urls.lock().unwrap().remove(&id) 一并清理,避免长期运行后表内积累已删除实例的死条目。
  2. clear_webview_data 的 doc 注释被截断(windows.rs:125-126 结尾停在「macOS clears the」),建议补完。
  3. instance_is_runningtry_lock() 探测:竞争时会返回 false,从而把「仍在启动中」误判为「没有可用地址」并清掉该实例的浏览器数据。建议改成对 try_lock 失败时保守返回「运行中」(即不做破坏性清理),或直接用 lock()
  4. macOS 上 data_store_identifier 依赖实例 id 的 SHA-256 前 16 字节,实例删除后 WKWebView 的 store 由系统管理、启动器无法清理(clear_instance_webview_data 只删文件目录,注释已说明这点)。建议在设置页或文档里提一句 macOS 的浏览器数据会随实例数累积。

验证情况

  • 已完整阅读三份改动的 diff(commands.rs / lib.rs / windows.rs)与其中的 2 个新单测;核对了仓库既有 #[cfg_attr(..., allow(dead_code))] 约定、tauri 2.11.5data_directory / data_store_identifier / clear_all_browsing_data 平台支持说明。
  • 本机无法交叉编译到 macOS(objc2-exception-helper 无法在 Windows 上构建 build script),因此 macOS 分支的实际编译验证以本次 CI 重跑为准(已通过)。
  • 本地门禁:cargo fmt --all -- --check ✅、cargo clippy --all-targets -- -D warnings ✅、cargo test(114 passed / 1 ignored)✅。

CI 已全绿,我将按流程 squash 合入。

@Gu-ZT
Gu-ZT merged commit 9bf3ab2 into dsh-plugins:main Sep 14, 2026
8 checks passed
Gu-ZT added a commit to yukitakasama/dsh-launcher that referenced this pull request Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants