Implement PoC webview-based WEB transport.

This commit is contained in:
John Preston
2026-08-11 10:54:52 +04:00
parent 359e533b2a
commit 979e116a23
12 changed files with 1038 additions and 204 deletions

View File

@@ -7,9 +7,9 @@ the loopback fragment capability in logs or screenshots.
## 1. Release gate
WEB is ready for wider testing only when all P0 and P1 cases below pass on at least
one Chromium browser and the supported browser/platform matrix has no unexplained
P0 failure.
WEB is ready for wider testing only when all P0 and P1 cases below pass through the
native WebView on every supported desktop platform, and the explicit
system-browser fallback has no unexplained P0 failure in its browser matrix.
Severity:
@@ -57,14 +57,14 @@ an incompatible bridge.
cmake --build out --config Debug --target Telegram
```
2. Record the commit, build timestamp, OS version, browser name/version, and whether
the browser is managed by enterprise policy.
2. Record the commit, build timestamp, OS version, native WebView engine/version,
fallback browser name/version, and whether either is managed by enterprise policy.
3. Use a disposable Telegram test account and a separate portable/test profile. Do
not overwrite an existing personal portable profile.
4. Preserve Debug logs for the run, but verify they contain no proxy secret or frame
payload.
5. Start with all browser developer tools closed; opening DevTools changes background
throttling and would invalidate lifecycle observations.
5. Start with WebView inspection and browser developer tools closed; either changes
scheduling and would invalidate lifecycle observations.
6. Disable unrelated VPNs/proxies for baseline. Record DNS-over-HTTPS, browser proxy,
and system proxy state.
@@ -113,27 +113,30 @@ configuration. Keep sanitized headers with the run artifacts.
- empty hostname or secret.
6. Save the valid entry and enable it.
7. Confirm exactly one default-browser tab opens at a numeric
`http://127.0.0.1:<ephemeral>/#<capability>` URL.
8. Confirm the fragment disappears immediately and the page says it is connecting.
9. Confirm the settings row moves through `waiting for browser` / `connecting…` to
`online` and the tab says it is connected.
10. Confirm Telegram loads dialogs and receives updates.
7. Confirm no system-browser tab opens.
8. Confirm exactly one hidden platform WebView loads
`https://<canonical-host>/?bridge=<43-char-capability>#android=<43-char-nonce>`.
9. Confirm the settings row moves from `connecting` to `online` within ten seconds.
10. Confirm Telegram loads dialogs and receives updates without a Telegram WebView
window, Qt widget container, taskbar item, or dock item appearing.
Pass conditions:
- no crash, assertion, TLS warning, CORS/LNA prompt, mixed-content error, or iframe
refusal;
- server sees one relay session and the expected MTProxy stream connections;
- the iframe requests exactly `https://<canonical-host>/?bridge=<43-char-capability>`;
- the browser page, DOM, network request headers, and console never contain the
- the WebView requests exactly the canonical bridge URL and then scrubs its query
and fragment from history;
- the page, DOM, network request headers, and console never contain the
MTProxy secret;
- closing proxy settings does not affect the connection.
Repeat once with a profile secret that is valid MTProxy syntax but is not configured
on staging. The ordinary-site fallback must match other root responses, and the
client must leave `connecting…` for `not available` within 30 seconds rather than
waiting forever.
on staging. The ordinary-site fallback must match other root responses. Within ten
seconds the client must stop showing only `connecting…`, offer to open the proxy page
in the browser, and keep retrying the hidden WebView every 30 seconds. Cancel the
offer and confirm no browser opens; then accept it and confirm exactly one numeric
`http://127.0.0.1:<ephemeral>/#<capability>` tab opens.
## 6. Network-origin invariant (P0)
@@ -148,14 +151,19 @@ Also capture a short packet trace or firewall connection log if permitted.
Verify:
- Telegram Desktop connects to `127.0.0.1:<ephemeral>` only for this transport;
- Telegram Desktop has no external connection to the relay origin, stock MTProxy,
or Telegram DCs for MTProto traffic;
- in the primary mode, Telegram Desktop's WebView/WebContent process owns the HTTPS
connection to the relay and no loopback WebSocket is connected;
- Telegram's ordinary MTProto sockets have no external connection to the relay,
stock MTProxy, or Telegram DCs; the relay connection belongs only to the platform
WebView engine;
- a WEB connection failure does not trigger tdesktop's HTTP time-sync fallback;
- the browser process owns the external HTTPS connection to the relay;
- DNS resolution of the relay is attributable to the browser/system resolver, not a
- DNS resolution of the relay is attributable to the WebView/system resolver, not a
custom proxy/DC resolver in tdesktop;
- external carrier traffic remains inside the browser-owned TLS connection.
- external carrier traffic remains inside the WebView-owned TLS connection.
Repeat after explicitly accepting browser fallback. In that mode Telegram Desktop
must connect only to `127.0.0.1:<ephemeral>` for this transport, and the browser must
own the external HTTPS connection to the relay.
Account for unrelated Telegram HTTP traffic such as update checks before declaring
a failure. The invariant applies to the MTProto transport, not every auxiliary HTTP
@@ -180,7 +188,7 @@ For large transfers record:
- bytes and final content hash;
- average and minimum throughput;
- tdesktop, browser, and relay peak memory;
- tdesktop, WebView/WebContent, fallback browser when used, and relay peak memory;
- number of logical streams and stock-MTProxy sockets;
- reconnect/retry count;
- pending-uplink overflow or flow-control errors.
@@ -188,8 +196,9 @@ For large transfers record:
Run the same payload once through direct MTProxy and once through tdesktop's built-in
HTTP transport under the same controlled capacity/RTT when those controls are
reachable. On a controlled link with at least 100 Mbit/s capacity, WEB should
sustain at least 40 Mbit/s at 200 ms browser-to-relay RTT and 20 Mbit/s at 500 ms,
in both a foreground and an ordinarily hidden tab on each supported browser.
sustain at least 40 Mbit/s at 200 ms web-engine-to-relay RTT and 20 Mbit/s at 500 ms,
through the hidden WebView. Repeat the browser-specific target with the fallback tab
in both foreground and ordinarily hidden states.
Also report WEB/direct-HTTP ratios for message round-trip p50/p95 and bulk transfer;
route differences must be reported separately from transport overhead.
@@ -203,8 +212,8 @@ memory without returning toward baseline after completion.
3. Start a large upload at the same time.
4. If multi-account is available, sign in to two disposable accounts and generate
traffic on both.
5. Confirm all logical streams use the same authenticated local WebSocket and browser
relay session.
5. Confirm all logical streams use the same native bridge and relay session. Repeat
through fallback and confirm one authenticated local WebSocket/browser session.
6. Confirm one slow or window-exhausted stream does not block unrelated streams.
7. Cancel half the transfers and verify the corresponding `CLOSE`s release relay and
stock-MTProxy resources.
@@ -220,35 +229,47 @@ failure notifications. Run it under ASan and TSan where supported. No notificati
may begin after synchronous stream unregistration returns, and no callback may run
against a socket whose destructor has started.
## 9. Browser and transport lifecycle (P0/P1)
## 9. WebView, browser, and transport lifecycle (P0/P1)
The Settings code `externalweb` toggles a process-local test override. The first
invocation blocks and tears down the hidden WebView carrier; the second removes the
block and starts a fresh WebView candidate immediately. Each invocation shows its
new state in a toast. Use it to drive the fallback and recovery cases without
changing the proxy or network.
Execute each case from a connected baseline:
| Case | Expected result |
|---|---|
| Close the sidecar tab | all logical sockets disconnect; row says waiting; no tab auto-reopens |
| Row menu -> Open browser | fresh fragment capability; new tab authenticates; Telegram reconnects |
| Refresh the tab | consumed capability is not reusable; row says waiting; `Open browser` restores the connection with a fresh capability |
| Open browser twice | newest authenticated tab replaces the old one; no stream crosses sessions |
| Quit browser | same as tab loss; tdesktop remains responsive |
| Restart browser and use Open browser | clean reconnection |
| Restart tdesktop with WEB saved/enabled | new loopback port/token and one new tab; stale old tab cannot attach |
| Disable WEB | listener closes, browser loses local WS, normal connection policy resumes |
| Initial WebView cannot be created | fallback is offered; no browser opens without confirmation; retry begins after 30 seconds |
| Initial WebView handshake stalls | fallback is offered after ten seconds; no permanent spinner |
| Active WebView stops answering probes | logical sockets disconnect; fallback is offered after at most ten seconds |
| Cancel fallback offer | no browser opens; hidden WebView retries continue every 30 seconds |
| Confirm fallback offer | fresh fragment capability; one tab authenticates; Telegram reconnects |
| WebView retry succeeds during fallback | browser carrier closes only after WebView `WELCOME`; logical sockets reconnect through WebView |
| Close the fallback tab | fallback sockets disconnect; no tab auto-reopens; WebView retries continue |
| Refresh the fallback tab | consumed capability is not reusable; another explicit `Open browser` uses a fresh capability |
| Quit browser | same as fallback-tab loss; tdesktop remains responsive |
| Restart browser and use Open browser | clean fallback reconnection |
| Restart tdesktop with WEB saved/enabled | one hidden WebView starts; no browser tab opens; stale fallback tab cannot attach |
| Disable WEB | WebView, listener, and fallback socket close; normal connection policy resumes |
| Switch WEB A -> non-WEB -> WEB A | clean teardown and reactivation |
| Edit WEB hostname or secret | old transport closes; new settings take effect; no old relay traffic remains |
| System sleep 5 minutes | reconnect after wake without corruption or permanent spinner |
| Network down/up | browser carrier and MTProto recover within normal retry bounds |
| Network down/up | WebView carrier and MTProto recover within normal retry bounds or offer fallback |
| RTC unavailable or disabled by browser policy | carrier remains usable; lifecycle guard failure is silent and bounded |
For Chromium browsers, confirm the page has one open `RTCDataChannel` between two
same-page peer connections in `chrome://webrtc-internals`, with the selected ICE
pair confined to `127.0.0.1` and no STUN or TURN server. In `chrome://discards`,
record the tab's automatic freeze/discard eligibility and reasons; active WebRTC
record the fallback tab's automatic freeze/discard eligibility and reasons; active WebRTC
should protect it from normal automatic freezing. Then leave the tab hidden for at
least 15 minutes with developer tools closed while continuously exchanging Telegram
traffic. Carrier traffic must continue without minute-scale stalls. Repeat once
with browser energy saving enabled. Manual or urgent discard may still terminate
the carrier and must recover through `Open browser` as described above.
the fallback carrier and must recover through an explicit `Open browser` as described
above. Run the corresponding 15-minute hidden test through the native WebView first;
it must not depend on the fallback page's RTC lifecycle guard.
## 10. Carrier reliability and server faults (P1)
@@ -264,7 +285,7 @@ Coordinate these with the server operator:
5. Restart the web relay while preserving or intentionally discarding session state;
record expected bridge status and MTProto reconnection.
6. Restart stock MTProxy only. Affected logical streams must close/reconnect without
breaking the browser carrier.
breaking the active carrier.
7. Return malformed frame length, unknown frame type, invalid stream zero usage,
zero/invalid `WINDOW`, and data beyond granted credit in a controlled staging
environment. The client must close the carrier/streams cleanly, remain responsive,
@@ -280,10 +301,10 @@ Coordinate these with the server operator:
source IPs must retain bounded access, expired tokens must release their slots,
and the public fallback must not expose why a request was limited.
## 11. Loopback validation tests (P0)
## 11. Explicit browser-fallback loopback validation tests (P0)
Use a purpose-built local test client; do not paste the real capability into shell
history.
Accept the fallback offer, then use a purpose-built local test client; do not paste
the real capability into shell history.
Verify rejection of:
@@ -327,29 +348,32 @@ Then verify:
document its behavior. The new binary handles unknown types; old binary
behavior may still require a release-note warning.
5. Confirm WEB cannot be shared/copied as a `tg://proxy` link and inactive WEB rows do
not auto-open a browser during availability checks or proxy rotation.
6. Confirm a saved and enabled WEB proxy intentionally opens one replacement tab at
application startup, while closing that tab does not cause an automatic reopen
loop.
not create a WebView or open a browser during availability checks or proxy rotation.
6. Confirm a saved and enabled WEB proxy creates one hidden WebView at application
startup and opens no browser tab. Force the WebView to fail, cancel the offer, and
confirm restart/retry still never opens a tab without confirmation.
## 13. Browser/platform matrix
## 13. WebView and fallback-browser matrix
At minimum execute sections 5, 6, 7 (small traffic), 9, and 11 on each supported
combination available:
| OS | Browser | Version | Result |
|---|---|---|---|
| Windows | Chrome | | |
| Windows | Edge | | |
| Windows | Firefox | | |
| macOS | Chrome | | |
| macOS | Safari | | |
| macOS | Firefox | | |
| all-other desktop | Chrome/Chromium | | |
| all-other desktop | Firefox | | |
| OS | Primary WebView | Fallback browser | Version | Result |
|---|---|---|---|---|
| Windows | WebView2 | Chrome | | |
| Windows | WebView2 | Edge | | |
| Windows | WebView2 | Firefox | | |
| macOS | WKWebView | Chrome | | |
| macOS | WKWebView | Safari | | |
| macOS | WKWebView | Firefox | | |
| all-other desktop | helper-process WebKitGTK | Chrome/Chromium | | |
| all-other desktop | helper-process WebKitGTK | Firefox | | |
Pay special attention to iframe CSP, loopback WebSocket Origin, mixed-content rules,
background-tab throttling, default-browser launch, and managed-browser policies.
For the primary path, verify the WebView is native, hidden, unique per process, and
has no Telegram `RpWindow` or embedded widget. On all-other platforms verify the
WebKitGTK helper process remains the owner. For fallback, pay special attention to
iframe CSP, loopback WebSocket Origin, mixed-content rules, background-tab
throttling, confirmation-only browser launch, and managed-browser policies.
## 14. Unreliable-MTProto network field test (P0)
@@ -361,8 +385,10 @@ This is the product hypothesis test and cannot be replaced by a lab run.
3. Confirm the relay's ordinary site is reachable in the chosen browser.
4. Enable WEB and repeat login/history/message/media cases.
5. Capture sanitized connection ownership and traffic metadata.
6. Confirm the observable external client is the browser and all carrier requests are
ordinary same-origin HTTPS; no public WebSocket is required.
6. Confirm the observable external client is the platform WebView and all carrier
requests are ordinary same-origin HTTPS; no public WebSocket is required. Repeat
once through explicit fallback and confirm the observable client then becomes the
selected browser.
7. Repeat at two times of day and, if possible, through two access providers.
Pass means WEB works while both direct Telegram and ordinary MTProxy controls fail,
@@ -396,7 +422,7 @@ Attach or link:
- connection-owner evidence;
- long-poll retry/replay evidence;
- loopback and protocol validation results;
- browser/platform matrix;
- WebView and fallback-browser matrix;
- unreliable-MTProto network comparisons and outcome;
- every defect with severity, exact reproduction, expected/actual result, timestamps,
and relevant sanitized logs.