dsh-mobile 0.6.13 → 0.6.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,13 +2,20 @@
2
2
 
3
3
  Notable changes are recorded here. GitHub Releases provide the downloadable packages and generated commit notes.
4
4
 
5
+ ## 0.6.14 - 2026-10-21
6
+
7
+ - Defer touch-triggered history loading until the gesture settles, cancel pending loading when the reader leaves the top zone, and scope movement/settle events to the conversation scrollport. Withdraw an older refused loading intent when a new gesture begins. Retain @chintoleung's three original commits from [#239](https://github.com/saya-ch/dsh-mobile/pull/239) alongside maintainer regression fixes.
8
+ - Keep Mobile Access usable beside other sidebar-footer actions: use a compact icon button when the row is shared, retain its accessible name, and restore the full label when it is alone. Thanks @gugubb5 for [#237](https://github.com/saya-ch/dsh-mobile/issues/237).
9
+ - Support explicit IPv6 loopback and ULA listeners and same-family private proxy-source CIDRs for an existing HTTPS reverse proxy. Display bracketed IPv6 backend URLs and clarify the difference between the phone-to-proxy and proxy-to-backend connections. Public frontend IPv6 does not require an IPv6 backend; exposing the plain HTTP backend publicly remains unsupported. Thanks @faruzanCN for [#238](https://github.com/saya-ch/dsh-mobile/issues/238).
10
+ - Add separate bug-report and feature-request forms with environment, reproduction, expected/actual behavior and third-party plugin comparison prompts.
11
+ - Link the independent experimental [dsh-mobile-iroh](https://github.com/saya-ch/dsh-mobile-iroh) project and summarize its local implementation progress without enabling a new provider in the stable plugin or App.
12
+ - Android App remains independently published as 0.6.5 (build 81); no native changes or new APK are included.
13
+
5
14
  ## 0.6.13 - 2026-10-19
6
15
 
7
- - Distinguish inbound HTTP receive timeouts (408 `request_timeout`) and oversized request headers (431 `headers_too_large`) from other malformed HTTP requests (400 `bad_request`). Preserve the existing receive limits and single-attempt POST forwarding; do not automatically retry messages.
16
+ - Distinguish inbound HTTP receive timeouts (408 `request_timeout`) and oversized request headers (431 `headers_too_large`) from other malformed HTTP requests (400 `bad_request`). Preserve the existing receive limits, authentication checks and single-attempt POST forwarding; do not automatically retry messages.
8
17
  - Add sampled HTTP rejection diagnostics that distinguish parser errors, invalid targets and authenticated upstream prompt rejections without recording request contents, raw packets, Cookies or arbitrary URLs. Connect diagnostic sinks for all Gateway factories, including own-origin and self-signed FRP entries.
9
- - Add real-page prompt-failure checks for restored text/images and visible errors. Separately reproduce a DSH 0.2.0-rc.2 and 0.2.1-rc.2 lifecycle defect: leaving a Session during a pending send cancels that request and discards its recovery state, including in pure stock profiles without Mobile installed. DSH source remains unchanged; this upstream defect and the exact cause of the reported #234 rejection are not claimed fixed. Thanks @Void-LifeStream for [#234](https://github.com/saya-ch/dsh-mobile/issues/234).
10
- - Distinguish HTTP receive timeouts and oversized request headers in the Gateway response and add bounded, privacy-preserving rejection diagnostics across all Gateway factories. Existing request limits, authentication checks and single-attempt POST forwarding remain unchanged; this release does not add automatic message retries.
11
- - Add a packed prompt-failure smoke covering text/image recovery and visible DSH errors on DSH 0.2.0-rc.2 and 0.2.1-rc.2. The optional navigation diagnostic records an upstream Session-lifecycle failure but is not a passing regression lane.
18
+ - Add packed real-page prompt-failure checks for restored text/images and visible errors on DSH 0.2.0-rc.2 and 0.2.1-rc.2. Separately reproduce a DSH lifecycle defect: leaving a Session during a pending send cancels that request and discards its recovery state, including in pure stock profiles without Mobile installed. The optional navigation diagnostic records that upstream Session-lifecycle failure but is not a passing regression lane. DSH source remains unchanged; this upstream defect and the exact cause of the reported #234 rejection are not claimed fixed. Thanks @Void-LifeStream for [#234](https://github.com/saya-ch/dsh-mobile/issues/234).
12
19
  - Keep DSH source and installed frontend artifacts read-only. The proposed iroh P2P channel in [#235](https://github.com/saya-ch/dsh-mobile/issues/235) is intentionally outside this repository and this release; it requires a separate host-side proof of concept.
13
20
 
14
21
  ## 0.6.12 - 2026-10-18
package/CONTRIBUTORS.md CHANGED
@@ -1,8 +1,14 @@
1
1
  # 贡献者 / Contributors
2
2
 
3
- GitHub 的 [Contributors 图表](https://github.com/saya-ch/dsh-mobile/graphs/contributors) 按进入默认分支的提交自动统计,无法手动加入仅提交 issue 或 PR 提案的成员。本页按截至 2026-10-18 的实际参与方式感谢社区成员;仓库维护者与自动依赖更新仍可在 GitHub 历史记录中查看。
3
+ GitHub 的 [Contributors 图表](https://github.com/saya-ch/dsh-mobile/graphs/contributors) 按进入默认分支的提交自动统计,无法手动加入仅提交 issue 或 PR 提案的成员。本页按截至 2026-10-21 的实际参与方式感谢社区成员;仓库维护者与自动依赖更新仍可在 GitHub 历史记录中查看。
4
4
 
5
- GitHub's Contributors graph counts commits on the default branch; issue reports and PR proposals cannot be manually added to it. This page credits community members by how they contributed, through 2026-10-18. The repository maintainer and automated dependency updates remain visible in GitHub's history.
5
+ GitHub's Contributors graph counts commits on the default branch; issue reports and PR proposals cannot be manually added to it. This page credits community members by how they contributed, through 2026-10-21. The repository maintainer and automated dependency updates remain visible in GitHub's history.
6
+
7
+ ## 0.6.14 代码贡献与反馈 / Code contributions and reports for 0.6.14
8
+
9
+ [@chintoleung](https://github.com/chintoleung) 的 [#239](https://github.com/saya-ch/dsh-mobile/pull/239) 将触摸历史自动加载延后至手势落定,并增加真实分页回归。0.6.14 保留原作者的三个提交,并追加维护者对滚动事件归属、新手势意图和混合输入的修正。感谢 [@gugubb5](https://github.com/gugubb5) 在 [#237](https://github.com/saya-ch/dsh-mobile/issues/237) 反馈侧栏入口共存问题,以及 [@faruzanCN](https://github.com/faruzanCN) 在 [#238](https://github.com/saya-ch/dsh-mobile/issues/238) 提出 IPv6 反代需求。
10
+
11
+ [@chintoleung](https://github.com/chintoleung)'s [#239](https://github.com/saya-ch/dsh-mobile/pull/239) defers touch-driven history loading until the gesture settles and adds real pagination regressions. Version 0.6.14 retains the author's three commits alongside maintainer fixes for scroll-event ownership, new-gesture intent and mixed input. Thanks [@gugubb5](https://github.com/gugubb5) for reporting sidebar-entry coexistence in [#237](https://github.com/saya-ch/dsh-mobile/issues/237), and [@faruzanCN](https://github.com/faruzanCN) for the IPv6 reverse-proxy request in [#238](https://github.com/saya-ch/dsh-mobile/issues/238).
6
12
 
7
13
  ## 0.6.12 问题定位 / Issue findings for 0.6.12
8
14
 
@@ -107,7 +113,9 @@ Thanks [@xhwxt](https://github.com/xhwxt) for the document-picker proposal in [#
107
113
  | [@CharlesLueng](https://github.com/CharlesLueng) | [#68](https://github.com/saya-ch/dsh-mobile/issues/68) |
108
114
  | [@chintoleung](https://github.com/chintoleung) | [#103](https://github.com/saya-ch/dsh-mobile/issues/103), [#166](https://github.com/saya-ch/dsh-mobile/issues/166), [#189](https://github.com/saya-ch/dsh-mobile/issues/189), [#228](https://github.com/saya-ch/dsh-mobile/issues/228) |
109
115
  | [@chmzs](https://github.com/chmzs) | [#73](https://github.com/saya-ch/dsh-mobile/issues/73) |
116
+ | [@faruzanCN](https://github.com/faruzanCN) | [#238](https://github.com/saya-ch/dsh-mobile/issues/238) |
110
117
  | [@gjzbbs](https://github.com/gjzbbs) | [#123](https://github.com/saya-ch/dsh-mobile/issues/123) |
118
+ | [@gugubb5](https://github.com/gugubb5) | [#237](https://github.com/saya-ch/dsh-mobile/issues/237) |
111
119
  | [@fishdivinity](https://github.com/fishdivinity) | [#202](https://github.com/saya-ch/dsh-mobile/issues/202) |
112
120
  | [@hairyf](https://github.com/hairyf) | [#114](https://github.com/saya-ch/dsh-mobile/issues/114) |
113
121
  | [@helan-1997](https://github.com/helan-1997) | [#168](https://github.com/saya-ch/dsh-mobile/issues/168) |
package/README.en.md CHANGED
@@ -26,13 +26,13 @@
26
26
  <a href="#compatibility">Compatibility</a> ·
27
27
  <a href="docs/README.md">Documentation</a> ·
28
28
  <a href="#contributors">Contributors</a> ·
29
- <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.13">Release notes</a> ·
29
+ <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.14">Release notes</a> ·
30
30
  <a href="README.md">简体中文</a>
31
31
  </p>
32
32
 
33
33
  > DSH Mobile is a DeepSeek Harness community plugin; the native app supports Android only.
34
34
  >
35
- > **Current stable release: 0.6.13**. Distinguish Gateway receive timeouts and oversized headers, add privacy-bounded rejection diagnostics, and cover packed text/image prompt failures. Android App **0.6.5** is unchanged and needs no matching update. [Release notes and downloads](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.13) · [Full changelog](CHANGELOG.md).
35
+ > **Current stable release: 0.6.14**. Improve history-loading gestures and shared sidebar-footer entries, and support IPv6 loopback/ULA backends for an existing HTTPS reverse proxy. Android App **0.6.5** is unchanged and needs no matching update. [Release notes and downloads](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.14) · [Full changelog](CHANGELOG.md).
36
36
  >
37
37
  > **Version policy**: since plugin **0.6.2**, the Android app and plugin use independent version numbers and releases. Their numbers do not need to match, and a plugin update does not imply an app update. [Compatibility notes](#compatibility).
38
38
 
@@ -128,6 +128,8 @@ Use this when the phone and computer share Wi-Fi, Ethernet, or a phone hotspot.
128
128
  3. In the Android app, open **Local network**, scan for computers, select the device, then scan the QR code or paste the pairing key.
129
129
  4. Pairing creates persistent device trust. Later app launches discover and connect automatically; Wi-Fi, hotspot, and DHCP address changes normally do not require pairing again.
130
130
 
131
+ When other plugin entries share the sidebar footer, **Mobile access** becomes a phone-icon button. Hover to read its name; clicking opens the same panel. Its text label returns when the entry is alone.
132
+
131
133
  Port note: `dsh web --port` changes the DSH Web upstream port (3080 by default), which the plugin follows automatically. `dsh-mobile setup --port` changes the Mobile HTTPS listener (3443 by default), and the pairing QR code includes the selected port.
132
134
 
133
135
  <details>
@@ -181,7 +183,7 @@ After selecting the channel in the panel:
181
183
  - **Tailscale Funnel**: select **Enable remote access**, complete the one-time Tailscale sign-in on the official page, follow the panel prompt to allow Funnel, then return to DSH and wait until the connection is ready.
182
184
  - **cpolar**: select **Install official component**, sign in to the cpolar dashboard and obtain an Authtoken, paste it, then select **Save and connect**. The component is downloaded into the plugin's private directory only after confirmation; free temporary addresses may change after DSH or cpolar restarts.
183
185
  - **Self-hosted FRP (advanced)**: if you have a VPS, expand **Self-hosted connection** and enter its frps details and a public HTTPS domain or real public IPv4 address. Apply the restricted frps + Caddy template manually, or deploy with an SSH key on Ubuntu/Debian with systemd. Password login is unsupported. Use manual deployment and merge the import as described in the guide when custom Caddy sites already exist. Verify the VPS host keys against its console before deployment or cleanup. The local `frpc` is downloaded and verified on demand; VPS cleanup is separate. Android app 0.3.3 or later is required. The [self-hosted FRP guide](docs/SELF_HOSTED_FRP.en.md) covers certificates, ports, and the complete procedure.
184
- - **Own reverse proxy**: open **Self-hosted connection → Own reverse proxy**, enter the public HTTPS origin (custom ports supported), private listen IPv4, separate HTTP backend port (default 3444), and allowed proxy source CIDRs, then select **Save and start backend**. This uses your existing Lucky/Nginx/Caddy without a tunnel component and requires Android app 0.4.0 or later. See the [own reverse proxy guide](docs/SELF_HOSTED_ORIGIN.en.md).
186
+ - **Own reverse proxy**: open **Self-hosted connection → Own reverse proxy**, enter the public HTTPS origin (custom ports supported), private listen IP (IPv4 or IPv6 loopback/ULA), separate HTTP backend port (default 3444), and allowed direct proxy source CIDRs, then select **Save and start backend**. This uses your existing Lucky/Nginx/Caddy without a tunnel component and requires Android app 0.4.0 or later. See the [own reverse proxy guide](docs/SELF_HOSTED_ORIGIN.en.md).
185
187
  - **Managed Caddy**: under **Self-hosted connection → Own reverse proxy**, select **Managed Caddy**, choose **Install managed Caddy**, and confirm the download. Enter the public HTTPS origin, Tencent Cloud DNSPod credentials and local HTTPS listen port, then choose **Save and start Caddy**. A domain and reachable public ingress are required; this does not bypass CGNAT. See the [managed Caddy guide](docs/CADDY_MANAGED.en.md) for forwarding and complete steps.
186
188
  - **cloudflared quick tunnel**: select **Install official component**. After you confirm, the plugin downloads a pinned build from the official release page into its private directory and requests a temporary public address (a quick tunnel) with **no sign-up or sign-in**. Choose this when you would rather not create an account. The quick-tunnel hostname changes on every reconnect, and Cloudflare positions quick tunnels for testing: they are rate-limited and carry no uptime guarantee, so do not rely on one for production access that must stay reachable; it suits temporary or verification use.
187
189
  - **cloudflared named tunnel**: with a Cloudflare account and domain, switch **Tunnel type** to **Named**, then supply a connector token, a public hostname and a local forward port to get an address that survives restarts. The token is stored only in the private directory and reaches cloudflared through the environment rather than the command line; see [Cloudflare named tunnel](docs/CLOUDFLARE_TUNNEL.en.md).
@@ -203,6 +205,10 @@ See [Compatibility](#compatibility) for the supported components and platforms.
203
205
 
204
206
  </details>
205
207
 
208
+ ### Experimental iroh connection
209
+
210
+ [dsh-mobile-iroh](https://github.com/saya-ch/dsh-mobile-iroh) is being developed independently to explore iroh connections while retaining DSH Mobile's pairing, device list and WebView experience. The local development candidate connects the Rust transport and Android app, with local QUIC/HTTPS/WSS checks and Android builds passing. It has not been integrated into this plugin or formally released; the desktop management UI, automatic certificate setup and physical cross-network acceptance remain unfinished. It is not yet a connection option in the current stable app.
211
+
206
212
  ## Extend and customize
207
213
 
208
214
  Type `/mobile <what you want>` in a DSH conversation to hand the request to the current agent. Once the files have been changed, the phone page usually refreshes within a few seconds. For example:
@@ -340,7 +346,7 @@ The dedicated mobile page synchronously loads the authenticated, same-origin `/m
340
346
 
341
347
  **Old-engine limits**: API shims cannot repair JavaScript syntax an engine cannot parse. The published **DSH 0.2.1-rc.2** frontend contains class static blocks, which Chromium **92** cannot parse. This syntax became enabled by default in Chrome 94, but that does not establish full DSH compatibility on 94. [V8 announcement](https://v8.dev/blog/v8-release-94). The App's below-100 advisory is not a compatibility guarantee; choosing Continue does not make the current DSH runnable. If system WebView cannot be updated, use a phone browser already confirmed to work with the computer's mobile address, without clearing existing App pairings.
342
348
 
343
- **Plugin 0.6.13** retains the 0.6.12 compatibility layer and startup feedback, distinguishes Gateway receive timeouts from oversized headers, and adds packed text/image prompt-failure checks. It does not transpile or modify DSH, and it does not automatically replay messages; acceptance on the physical Huawei Chromium 92 App remains unverified. Reports should include DSH/plugin/App and WebView versions, entry mode and the first redacted console error, never tokens or complete pairing URLs.
349
+ The current plugin retains the 0.6.12 compatibility layer and startup feedback, alongside 0.6.13's Gateway receive-timeout/header-size classification and packed text/image prompt-failure checks. It does not transpile or modify DSH, and it does not automatically replay messages; acceptance on the physical Huawei Chromium 92 App remains unverified. Reports should include DSH/plugin/App and WebView versions, entry mode and the first redacted console error, never tokens or complete pairing URLs.
344
350
 
345
351
  > **Community client (unofficial)**: [WeChat Mini-Program client](https://github.com/StrawberryAO/dsh-mobile-minapp)
346
352
  > A native WeChat Mini-Program that reuses the Mobile Access pairing and Remote stream protocol (requires dsh-mobile ≥ 0.3.8).
package/README.md CHANGED
@@ -26,13 +26,13 @@
26
26
  <a href="#兼容性">兼容性</a> ·
27
27
  <a href="docs/README.md">文档</a> ·
28
28
  <a href="#贡献者">贡献者</a> ·
29
- <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.13">更新记录</a> ·
29
+ <a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.14">更新记录</a> ·
30
30
  <a href="README.en.md">English</a>
31
31
  </p>
32
32
 
33
33
  > DSH Mobile 是 DeepSeek Harness 社区插件,原生 App 仅支持 Android。
34
34
  >
35
- > **当前正式版本:0.6.13**。区分网关 HTTP 接收超时与请求头过大错误,增加隐私受限的拒绝诊断,并补充图文发送失败回归。Android App **0.6.5** 保持不变,无需同步升级。[更新与下载](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.13) · [完整更新记录](CHANGELOG.md)。
35
+ > **当前正式版本:0.6.14**。改善历史消息加载手势与侧栏入口共存,支持自有反向代理的 IPv6 回环/ULA 后端。Android App **0.6.5** 保持不变,无需同步升级。[更新与下载](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.14) · [完整更新记录](CHANGELOG.md)。
36
36
  >
37
37
  > **版本说明**:自插件 **0.6.2** 起,Android App 与插件独立编号、独立发布,版本号无需一致;插件升级不代表 App 需要同步升级。[兼容说明](#兼容性)。
38
38
 
@@ -128,6 +128,8 @@ dsh plugin --profile web add dshmarket
128
128
  3. 在 Android App 中进入 **局域网访问**,扫描发现电脑并点击设备,再扫描二维码或粘贴配对密钥。
129
129
  4. 配对完成后会建立持久设备信任。以后打开 App 会自动发现并连接,切换 Wi-Fi、热点或 DHCP 地址通常不需要重新配对。
130
130
 
131
+ 侧栏底部有其他插件入口时,**移动访问**会收起为手机图标;悬停可查看名称,点击仍打开原面板。独占该区域时恢复文字显示。
132
+
131
133
  端口说明:`dsh web --port` 修改 DSH Web 上游端口(默认 3080),插件会自动跟随;`dsh-mobile setup --port` 修改 Mobile HTTPS 监听端口(默认 3443),配对二维码会包含实际端口。
132
134
 
133
135
  <details>
@@ -181,7 +183,7 @@ dsh plugin --profile web add dshmarket
181
183
  - **Tailscale Funnel**:点击 **启用远程访问**,在打开的官方页面完成一次 Tailscale 登录;按面板提示继续允许 Funnel,然后返回 DSH 等待连接就绪。
182
184
  - **cpolar**:点击 **安装官方组件**,登录 cpolar 控制台取得 Authtoken,粘贴后点击 **保存并连接**。组件只会在确认后下载到插件私有目录;免费临时地址可能在 DSH 或 cpolar 重启后变化。
183
185
  - **自建 FRP(高级)**:已有 VPS 时,展开 **自建连接**,填写 frps 信息和公开 HTTPS 域名或真实公网 IPv4。可以复制受限的 frps + Caddy 模板手动部署,也可以在 Ubuntu/Debian + systemd 上用 SSH 密钥一键部署;不支持密码登录。已有自定义 Caddy 站点时,请按指南手动部署并合并 import。部署或清理前须到 VPS 控制台核对主机指纹。本机 `frpc` 按需下载校验,VPS 需单独清理。需要 Android App 0.3.3 或更新版本;证书、端口和操作步骤见 [自建 FRP 使用指南](docs/SELF_HOSTED_FRP.md)。
184
- - **自有反向代理**:展开 **自建连接 → 自有反向代理**,填写公网 HTTPS 地址(支持自定义端口)、私有监听 IPv4、独立 HTTP 后端端口(默认 3444)和代理来源 CIDR,再点击 **保存并启动后端**。适合已有 Lucky/Nginx/Caddy 的用户,无需隧道组件;需要 Android App 0.4.0 或更高版本。详见 [自有反向代理指南](docs/SELF_HOSTED_ORIGIN.md)。
186
+ - **自有反向代理**:展开 **自建连接 → 自有反向代理**,填写公网 HTTPS 地址(支持自定义端口)、私有监听 IP(IPv4 或 IPv6 回环/ULA)、独立 HTTP 后端端口(默认 3444)和代理直连来源 CIDR,再点击 **保存并启动后端**。适合已有 Lucky/Nginx/Caddy 的用户,无需隧道组件;需要 Android App 0.4.0 或更高版本。详见 [自有反向代理指南](docs/SELF_HOSTED_ORIGIN.md)。
185
187
  - **托管 Caddy**:在 **自建连接 → 自有反向代理** 中选择 **托管 Caddy**,点击 **安装托管 Caddy** 并确认下载。填写公网 HTTPS 地址、腾讯云 DNSPod 凭据和本机 HTTPS 监听端口,再点击 **保存并启动 Caddy**。需要域名和可达的公网入站,不会替你穿透 CGNAT;端口映射与完整步骤见 [托管 Caddy 指南](docs/CADDY_MANAGED.md)。
186
188
  - **cloudflared 快速隧道**:点击 **安装官方组件**,插件在确认后从官方发布页下载固定版本到插件私有目录,随后自动申请一个临时公网地址(quick tunnel),**无需注册或登录**。适合不想注册账号的用户;quick tunnel 地址每次重连都会变化,官方定位为测试用途、有限流且无可用性保证,请勿用于必须长期可达的生产访问,只适合临时或验证场景。
187
189
  - **cloudflared 命名隧道**:已有 Cloudflare 账号和域名时,把隧道类型切到 **命名隧道**,填入连接器令牌、公网域名与本机转发端口,即可获得重启后不变的固定地址(令牌只存私有目录、只经环境变量传给 cloudflared)。步骤见 [Cloudflare 命名隧道](docs/CLOUDFLARE_TUNNEL.md)。
@@ -203,6 +205,10 @@ Funnel 的运行组件把公开监听生命周期绑定到父进程和受限控
203
205
 
204
206
  </details>
205
207
 
208
+ ### 实验中的 iroh 连接
209
+
210
+ [dsh-mobile-iroh](https://github.com/saya-ch/dsh-mobile-iroh) 正在独立开发,探索通过 iroh 连接电脑,并沿用 DSH Mobile 的配对、设备列表和 WebView 体验。目前本地开发候选已接通 Rust 传输与 Android,并通过本地 QUIC/HTTPS/WSS 验证和 Android 构建;尚未并入本插件或正式发布,电脑端操作界面、自动证书配置与真机跨网验收仍待完成。它还不是当前正式 App 可选的连接方式。
211
+
206
212
  ## 扩展与自定义
207
213
 
208
214
  在 DSH 对话里输入 `/mobile <需求>`,当前会话的 agent 会处理定制请求;文件修改完成后,手机端通常会在几秒内刷新。例如:
@@ -340,7 +346,7 @@ Android App 只是 Kotlin WebView 薄壳,不内置另一份网页;手机浏
340
346
 
341
347
  **旧内核限制**:API 兼容实现不能修复内核无法解析的 JavaScript 语法。DSH **0.2.1-rc.2** 的正式前端包含 class static blocks,Chromium **92** 无法解析;该语法从 Chrome 94 默认可用,但这不代表 94 已通过整个 DSH 的兼容验收。[V8 说明](https://v8.dev/blog/v8-release-94)。App 的“内核低于 100”提醒只是建议,点击继续不代表当前 DSH 可以运行。若系统 WebView 无法更新,可使用已确认正常的手机浏览器访问电脑端提供的移动地址,无需清除原有 App 配对。
342
348
 
343
- 插件 **0.6.13** 在保留 0.6.12 兼容层和启动反馈的基础上,区分网关接收超时与请求头过大,并增加图文发送失败的打包回归。它不转译 DSH、不修改 DSH 源码,也不自动重发消息;华为 Chromium 92 的实际 App 尚未完成验收。反馈问题时请提供 DSH/插件/App 与 WebView 版本、进入方式和脱敏后的首个控制台错误,不要发送令牌或完整配对地址。
349
+ 当前插件保留 0.6.12 的兼容层和启动反馈,以及 0.6.13 的网关接收超时/请求头过大分类与图文发送失败回归。它不转译 DSH、不修改 DSH 源码,也不自动重发消息;华为 Chromium 92 的实际 App 尚未完成验收。反馈问题时请提供 DSH/插件/App 与 WebView 版本、进入方式和脱敏后的首个控制台错误,不要发送令牌或完整配对地址。
344
350
 
345
351
  > **社区客户端(非官方)**:[微信小程序客户端](https://github.com/StrawberryAO/dsh-mobile-minapp)
346
352
  > 原生微信小程序实现,复用「移动访问」的配对与 Remote 流协议(需 dsh-mobile ≥ 0.3.8)。
package/SECURITY.md CHANGED
@@ -50,7 +50,7 @@ The maintainer will acknowledge a complete report within seven days. Publication
50
50
  - The Funnel node stores its Tailscale login state under `$DSH_HOME/mobile-access/remote/tailscale/`. The plugin does not request or store a Tailscale password, Auth Key, or OAuth secret.
51
51
  - The proxy-assisted remote diagnostic probes only the public `/mobile-access/health` path. It tries direct HTTPS first and, only after direct failure, may use an HTTP CONNECT proxy named by the DSH process environment unless `NO_PROXY` excludes the target. The probe sends no device token or session Cookie; configured proxy credentials are sent to that proxy for CONNECT, not placed in the diagnostic report. A proxy-only success is a warning to test from the phone, not proof that the phone or the provider route is available. This diagnostic does not change the remote provider's traffic path.
52
52
  - Plugin 0.6.11 and later record limited HTTP authorization and CSRF rejection metadata. It omits credential values and query strings, categorizes arbitrary paths, normalizes Origin and admits only recognized fetch-site values. Each Gateway keeps two fixed diagnostic categories with 30-second repeat aggregation, not an unbounded per-client/path history. Diagnostic-callback failures do not change the rejection response. These records are not complete WebSocket or native-pairing traces, and absence of a record does not establish successful authentication. Review even bounded metadata before sharing logs.
53
- - The unreleased HTTP-diagnostic change adds three fixed per-Gateway categories: parser rejection, invalid target, and an authenticated exact `POST /api/session/prompt` rejected by the upstream. Each has 30-second sampling with suppressed counts. Parser codes are allowlisted; raw packets, headers, request bodies, error messages, arbitrary URLs and query strings are excluded. A diagnostic failure cannot change the response or retry a write. Request timeout and header overflow remain rejected, using 408 and 431 rather than a generic 400; receive limits are not relaxed.
53
+ - Plugin 0.6.13 and later add three fixed per-Gateway HTTP-diagnostic categories: parser rejection, invalid target, and an authenticated exact `POST /api/session/prompt` rejected by the upstream. Each has 30-second sampling with suppressed counts. Parser codes are allowlisted; raw packets, headers, request bodies, error messages, arbitrary URLs and query strings are excluded. A diagnostic failure cannot change the response or retry a write. Request timeout and header overflow remain rejected, using 408 and 431 rather than a generic 400; receive limits are not relaxed.
54
54
  - cpolar is downloaded only after confirmation from a pinned official artifact whose size and SHA-256 are verified. Its Authtoken is stored in a private, self-update-disabled configuration under `$DSH_HOME/mobile-access/`, never returned by the admin API or written to logs. Component removal deletes its managed executable, Authtoken configuration, logs and staging files, but retains LAN and shared remote pairing records.
55
55
  - Self-hosted FRP accepts a VPS address, frps control port, operator-generated high-entropy shared token, and standard-port public HTTPS origin. The 0.4.6 self-signed entry additionally selects a non-reserved public TCP port on a globally routable IPv4 address. The plugin validates token length and format; the operator remains responsible for its entropy. Managed deployment creates one HTTP vhost and Caddy; existing-frps attachment changes no VPS files or services and allows either a restricted HTTP vhost with a public CA or one TCP passthrough to a computer-side HTTPS gateway. Arbitrary FRP configuration, general TCP/UDP forwarding, FRP plugins, PATH entries, and startup tasks are not supported.
56
56
  - For an HTTP-vhost entry, the generated managed-frps template binds the plaintext listener to `127.0.0.1` and uses Caddy for public HTTPS. An existing frps must have its actual `vhostHTTPPort` entered explicitly and its plaintext vhost kept off the public network; the plugin probes the configured port before starting `frpc`. frps `proxyBindAddr` governs proxy listeners globally: exposing a TCP passthrough on the same instance must not accidentally expose another plaintext vhost. A separate frps instance may be required. For self-signed ingress, the computer-side CA lasts five years and the leaf lasts 397 days; the leaf is renewed under the same CA, but an expired or replaced CA is not silently trusted and requires fresh pairing. A local readiness probe does not establish phone reachability; verify the public entry from an independent network.
@@ -27,15 +27,15 @@ Replace these examples with your own addresses:
27
27
  | Field | Proxy on the DSH computer | Proxy on another private-network host |
28
28
  | --- | --- | --- |
29
29
  | Public HTTPS origin | `https://phone.example.com:8815` | `https://phone.example.com:8815` |
30
- | Private listen IPv4 | `127.0.0.1` | DSH computer's address, e.g. `192.168.50.10` |
30
+ | Private listen IP | `127.0.0.1` or `::1` | DSH computer's private address, e.g. `192.168.50.10` or `fd12:3456:789a::10` |
31
31
  | HTTP backend port | `3444` | `3444` |
32
- | Allowed proxy source CIDR | `127.0.0.0/8` | Actual proxy source, e.g. `192.168.50.1/32` |
32
+ | Allowed proxy source CIDR | `127.0.0.0/8` for IPv4; `::1/128` for IPv6 | Actual proxy source, e.g. `192.168.50.1/32` or `fd12:3456:789a::1/128` |
33
33
 
34
- The public origin must be HTTPS and may include a custom port, but no path, credentials, query or fragment. Private/reserved public addresses, local names and IPv6 literals are rejected by this provider.
34
+ The public origin must be HTTPS and may include a custom port, but no path, credentials, query or fragment. Domains may use A/AAAA records for IPv4, IPv6 or dual-stack access. Private/reserved addresses, local names and IPv6 literals are rejected in the public-origin field.
35
35
 
36
- Bind to an explicit loopback or RFC1918 IPv4 already assigned to the DSH computer, not `0.0.0.0`, a hostname, public IP or IPv6. Choose an unused integer port from 1024–65535, excluding reserved 3080 and 3443. Default 3444 is also the named-cloudflared forward port: only one remote provider runs at a time, but verify the port is released during a switch.
36
+ Bind to an explicit loopback, RFC1918 IPv4 or IPv6 ULA (`fc00::/7`) already assigned to the DSH computer. Enter IPv6 as a bare address such as `::1`, without brackets, port or zone ID; displayed backend URLs add the required brackets, e.g. `http://[::1]:3444`. Wildcards `0.0.0.0`/`::`, hostnames, public IPs and IPv6 link-local addresses are rejected. Choose an unused integer port from 1024–65535, excluding reserved 3080 and 3443. Default 3444 is also the named-cloudflared forward port: only one remote provider runs at a time, but verify the port is released during a switch.
37
37
 
38
- CIDRs match the proxy's **direct TCP peer**, not the phone or `X-Forwarded-For` / `X-Real-IP` / `Forwarded`. Docker or NAT may change that peer. Prefer the actual single-host /32, not an entire subnet. Up to 16 canonical private/loopback CIDRs are accepted, separated by spaces or commas; explicit private proxy sources are required for a LAN bind.
38
+ CIDRs match the proxy's **direct TCP peer**, not the phone or `X-Forwarded-For` / `X-Real-IP` / `Forwarded`. Docker or NAT may change that peer. Prefer an actual single-host IPv4 /32 or IPv6 /128. Up to 16 private/loopback CIDRs are accepted, separated by spaces or commas; each must use the listener's IP family and have no host bits set. Explicit private proxy sources are required for a private-network bind; `::/0` is rejected.
39
39
 
40
40
  Phones behind a proxy may share that direct peer. From plugin 0.6.12, invalid credentials still share its failure budget, but anonymous failures cannot exhaust a valid one-time pairing secret's admission. Authenticated renewals and probes have per-device limits and bounded pending work. Adding or trusting forwarded-IP headers is unnecessary. For `429 rate_limited` on older versions, update the plugin while retaining pairings; do not widen source CIDRs or expose the ordinary DSH listener.
41
41
 
@@ -53,6 +53,34 @@ Select **Save and start backend**. An active backend reloads its settings. The p
53
53
 
54
54
  For a separate proxy host, configure routing and a firewall rule limited to its actual private source yourself. This provider does not change the firewall.
55
55
 
56
+ ### Nginx and IPv6
57
+
58
+ The phone's public IPv6 connection to Nginx and Nginx's HTTP connection to DSH Mobile are separate connections. **An IPv6 public entry does not require an IPv6 backend.** On the same computer, Nginx can accept public IPv6 and forward to `http://127.0.0.1:3444`; the source CIDR remains IPv4 loopback. For an explicit `::1` backend, use `http://[::1]:3444` and `::1/128` instead.
59
+
60
+ In an existing Nginx HTTPS site with its certificate configured, preserve the external Host and WebSocket upgrade headers:
61
+
62
+ ```nginx
63
+ # In the http block; reuse an existing map when already defined.
64
+ map $http_upgrade $connection_upgrade {
65
+ default upgrade;
66
+ '' close;
67
+ }
68
+
69
+ # In the corresponding HTTPS server block.
70
+ location / {
71
+ proxy_pass http://127.0.0.1:3444;
72
+ proxy_http_version 1.1;
73
+ proxy_set_header Host $http_host;
74
+ proxy_set_header Upgrade $http_upgrade;
75
+ proxy_set_header Connection $connection_upgrade;
76
+ proxy_buffering off;
77
+ }
78
+ ```
79
+
80
+ `$http_host` preserves a non-default port from the phone's request; do not replace it with the backend address. See [Nginx WebSocket documentation](https://nginx.org/en/docs/http/websocket.html) and [request-header settings](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header). You still configure public AAAA records, the Nginx IPv6 HTTPS listener, certificates and firewall.
81
+
82
+ When Nginx and DSH run on separate machines connected only through the Internet, do not expose this plain HTTP backend publicly. Establish a trusted private/VPN link first, then use its private IPv4/ULA address and the proxy's actual source CIDR. A public IPv6 address alone does not provide that private link.
83
+
56
84
  ## State and phone verification
57
85
 
58
86
  **Backend listening proves the local listener only, not public HTTPS, certificates or WebSocket connectivity.** External-proxy diagnostics do not probe the public origin.
@@ -82,7 +110,7 @@ Under the default `$DSH_HOME/mobile-access/` root, settings are in `remote/origi
82
110
  | Symptom | First check |
83
111
  | --- | --- |
84
112
  | Port occupied | Choose an unused backend port and update the proxy target |
85
- | Listen address unavailable | Use a private IPv4 assigned to the DSH computer, not the proxy host |
113
+ | Listen address unavailable | Use loopback, private IPv4 or ULA assigned to the DSH computer, not the proxy host; public IPv6 access does not imply a local ULA exists |
86
114
  | Refused / HTTP 403 | Verify direct source CIDR, full external Host and HTTPS Origin; forwarded headers cannot bypass them |
87
115
  | Page works but real-time operations fail | Check WebSocket forwarding, timeout and approved paths without disabling trust checks |
88
116
  | Only Backend listening | Expected local state; verify public DNS, HTTPS routing, certificate and actual phone access |
@@ -28,15 +28,15 @@
28
28
  | 字段 | 代理与 DSH 同机 | 代理在另一台 LAN 设备 |
29
29
  | --- | --- | --- |
30
30
  | 公网 HTTPS 地址 | `https://phone.example.com:8815` | `https://phone.example.com:8815` |
31
- | 私有监听 IPv4 | `127.0.0.1` | DSH 电脑的私网地址,如 `192.168.50.10` |
31
+ | 私有监听 IP | `127.0.0.1` 或 `::1` | DSH 电脑的私网地址,如 `192.168.50.10` 或 `fd12:3456:789a::10` |
32
32
  | HTTP 后端端口 | `3444` | `3444` |
33
- | 允许的代理来源 CIDR | `127.0.0.0/8` | 代理的实际来源,如 `192.168.50.1/32` |
33
+ | 允许的代理来源 CIDR | IPv4 使用 `127.0.0.0/8`;IPv6 使用 `::1/128` | 代理的实际来源,如 `192.168.50.1/32` 或 `fd12:3456:789a::1/128` |
34
34
 
35
- 公网地址只能是 HTTPS Origin,可带非 443 端口;不包含路径、账号密码、查询参数或 fragment。私有/保留 IP、本地域名和 IPv6 字面地址不适用于此提供方。
35
+ 公网地址只能是 HTTPS Origin,可带非 443 端口;不包含路径、账号密码、查询参数或 fragment。域名可以通过 A/AAAA 记录提供 IPv4、IPv6 或双栈访问;私有/保留 IP、本地域名和 IPv6 字面地址不适用于公网地址字段。
36
36
 
37
- 监听地址必须是**本机已有的明确回环或 RFC1918 私有 IPv4**,不能填 `0.0.0.0`、主机名、公网 IP 或 IPv6。端口必须是 **1024–65535** 的整数,并排除 3443(局域网网关)与 3080(DSH 自身);请使用未被占用的端口。
37
+ 监听地址必须是**本机已有的明确回环、RFC1918 私有 IPv4 或 IPv6 ULA(`fc00::/7`)**。IPv6 直接填写 `::1` 或 ULA 地址,不加方括号、端口或 zone ID;面板给出的 HTTP 后端 URL 会自动补齐方括号,例如 `http://[::1]:3444`。不能填写 `0.0.0.0`、`::`、主机名、公网 IP 或 IPv6 链路本地地址。端口必须是 **1024–65535** 的整数,并排除 3443(局域网网关)与 3080(DSH 自身);请使用未被占用的端口。
38
38
 
39
- CIDR 限制针对 TCP 连接的**直接来源地址**,不是手机 IP,也不是 `X-Forwarded-For`、`X-Real-IP` 或 `Forwarded`。Docker、桥接或 NAT 可能改变这个地址,应填写后端实际看到的私网来源。优先用单地址 `/32`,不要为了排错放宽整个局域网。最多 16 项,用空格或逗号分隔;只允许回环/私网网段,网络地址不能带主机位。LAN 监听必须显式列出私网代理来源。
39
+ CIDR 限制针对 TCP 连接的**直接来源地址**,不是手机 IP,也不是 `X-Forwarded-For`、`X-Real-IP` 或 `Forwarded`。Docker、桥接或 NAT 可能改变这个地址,应填写后端实际看到的私网来源。优先用单地址 IPv4 `/32` 或 IPv6 `/128`,不要为了排错放宽整个局域网。最多 16 项,用空格或逗号分隔;只允许与监听地址同一 IP 协议的回环/私网网段,网络地址不能带主机位,不能使用 `::/0`。私网监听必须显式列出私网代理来源。
40
40
 
41
41
  代理后的手机可能共享一个直接来源地址。插件 0.6.12 起,错误凭据仍共享该来源的失败限额,但有效的一次性配对码不会被匿名失败耗尽;已认证设备的续期和探测按设备分别限频,并限制未完成操作。不需要为此添加或信任转发 IP 请求头。旧版出现 `429 rate_limited` 时先升级插件并保留配对记录,不要放宽来源网段或公开裸 DSH 端口。
42
42
 
@@ -54,6 +54,34 @@ CIDR 限制针对 TCP 连接的**直接来源地址**,不是手机 IP,也不
54
54
 
55
55
  若代理在另一台机器上,还需由管理员保证网络可达,并将主机防火墙入站范围限制到代理的实际私网来源;此功能不自动改防火墙。
56
56
 
57
+ ### Nginx 与 IPv6
58
+
59
+ 手机到 Nginx 的公网 IPv6 连接,与 Nginx 到 DSH Mobile 的 HTTP 后端连接是两段独立连接。**公网入口使用 IPv6,不要求后端也使用 IPv6**。同机 Nginx 可以通过 IPv6 接收手机请求,再代理到 `http://127.0.0.1:3444`;这时来源 CIDR 仍是 IPv4 回环。若后端明确监听 `::1`,Nginx 目标改为 `http://[::1]:3444`,来源改为 `::1/128`。
60
+
61
+ 在现有已配置 HTTPS 证书的 Nginx 站点中,保留外部 Host 与 WebSocket 升级头:
62
+
63
+ ```nginx
64
+ # 放在 http 块中;已定义时复用现有 map。
65
+ map $http_upgrade $connection_upgrade {
66
+ default upgrade;
67
+ '' close;
68
+ }
69
+
70
+ # 放在对应 HTTPS server 块中。
71
+ location / {
72
+ proxy_pass http://127.0.0.1:3444;
73
+ proxy_http_version 1.1;
74
+ proxy_set_header Host $http_host;
75
+ proxy_set_header Upgrade $http_upgrade;
76
+ proxy_set_header Connection $connection_upgrade;
77
+ proxy_buffering off;
78
+ }
79
+ ```
80
+
81
+ `$http_host` 保留手机请求中的非默认端口;不要替换为后端地址。参见 [Nginx WebSocket 官方说明](https://nginx.org/en/docs/http/websocket.html)与[请求头设置](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header)。公网域名的 AAAA、Nginx IPv6 HTTPS 监听、证书和防火墙仍由你配置。
82
+
83
+ 若 Nginx 与 DSH 分处两台只有公网互通的机器,不能直接把此明文 HTTP 后端暴露到公网。先建立可信私网/VPN 链路,再填其私有 IPv4/ULA 地址及代理的实际来源 CIDR;仅有公网 IPv6 地址并不提供这条私网链路。
84
+
57
85
  ## 状态与手机验证
58
86
 
59
87
  **“后端已监听”只证明本地 HTTP 监听成功,不代表公网 HTTPS、证书或 WebSocket 已成功。** 自备代理模式的连接诊断也只报告本地状态,不自动向公网地址探测。
@@ -83,7 +111,7 @@ CIDR 限制针对 TCP 连接的**直接来源地址**,不是手机 IP,也不
83
111
  ## 常见问题
84
112
 
85
113
  - **端口占用**:换一个空闲后端端口并同步修改代理目标;不要挪动现有 LAN 或 DSH 端口。
86
- - **监听地址不可用**:填写 DSH 本机当前私有 IPv4,不是代理机器的 IP。
114
+ - **监听地址不可用**:填写 DSH 本机当前回环、私有 IPv4 或 ULA,不是代理机器的 IP;公网入口能走 IPv6 不代表本机已分配 ULA。
87
115
  - **被拒绝 / 403**:核对直接来源 CIDR、完整外部 Host 和 HTTPS Origin;伪造转发头不会绕过这些检查。
88
116
  - **HTTP 页面可开但实时功能失败**:核对代理 WebSocket 转发、超时及路径白名单,不要通过关闭来源验证来排错。
89
117
  - **只有“后端已监听”**:这是预期语义;继续检查公网 DNS、端口映射到 HTTPS 代理、证书及手机实际访问。
@@ -20,11 +20,11 @@ Both [#126](https://github.com/saya-ch/dsh-mobile/issues/126) and [#146](https:/
20
20
 
21
21
  Plugin 0.6.11 and later write limited `auth failure` HTTP diagnostics to the plugin log (`$DSH_HOME/mobile-access/logs/dsh-mobile.log`): authorization versus CSRF rejection, status, method, a safe route or route category, related Cookie/header presence and counts, normalized Origin and recognized fetch-site values. It omits tokens, Cookie values, query strings and arbitrary original paths. Each Gateway rate-limits its two categories separately: the first event is immediate and same-category rejections aggregate within a 30-second window; `suppressed` counts previously suppressed records of that category, not all requests or only the current path. This helps investigate missing credentials and CSRF failures; it does not automatically repair a 401/403. The absence of a record does not establish successful authentication: earlier Host/Origin rejections, WebSocket upgrades and native pairing/renewal are outside these two recording points. Review logs before sharing them.
22
22
 
23
- ## HTTP 400, 408 and 431 (in development)
23
+ ## HTTP 400, 408 and 431 (plugin 0.6.13+)
24
24
 
25
- The unpublished plugin correction distinguishes request receive timeouts as `408 request_timeout` and oversized headers as `431 headers_too_large`; other malformed HTTP requests remain `400 bad_request`. Older versions may return 400 with the same short JSON for all of them, so a status and a 24-byte body do not identify the cause.
25
+ Plugin 0.6.13 and later distinguish request receive timeouts as `408 request_timeout` and oversized headers as `431 headers_too_large`; other malformed HTTP requests remain `400 bad_request`. Older versions may return 400 with the same short JSON for all of them, so a status and a 24-byte body do not identify the cause.
26
26
 
27
- New `http failure` diagnostics distinguish three per-Gateway categories: `parser` for HTTP parsing/receive failures, `target` for invalid request targets, and `upstream` for an authenticated `POST /api/session/prompt` rejected upstream. The first event of each kind is immediate; repeats aggregate for 30 seconds, with `suppressed` counting earlier suppressed events of that kind. Logs exclude raw errors, request bodies, raw packets, Cookies, Tokens, queries and arbitrary URLs. No record does not establish success.
27
+ The `http failure` diagnostics distinguish three per-Gateway categories: `parser` for HTTP parsing/receive failures, `target` for invalid request targets, and `upstream` for an authenticated `POST /api/session/prompt` rejected upstream. The first event of each kind is immediate; repeats aggregate for 30 seconds, with `suppressed` counting earlier suppressed events of that kind. Logs exclude raw errors, request bodies, raw packets, Cookies, Tokens, queries and arbitrary URLs. No record does not establish success.
28
28
 
29
29
  `upstreamTimeoutMs` governs upstream transport waits and also configures the complete inbound-request receive deadline. A continuously active upload can still exceed that total deadline, and Node's periodic checks affect the observed firing time. Do not delete pairings, clear App data or automatically resend because of HTTP 400 alone. Identify the rejection layer using the actual response body, Content-Type, exact versions and redacted proxy upstream status. Check the Session result before retrying an operation whose execution outcome is unknown.
30
30
 
@@ -20,11 +20,11 @@
20
20
 
21
21
  插件 0.6.11 起会在插件日志(`$DSH_HOME/mobile-access/logs/dsh-mobile.log`)记录有限的 `auth failure` HTTP 诊断:区分授权与 CSRF 拒绝,包含状态、方法、安全路径或路径类别、相关 Cookie/请求头是否存在及计数、规范化 Origin 和受支持的 fetch-site 值,不记录令牌、Cookie 值、查询参数或任意原始路径。每个网关的两类诊断分别限频,首条立即记录,30 秒窗口内同类拒绝聚合;`suppressed` 表示此前被抑制的同类记录数量,不是全部请求数,也不限定于当前路径。它帮助排查凭据未携带或 CSRF 校验失败,不会自动修复 401/403。没有日志也不代表认证成功:更早的 Host/Origin 拒绝、WebSocket 升级和原生配对/续期不在这两处记录范围内。分享前仍应检查日志。
22
22
 
23
- ## HTTP 400、408 与 431 的区别(开发中)
23
+ ## HTTP 400、408 与 431 的区别(插件 0.6.13 起)
24
24
 
25
- 尚未发布的插件修正会把请求接收超时区分为 `408 request_timeout`,请求头过大区分为 `431 headers_too_large`;其他非法 HTTP 请求仍为 `400 bad_request`。旧版可能把这几类情况都返回成 400 和相同的短 JSON,因此状态码与“24 字节”不足以定位原因。
25
+ 插件 0.6.13 起把请求接收超时区分为 `408 request_timeout`,请求头过大区分为 `431 headers_too_large`;其他非法 HTTP 请求仍为 `400 bad_request`。旧版可能把这几类情况都返回成 400 和相同的短 JSON,因此状态码与“24 字节”不足以定位原因。
26
26
 
27
- 新的 `http failure` 日志按网关区分 `parser`、`target`、`upstream` 三类:分别表示 HTTP 解析/接收失败、非法请求目标、已认证的 `POST /api/session/prompt` 被上游拒绝。每类首条立即记录,后续 30 秒内聚合,下一条的 `suppressed` 是此前被抑制的同类数量。日志不保留原始报错、请求正文、原始包、Cookie、Token、查询参数或任意 URL;不记录某条也不能证明它成功。
27
+ `http failure` 日志按网关区分 `parser`、`target`、`upstream` 三类:分别表示 HTTP 解析/接收失败、非法请求目标、已认证的 `POST /api/session/prompt` 被上游拒绝。每类首条立即记录,后续 30 秒内聚合,下一条的 `suppressed` 是此前被抑制的同类数量。日志不保留原始报错、请求正文、原始包、Cookie、Token、查询参数或任意 URL;不记录某条也不能证明它成功。
28
28
 
29
29
  `upstreamTimeoutMs` 既用于上游传输等待,也配置了入站完整请求的接收期限;持续上传不保证避开这个总期限,Node 的定期检查会影响实际触发时刻。不要仅凭 HTTP 400 就删除配对、清空 App 数据或自动重发。先区分拒绝来源,并查看实际响应正文、Content-Type、准确版本和脱敏的代理上游状态;消息或工具是否已执行不明时,先核对会话结果。
30
30