Repository navigation
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The new regression test builds a native wtransport config without installing a rustls CryptoProvider, so it will panic at runtime instead of validating the cancellation path.
1 open finding
What changed in this PR
This PR fixes a resource/lifecycle issue in the WebTransport client backend: when the client frontend is dropped during an in-progress handshake, the connection attempt previously kept running until it completed or hit the configured timeout (up to five seconds). This matters for use cases like auto-fallback from QUIC to WebSocket, where a quick cancellation is needed. The fix races the handshake against the oneshot sender's cancellation() signal, so dropping the frontend's receiver promptly aborts the attempt. On native, dropping the connecting future cancels the QUIC attempt; on WASM, a PendingWebTransport drop guard explicitly closes the browser transport because dropping a Rust future does not cancel the underlying JS promise.
Changes:
- Add handshake cancellation by
select-ing the connect future againsttx_next.cancellation(), returningSessionError::FrontendClosedif the frontend closes first. - Introduce a WASM-only
PendingWebTransportdrop guard that closes the pending transport unless ownership passes to the session. - Add a native-only Tokio dev-dependency and a regression test asserting cancellation within 500 ms.
| File | Description |
|---|---|
crates/aeronet_webtransport/src/client/backend.rs |
Wraps the connect logic in a future raced against frontend cancellation, adds the WASM drop guard, and adds a regression test. |
crates/aeronet_webtransport/Cargo.toml |
Adds a native-only tokio dev-dependency (rt, net, time) for the new test. |
Cargo.lock |
Records the new tokio dependency for aeronet_webtransport. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| let config = ClientConfig::builder() | ||
| .with_bind_default() | ||
| .with_native_certs() | ||
| .max_idle_timeout(Some(Duration::from_secs(5))) | ||
| .unwrap() | ||
| .build(); |

Problem
Dropping the client frontend during a WebTransport handshake leaves the connection attempt running until it completes or times out. This can happen when falling back to other transport (eg implement auto fallback from QUIC to websocket).
Fix
Race the handshake against frontend-channel cancellation.
On native, cancellation drops the connection future and endpoint.
On WASM, a drop guard explicitly closes the pending browser transport, since dropping a Rust future doesn’t cancel a JavaScript promise.
Test
Start a handshake against a silent UDP endpoint, drop the frontend, and require cancellation within 500 ms rather than the configured five-second timeout.
added native-only Tokio dev dependency supports the regression test.