dsh-mobile 0.6.13 → 0.6.15
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 +27 -4
- package/CONTRIBUTORS.md +20 -2
- package/README.en.md +13 -7
- package/README.md +13 -7
- package/SECURITY.md +5 -2
- package/THIRD_PARTY_NOTICES.md +30 -2
- package/apps/mobile/README.md +10 -4
- package/apps/mobile/README.zh-CN.md +10 -4
- package/apps/mobile/release.json +3 -3
- package/docs/SELF_HOSTED_ORIGIN.en.md +34 -6
- package/docs/SELF_HOSTED_ORIGIN.md +34 -6
- package/docs/SLOW_CONNECTIONS.en.md +14 -4
- package/docs/SLOW_CONNECTIONS.md +14 -4
- package/lib/client.js +102 -32
- package/lib/client.js.map +1 -1
- package/lib/extension-worker-runtime.mjs.map +1 -1
- package/lib/index.d.mts +25 -3
- package/lib/index.mjs +478 -54
- package/lib/index.mjs.map +1 -1
- package/lib/mobile-compat.js +1 -1
- package/lib/mobile-compat.js.map +1 -1
- package/package.json +3 -1
- package/packages/question-fixes/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,13 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
Notable changes are recorded here. GitHub Releases provide the downloadable packages and generated commit notes.
|
|
4
4
|
|
|
5
|
+
## 0.6.15 - 2026-10-21
|
|
6
|
+
|
|
7
|
+
- Keep the dedicated Mobile page's plugin-update notifications connected during idle periods, without gzip buffering. Live module updates retain the mobile layout and the page's selected modules instead of replacing them with the desktop layout. Upgrade and reload the dedicated page to use the corrected stream; stock and older pages keep their existing behavior.
|
|
8
|
+
- Retain authentication, expiry, revocation and cancellation checks for module notifications. A page view does not migrate to a new authentication Session: after native renewal, an old view can return `409 mobile_document_view_invalid` until the page is loaded again. This does not clear pairings or automatically refresh the current conversation. See [connection troubleshooting](docs/SLOW_CONNECTIONS.en.md#keep-event-streams-distinct).
|
|
9
|
+
- Allow same-origin audio/video fetched into Blob URLs on the proxied DSH page. External media remains blocked, Gateway-owned pages retain their policy, and Android's media user-gesture requirement stays enabled.
|
|
10
|
+
- Fix computer-side JSON management actions when Firefox privacy settings omit Origin. Keep local connection and Host checks, cross-origin rejection and official Desktop authentication. Thanks @axlrose for [#246](https://github.com/saya-ch/dsh-mobile/issues/246).
|
|
11
|
+
- Add limited, credential-free diagnostics for the Gateway's authentication exchange with local DSH, separate from phone-side authorization failures.
|
|
12
|
+
- Update development bundler dependencies to address Windows editor-launch security advisories; runtime authentication and model routing are unchanged.
|
|
13
|
+
- Thanks @Void-LifeStream for the startup and reload report in [#243](https://github.com/saya-ch/dsh-mobile/issues/243). This release improves module updates and diagnostics; the complete reported symptom sequence remains unconfirmed.
|
|
14
|
+
|
|
15
|
+
## Android 0.6.6 - 2026-10-21
|
|
16
|
+
|
|
17
|
+
- Prevent repeated automatic recovery while renewal or Cookie installation is already pending, and serialize background restore work for the same credential until the previous worker exits.
|
|
18
|
+
- Keep cancellation and the overall connection deadline effective for queued work and late results, without clearing existing pairing data.
|
|
19
|
+
- Publish independently as App 0.6.6 (build 82). The pairing protocol and package identity remain unchanged; these native fixes require an App update and are not installed by updating the npm plugin.
|
|
20
|
+
|
|
21
|
+
## 0.6.14 - 2026-10-21
|
|
22
|
+
|
|
23
|
+
- 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.
|
|
24
|
+
- 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).
|
|
25
|
+
- 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).
|
|
26
|
+
- Add separate bug-report and feature-request forms with environment, reproduction, expected/actual behavior and third-party plugin comparison prompts.
|
|
27
|
+
- 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.
|
|
28
|
+
- Android App remains independently published as 0.6.5 (build 81); no native changes or new APK are included.
|
|
29
|
+
|
|
5
30
|
## 0.6.13 - 2026-10-19
|
|
6
31
|
|
|
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.
|
|
32
|
+
- 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
33
|
- 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
|
|
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.
|
|
34
|
+
- 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
35
|
- 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
36
|
|
|
14
37
|
## 0.6.12 - 2026-10-18
|
package/CONTRIBUTORS.md
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
1
|
# 贡献者 / Contributors
|
|
2
2
|
|
|
3
|
-
GitHub 的 [Contributors 图表](https://github.com/saya-ch/dsh-mobile/graphs/contributors) 按进入默认分支的提交自动统计,无法手动加入仅提交 issue 或 PR 提案的成员。本页按截至 2026-10-
|
|
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-
|
|
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.15 反馈 / Reports for 0.6.15
|
|
8
|
+
|
|
9
|
+
感谢 [@axlrose](https://github.com/axlrose) 在 [#246](https://github.com/saya-ch/dsh-mobile/issues/246) 提供 Firefox 管理请求被拒的复现线索,促成 0.6.15 对缺少来源头场景的兼容与跨站拒绝测试。
|
|
10
|
+
|
|
11
|
+
Thanks [@axlrose](https://github.com/axlrose) for the Firefox management-request rejection report in [#246](https://github.com/saya-ch/dsh-mobile/issues/246), informing compatibility for omitted source headers and cross-origin rejection tests in 0.6.15.
|
|
12
|
+
|
|
13
|
+
感谢 [@Void-LifeStream](https://github.com/Void-LifeStream) 在 [#243](https://github.com/saya-ch/dsh-mobile/issues/243) 反馈启动、重载和会话显示问题,推动本轮模块通知、Android 自动恢复与诊断检查。插件 0.6.15 和 App 0.6.6 分别包含相关改进,不代表该报告中的全部现象已复现或解决。
|
|
14
|
+
|
|
15
|
+
Thanks [@Void-LifeStream](https://github.com/Void-LifeStream) for reporting startup, reload and session-display problems in [#243](https://github.com/saya-ch/dsh-mobile/issues/243), prompting the module-notification, Android recovery and diagnostic investigation. Related improvements belong to plugin 0.6.15 and App 0.6.6 independently; not every reported symptom has been reproduced or resolved.
|
|
16
|
+
|
|
17
|
+
## 0.6.14 代码贡献与反馈 / Code contributions and reports for 0.6.14
|
|
18
|
+
|
|
19
|
+
[@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 反代需求。
|
|
20
|
+
|
|
21
|
+
[@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
22
|
|
|
7
23
|
## 0.6.12 问题定位 / Issue findings for 0.6.12
|
|
8
24
|
|
|
@@ -107,7 +123,9 @@ Thanks [@xhwxt](https://github.com/xhwxt) for the document-picker proposal in [#
|
|
|
107
123
|
| [@CharlesLueng](https://github.com/CharlesLueng) | [#68](https://github.com/saya-ch/dsh-mobile/issues/68) |
|
|
108
124
|
| [@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
125
|
| [@chmzs](https://github.com/chmzs) | [#73](https://github.com/saya-ch/dsh-mobile/issues/73) |
|
|
126
|
+
| [@faruzanCN](https://github.com/faruzanCN) | [#238](https://github.com/saya-ch/dsh-mobile/issues/238) |
|
|
110
127
|
| [@gjzbbs](https://github.com/gjzbbs) | [#123](https://github.com/saya-ch/dsh-mobile/issues/123) |
|
|
128
|
+
| [@gugubb5](https://github.com/gugubb5) | [#237](https://github.com/saya-ch/dsh-mobile/issues/237) |
|
|
111
129
|
| [@fishdivinity](https://github.com/fishdivinity) | [#202](https://github.com/saya-ch/dsh-mobile/issues/202) |
|
|
112
130
|
| [@hairyf](https://github.com/hairyf) | [#114](https://github.com/saya-ch/dsh-mobile/issues/114) |
|
|
113
131
|
| [@helan-1997](https://github.com/helan-1997) | [#168](https://github.com/saya-ch/dsh-mobile/issues/168) |
|
package/README.en.md
CHANGED
|
@@ -26,20 +26,20 @@
|
|
|
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.
|
|
29
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.15">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.
|
|
35
|
+
> **Current stable release: 0.6.15**. Improve mobile-page plugin-update notifications, support same-origin Blob media and management actions under Firefox privacy settings, and add connection diagnostics. Independently released Android App **0.6.6** improves automatic recovery and cancellation. [Plugin release notes and downloads](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.15) · [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
|
|
|
39
39
|
<p align="center">
|
|
40
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.6.
|
|
41
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.6.
|
|
42
|
-
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.6.
|
|
40
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.6.6/dsh-mobile-android-v0.6.6.apk"><img src="https://raw.githubusercontent.com/saya-ch/dsh-mobile/main/assets/brand/app-icon-rounded.svg" alt="DSH Mobile Android app icon" width="72" height="72"></a><br>
|
|
41
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.6.6/dsh-mobile-android-v0.6.6.apk"><strong>Download Android app 0.6.6</strong></a><br>
|
|
42
|
+
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.6.6">Release notes and checksums</a></sub>
|
|
43
43
|
</p>
|
|
44
44
|
|
|
45
45
|
DSH Mobile is a DeepSeek Harness plugin that lets a mobile browser or the Android app connect over a protected LAN or an optional Tailscale Funnel, cpolar, cloudflared, self-hosted FRP, or own reverse-proxy remote path. Both routes reach the same sessions, Workspaces, messages, and tools. The computer manages their switches and pairing authorizations separately; the Android app lists paired computers together. The plugin does not modify DeepSeek Harness source.
|
|
@@ -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
|
-
|
|
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,20 +26,20 @@
|
|
|
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.
|
|
29
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.15">更新记录</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.
|
|
35
|
+
> **当前正式版本:0.6.15**。改善移动页面的插件更新通知,兼容同源 Blob 音视频与 Firefox 隐私设置下的管理操作,并补充连接诊断。Android App **0.6.6** 独立发布,改善自动重连与取消。[插件更新与下载](https://github.com/saya-ch/dsh-mobile/releases/tag/v0.6.15) · [完整更新记录](CHANGELOG.md)。
|
|
36
36
|
>
|
|
37
37
|
> **版本说明**:自插件 **0.6.2** 起,Android App 与插件独立编号、独立发布,版本号无需一致;插件升级不代表 App 需要同步升级。[兼容说明](#兼容性)。
|
|
38
38
|
|
|
39
39
|
<p align="center">
|
|
40
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.6.
|
|
41
|
-
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.6.
|
|
42
|
-
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.6.
|
|
40
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.6.6/dsh-mobile-android-v0.6.6.apk"><img src="https://raw.githubusercontent.com/saya-ch/dsh-mobile/main/assets/brand/app-icon-rounded.svg" alt="DSH Mobile 安卓应用图标" width="72" height="72"></a><br>
|
|
41
|
+
<a href="https://github.com/saya-ch/dsh-mobile/releases/download/android-v0.6.6/dsh-mobile-android-v0.6.6.apk"><strong>下载 Android App 0.6.6</strong></a><br>
|
|
42
|
+
<sub><a href="https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.6.6">版本说明与校验文件</a></sub>
|
|
43
43
|
</p>
|
|
44
44
|
|
|
45
45
|
DSH Mobile 是一个 DeepSeek Harness 插件,让手机浏览器或 Android App 通过局域网,或可选的 Tailscale Funnel、cpolar、cloudflared、自建 FRP 或自有反向代理远程通道连接电脑,继续使用同一份会话、工作区、消息和工具。电脑端分别启停局域网与远程访问、分别管理配对授权;Android App 统一显示已配对电脑。插件不修改 DeepSeek Harness 源码。
|
|
@@ -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
|
|
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
|
-
|
|
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
|
@@ -18,7 +18,9 @@ The maintainer will acknowledge a complete report within seven days. Publication
|
|
|
18
18
|
|
|
19
19
|
- Keep the ordinary DSH Web listener on loopback.
|
|
20
20
|
- Expose only the plugin-owned HTTPS listener to the LAN.
|
|
21
|
-
- The desktop admin API may accept an RFC1918 or IPv4 link-local Host only when the TCP peer is loopback, for a trusted local reverse proxy or headless host. Do not publicly forward `/api/mobile-access`; Host and loopback checks are not a replacement for proxy access control.
|
|
21
|
+
- The desktop admin API may accept an RFC1918 or IPv4 link-local Host only when the TCP peer is loopback, for a trusted local reverse proxy or headless host. Do not publicly forward `/api/mobile-access`; Host and loopback checks are not a replacement for proxy access control.
|
|
22
|
+
- Mutating Web admin requests normally require a same-origin `Origin`. When a browser omits it, the plugin accepts only a JSON POST with its exact non-simple Web marker and absent or `same-origin` Fetch Metadata. Explicit foreign Origins/sites remain rejected. This marker is not a credential: its CSRF protection relies on browser CORS enforcement and the management prefix refusing OPTIONS without CORS permission. A trusted reverse proxy must not answer allowed CORS preflights or inject CORS authorization for `/api/mobile-access`.
|
|
23
|
+
- Official DSH Desktop uses a separate path: its forwarder strips `Origin` and `Sec-Fetch-Site` and supplies a signed Host browser-session Cookie. The plugin requires both its separate Desktop marker and Connection's successful browser-session verification before accepting an Origin-less Desktop write. The Web marker cannot replace that authentication.
|
|
22
24
|
### Discovery, pairing and TLS
|
|
23
25
|
|
|
24
26
|
- DNS-SD/mDNS, periodic UDP announcements, active UDP query replies, and HTTPS discovery return only the device name, public HTTPS origin, port, protocol version, and stable non-secret installation identifier. Discovery never returns the CA, a pairing key, a device token, Cookies, credentials, or private configuration.
|
|
@@ -50,7 +52,7 @@ The maintainer will acknowledge a complete report within seven days. Publication
|
|
|
50
52
|
- 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
53
|
- 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
54
|
- 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
|
-
-
|
|
55
|
+
- 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
56
|
- 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
57
|
- 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
58
|
- 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.
|
|
@@ -70,6 +72,7 @@ The maintainer will acknowledge a complete report within seven days. Publication
|
|
|
70
72
|
### Framed content and browser policy
|
|
71
73
|
|
|
72
74
|
- Proxied GUI responses allow HTTP iframe sources for compatibility with community surfaces. HTTP content is unauthenticated and unencrypted; Android still blocks mixed HTTP content inside HTTPS pages, and browsers may block it too. Prefer HTTPS and do not treat a gateway framing allowance as a transport-security guarantee.
|
|
75
|
+
- Proxied GUI responses allow same-origin and Blob audio/video through `media-src 'self' blob:`; Gateway-owned login and pairing pages do not gain Blob media permission. External media and connections remain restricted. This permits a trusted page plugin to play a same-origin file fetched into an object URL; it does not bypass browser codec support or autoplay rules. Android retains its media user-gesture requirement. Media plugins should provide a visible poster and a user-initiated playback fallback rather than assume autoplay always succeeds.
|
|
73
76
|
|
|
74
77
|
## Known limitation
|
|
75
78
|
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -16,7 +16,7 @@ The optional [cloudflared](https://github.com/cloudflare/cloudflared) client is
|
|
|
16
16
|
|
|
17
17
|
The optional managed Caddy component is not included in the npm package or Android App. Since plugin 0.6.9, users on Windows/Linux x64 can explicitly confirm an on-demand download of the fixed [DSH Mobile component distribution](https://github.com/saya-ch/dsh-mobile/releases/tag/caddy-component-2.11.7-tencentcloud-0.4.3-r1); its source, exact size and SHA-256 are pinned in the plugin. This distribution builds [Caddy v2.11.7](https://github.com/caddyserver/caddy/blob/v2.11.7/LICENSE), under Apache License 2.0, with [caddy-dns/tencentcloud v0.4.3](https://github.com/caddy-dns/tencentcloud/blob/v0.4.3/LICENSE), under the MIT License. The component release supplies each platform's exact embedded dependency manifest, Go build metadata and complete third-party license/notice texts as separate assets. It is a DSH Mobile build, not an upstream Caddy release or a dynamically generated download. Existing user-managed proxies are separate from this optional component.
|
|
18
18
|
|
|
19
|
-
The npm package declares direct runtime dependencies on [Schemastery](https://github.com/shigma/schemastery) `^3.18.1`, [@noble/hashes](https://github.com/paulmillr/noble-hashes) `1.8.0`, [bonjour-service](https://github.com/onlxltd/bonjour-service) `1.4.4`, [qrcode](https://github.com/soldair/node-qrcode) `^1.5.4`, [selfsigned](https://github.com/jfromaniello/selfsigned) `^5.5.0`, and [ws](https://github.com/websockets/ws) `8.22.0`. These packages are distributed under the MIT License; the release checkout's exact transitive versions appear in the attached CycloneDX npm SBOM.
|
|
19
|
+
The npm package declares direct runtime dependencies on [Schemastery](https://github.com/shigma/schemastery) `^3.18.1`, [@noble/hashes](https://github.com/paulmillr/noble-hashes) `1.8.0`, [bonjour-service](https://github.com/onlxltd/bonjour-service) `1.4.4`, [eventsource-parser](https://github.com/rexxars/eventsource-parser) `3.1.0`, [qrcode](https://github.com/soldair/node-qrcode) `^1.5.4`, [selfsigned](https://github.com/jfromaniello/selfsigned) `^5.5.0`, and [ws](https://github.com/websockets/ws) `8.22.0`. These packages are distributed under the MIT License; the release checkout's exact transitive versions appear in the attached CycloneDX npm SBOM.
|
|
20
20
|
|
|
21
21
|
The Android App runtime contains [Kotlin standard library](https://github.com/JetBrains/kotlin) `2.1.0`, [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines) `1.6.4`, [JetBrains annotations](https://github.com/JetBrains/java-annotations) `13.0`, [AndroidX Core](https://developer.android.com/jetpack/androidx/releases/core) `1.15.0`, [AndroidX WebKit](https://developer.android.com/jetpack/androidx/releases/webkit) `1.17.1`, their AndroidX transitive components, [Guava listenablefuture](https://github.com/google/guava) `1.0`, and [ZXing Core](https://github.com/zxing/zxing) `3.5.4`. These runtime libraries are distributed under the Apache License 2.0; the exact resolved tree is attached to each release as `dsh-mobile-android-v<version>-dependencies.txt`.
|
|
22
22
|
|
|
@@ -48,9 +48,37 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
48
48
|
THE SOFTWARE.
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
## Event-stream parsing
|
|
52
|
+
|
|
53
|
+
The Gateway uses eventsource-parser for Server-Sent Events framing. Its MIT license is included below:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
MIT License
|
|
57
|
+
|
|
58
|
+
Copyright (c) 2026 Espen Hovlandsdal <espen@hovlandsdal.com>
|
|
59
|
+
|
|
60
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
61
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
62
|
+
in the Software without restriction, including without limitation the rights
|
|
63
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
64
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
65
|
+
furnished to do so, subject to the following conditions:
|
|
66
|
+
|
|
67
|
+
The above copyright notice and this permission notice shall be included in all
|
|
68
|
+
copies or substantial portions of the Software.
|
|
69
|
+
|
|
70
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
71
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
72
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
73
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
74
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
75
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
76
|
+
SOFTWARE.
|
|
77
|
+
```
|
|
78
|
+
|
|
51
79
|
## core-js browser compatibility bundle
|
|
52
80
|
|
|
53
|
-
The standalone `lib/mobile-compat.js` bundles selected Iterator
|
|
81
|
+
The standalone `lib/mobile-compat.js` bundles selected compatibility modules, including Iterator, `Promise.withResolvers`, collection methods and structured cloning, from [core-js](https://github.com/zloirock/core-js) `^3.50.0` (exact version recorded in `package-lock.json`). It is built into the npm package; browsers do not download a polyfill from a CDN. core-js is distributed under the following MIT License:
|
|
54
82
|
|
|
55
83
|
```text
|
|
56
84
|
Copyright (c) 2013–2025 Denis Pushkarev (zloirock.ru)
|
package/apps/mobile/README.md
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
DeepSeek Harness is the display name of this community-maintained Android WebView app. It opens the plugin's authenticated HTTPS page rather than bundling another DSH frontend. The app and mobile browsers receive the same DSH features and computer-side mobile customizations.
|
|
6
6
|
|
|
7
|
-
The current stable app is **0.6.
|
|
7
|
+
The current stable app is **0.6.6** (build 82). The npm plugin and Android App have independent versions: a plugin update does not automatically require another APK. See the [0.6.6 changes](#066-update).
|
|
8
8
|
|
|
9
9
|
Android 10 or later is supported. The local iOS experiment is not a published or supported client.
|
|
10
10
|
|
|
11
11
|
## Install and pair
|
|
12
12
|
|
|
13
13
|
1. Install and enable the plugin using the [project quick start](../../README.en.md#quick-start). Complete LAN setup from the command line or the computer's **Mobile Access** panel.
|
|
14
|
-
2. Install the signed Android APK from [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.6.
|
|
14
|
+
2. Install the signed Android APK from [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.6.6). Upgrade an official installation in place using the same release signer to retain its pairings. A differently signed Debug APK cannot replace it; do not uninstall or clear data just to bypass that mismatch.
|
|
15
15
|
3. On the computer, generate a pairing key/link under **Mobile Access → Local network**, or configure a remote provider and generate its remote pairing QR code. In the app, choose the matching connection mode and scan or paste the link.
|
|
16
16
|
4. Name the computer. The app stores each LAN or remote pairing as its own record. The phone does not need a cpolar, Cloudflare or Tailscale app.
|
|
17
17
|
|
|
@@ -35,6 +35,12 @@ Page zoom changes the whole page and is separate from per-address text preferenc
|
|
|
35
35
|
|
|
36
36
|
Deleting a local record removes its saved token and pinned CA, not the computer's authorization or every short-lived WebView cookie. Use **Mobile Access** on the computer to revoke access immediately. A full Android clear-app-data reset removes all pairings and web data and is not a normal reconnection step.
|
|
37
37
|
|
|
38
|
+
## 0.6.6 update
|
|
39
|
+
|
|
40
|
+
Android 0.6.6/build 82 prevents repeated automatic recovery while renewal or Cookie installation is already pending. Background restore work for the same credential waits for the previous worker to exit instead of overlapping it.
|
|
41
|
+
|
|
42
|
+
Cancellation and the connection deadline withdraw queued work and late results so an older recovery cannot replace a newer action. Existing pairings, package identity and the pairing protocol are unchanged; no data reset or re-pairing is required for this update. Network availability and recovery of an unsaved webpage still depend on the connection and WebView state.
|
|
43
|
+
|
|
38
44
|
## 0.6.5 update
|
|
39
45
|
|
|
40
46
|
Android 0.6.5/build 81 adds an immediate **Cancel connection** action during startup, saved-computer connection, LAN scanning and pairing. Cancellation returns to the device list or editable form without deleting existing pairings. **Stop reconnecting** retains a usable DSH page; a blank or failed document returns to the list.
|
|
@@ -120,12 +126,12 @@ Set-Location apps/mobile/android
|
|
|
120
126
|
|
|
121
127
|
The Debug APK is `app/build/outputs/apk/debug/app-debug.apk`. Official releases use the established signing key stored only in repository Secrets. A local unsigned Release build or a Debug install is not official-signer evidence.
|
|
122
128
|
|
|
123
|
-
The verified stable release is [Android 0.6.
|
|
129
|
+
The verified stable release is [Android 0.6.6](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.6.6), build 82, SHA-256 `a63fb40da261d290d4435d713258b508be3e4f0592d223a325dca1a5b32f3c95`. The downloaded APK retains the established release signer and package `io.github.sayach.dshmobile`. Earlier release history belongs in [CHANGELOG](../../CHANGELOG.md).
|
|
124
130
|
|
|
125
131
|
## Acceptance and known limits
|
|
126
132
|
|
|
127
133
|
- Connection-control development builds used Debug metadata 0.6.4/build 80 on PJW110, Android 16 and Google WebView 153.0.8010.36. Against an isolated DSH 0.2.0-rc.2/plugin 0.6.10 instance over USB and pinned HTTPS, checks covered pairing/startup/saved-connection cancellation, Back, failed manual connections and return from a failed page after stopping native recovery. Held module responses also verified early webpage display, touch-through outside compact cancellation, cancellation and later completion. Pairings were retained and owned QA records removed.
|
|
128
134
|
- Debug builds of App 0.6.4 retained one WebView across document replacement/reload, rejected an old selection, and received controlled PNG bytes with a decoded DSH draft preview. A held navigation and HTTP 204 also checked selector availability. Earlier checks covered model-menu Back, rotation with draft/reference/image retention, known revocation, re-pairing, icon choices and list ordering. None required a model prompt.
|
|
129
|
-
- These observations do not establish final
|
|
135
|
+
- These observations do not establish final official-signer APK device acceptance, every public provider, remote 60-second timing, full native recovery with a still-live draft, HyperOS/older WebViews or every screen/gesture configuration. Self-signed FRP still lacks a recorded real-VPS-plus-phone end-to-end check. Permission grants alone do not establish voice transcription, and process-death restoration is not guaranteed.
|
|
130
136
|
|
|
131
137
|
Apache-2.0 licensed. See [LICENSE](../../LICENSE).
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
DeepSeek Harness 是这个社区维护的 Android WebView App 的显示名称。它直接打开插件提供的已认证 HTTPS 页面,不打包另一套 DSH 前端;App 与手机浏览器获得相同的 DSH 功能,以及电脑端配置的移动页面定制。
|
|
6
6
|
|
|
7
|
-
当前正式 App 为 **0.6.
|
|
7
|
+
当前正式 App 为 **0.6.6**;构建号为 82。npm 插件与 Android App 独立编号、独立更新;插件升级不代表需要重新安装 APK。此次改进见 [0.6.6 更新](#066-更新)。
|
|
8
8
|
|
|
9
9
|
支持 Android 10 及以上系统。iOS 本地实验不属于已发布或受支持的客户端。
|
|
10
10
|
|
|
11
11
|
## 安装与配对
|
|
12
12
|
|
|
13
13
|
1. 按[项目快速开始](../../README.md#快速开始)安装并启用插件。局域网配置可通过命令行或电脑端的 **移动访问** 面板完成。
|
|
14
|
-
2. 从 [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.6.
|
|
14
|
+
2. 从 [GitHub Releases](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.6.6) 安装已签名 APK。正式版沿用相同发布签名,可原位升级并保留配对;不同签名的 Debug 包不能直接覆盖正式版,不要为绕过签名不匹配而卸载或清除数据。
|
|
15
15
|
3. 在电脑 **移动访问 → 局域网访问** 中生成密钥/配对链接,或配置远程通道并生成远程配对二维码。在 App 选择对应方式,扫码或粘贴链接。
|
|
16
16
|
4. 为电脑命名。每条局域网或远程配对单独保存;手机无需安装 cpolar、Cloudflare 或 Tailscale App。
|
|
17
17
|
|
|
@@ -35,6 +35,12 @@ DeepSeek Harness 是这个社区维护的 Android WebView App 的显示名称。
|
|
|
35
35
|
|
|
36
36
|
删除本机记录会移除保存的设备令牌和固定 CA,不等于撤销电脑授权或清除所有 WebView 短期 Cookie。需要立即终止访问时,请在电脑的 **移动访问** 中撤销设备。Android“清除应用数据”会删除全部配对和网页数据,不是普通重连的处理步骤。
|
|
37
37
|
|
|
38
|
+
## 0.6.6 更新
|
|
39
|
+
|
|
40
|
+
Android 0.6.6/构建 82 避免续期或安装 Cookie 尚未完成时重复触发自动恢复。同一凭据的后台恢复会等待上一项任务真正退出,不再重叠执行。
|
|
41
|
+
|
|
42
|
+
取消和连接总期限会撤销排队任务及迟到结果,避免旧恢复覆盖新的操作。已有配对、包名和配对协议保持不变,升级无需清除数据或重新配对;网络是否可达、未保存网页能否恢复,仍取决于连接与 WebView 状态。
|
|
43
|
+
|
|
38
44
|
## 0.6.5 更新
|
|
39
45
|
|
|
40
46
|
Android 0.6.5/构建 81 在启动连接、已配对电脑连接、局域网扫描和配对过程中均提供立即可用的 **取消连接**。取消后回到设备列表或可编辑表单,不删除原有配对;**停止重连**保留仍可用的 DSH 页面,空白或失效文档则返回列表。
|
|
@@ -120,12 +126,12 @@ Set-Location apps/mobile/android
|
|
|
120
126
|
|
|
121
127
|
Debug APK 位于 `app/build/outputs/apk/debug/app-debug.apk`。正式发布沿用只保存在仓库 Secrets 中的签名密钥,本地未签名 Release 构建或 Debug 安装不能替代正式签名核验。
|
|
122
128
|
|
|
123
|
-
已核验的正式版本为 [Android 0.6.
|
|
129
|
+
已核验的正式版本为 [Android 0.6.6](https://github.com/saya-ch/dsh-mobile/releases/tag/android-v0.6.6),构建 82,SHA-256:`a63fb40da261d290d4435d713258b508be3e4f0592d223a325dca1a5b32f3c95`。下载的 APK 沿用正式发布签名及包名 `io.github.sayach.dshmobile`。旧版本历史集中在 [CHANGELOG](../../CHANGELOG.md)。
|
|
124
130
|
|
|
125
131
|
## 验收与已知限制
|
|
126
132
|
|
|
127
133
|
- 连接控制的开发包使用 Debug 元数据 0.6.4/构建 80,在 PJW110、Android 16、Google WebView 153.0.8010.36 上,通过 USB 和固定 CA 的 HTTPS 连接隔离的 DSH 0.2.0-rc.2/插件 0.6.10。检查了配对/启动/已保存连接取消、系统返回、手动失败收尾,以及停止原生恢复后从失效页面返回;暂停模块响应时也验证了提前露出网页、非按钮区域触摸透传、取消和放行后完成。原配对保留,临时 QA 记录已清理。
|
|
128
134
|
- App 0.6.4 的 Debug 构建在同一 WebView 中覆盖文档替换/刷新、拒绝旧选择、接收受控 PNG 字节并形成已解码草稿预览;还检查了暂停导航及 HTTP 204 后选择器的可用性。更早的检查覆盖模型菜单返回、旋转保留草稿/引用/图片、已知撤销、重新配对、图标选择与列表顺序,均未发送模型请求。
|
|
129
|
-
-
|
|
135
|
+
- 这些观察不代表最终正式签名 APK 已完成真机验收,也不覆盖所有公网提供方、远程 60 秒期限、保留活动草稿的完整原生恢复、HyperOS/旧 WebView 或所有屏幕/手势组合。自签 FRP 尚无真实 VPS 加手机的端到端验收记录;权限授予不代表语音转写成功,进程终止后的状态恢复也不作保证。
|
|
130
136
|
|
|
131
137
|
Apache-2.0 licensed. See [LICENSE](../../LICENSE).
|
package/apps/mobile/release.json
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
| 私有监听
|
|
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
|
|
35
|
+
公网地址只能是 HTTPS Origin,可带非 443 端口;不包含路径、账号密码、查询参数或 fragment。域名可以通过 A/AAAA 记录提供 IPv4、IPv6 或双栈访问;私有/保留 IP、本地域名和 IPv6 字面地址不适用于公网地址字段。
|
|
36
36
|
|
|
37
|
-
|
|
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
|
|
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
|
|
114
|
+
- **监听地址不可用**:填写 DSH 本机当前回环、私有 IPv4 或 ULA,不是代理机器的 IP;公网入口能走 IPv6 不代表本机已分配 ULA。
|
|
87
115
|
- **被拒绝 / 403**:核对直接来源 CIDR、完整外部 Host 和 HTTPS Origin;伪造转发头不会绕过这些检查。
|
|
88
116
|
- **HTTP 页面可开但实时功能失败**:核对代理 WebSocket 转发、超时及路径白名单,不要通过关闭来源验证来排错。
|
|
89
117
|
- **只有“后端已监听”**:这是预期语义;继续检查公网 DNS、端口映射到 HTTPS 代理、证书及手机实际访问。
|