Skip to content

fix(http): interrupt pending body reads on cancellation (fix #3713) - #3720

Draft
Sealdot wants to merge 1 commit into
tauri-apps:v2from
Sealdot:codex/fix-http-silent-stream-cancel
Draft

Sealdot wants to merge 1 commit into
tauri-apps:v2from
Sealdot:codex/fix-http-silent-stream-cancel

Conversation

@Sealdot

@Sealdot Sealdot commented Oct 20, 2026

Copy link
Copy Markdown

AI assistance: The implementation and regression tests were developed with Codex, with a separate agent reviewing the cancellation path.

Problem

A pending fetch_read_body call retains an Arc to the response while awaiting Response::chunk(). Closing its resource-table entry alone does not interrupt that operation. When a streaming server stays silent, cancellation therefore waits for another chunk; in the local HTTP/1.1 reproduction, the server also keeps seeing an open connection.

Closes #3713.

Solution and key decisions

  • Give response resources a close notification, and race the pending body read against it using the existing Tokio sync dependency.
  • Store the response in Mutex<Option<Response>>, dropping it on cancellation, EOF or error. This also replaces the raw mutable Arc cast and serializes concurrent reads.
  • Keep commands, permissions, JS cancellation hooks, response sentinels, dependencies and lockfiles unchanged. Include matching http / http-js patch entries and streaming cancellation documentation.

Tests

macOS arm64, stable Rust 1.97.1 and MSRV 1.90.0, using the checked-in lockfile:

  • Original read algorithm plus the pending-read regression: fails at the expected 2-second cancellation timeout.
  • Final crate: 23 tests pass with stable default features, stable all features, and MSRV default features. These are the same 23 tests across configurations, including 4 new tests.
  • The new tests cover 3 real silent HTTP/1.1 TCP cases (pending read, cancel before read, and a second read waiting for the mutex), with server-observed EOF/reset assertions; the fourth is an in-memory normal EOF case. Repeated RID closure keeps its existing error behavior.
  • Strict Clippy for all targets with default and all features; cargo fmt --all --check; HTTP guest Rollup build, ESLint and TypeScript; documentation format, paired changeset and license checks pass.
  • cargo test --doc succeeds with 0 doctests.

Risks and follow-up

No native webview/IPC, Linux, Windows or mobile execution is claimed. HTTP/2 stream cancellation and TLS-specific transport behavior are not independently exercised by these tests; dropping a response does not imply closing a shared HTTP/2 TCP connection. ResourceTable::clear does not call Resource::close, so this change does not claim to fix webview teardown with outstanding reads. Upstream platform CI and maintainer review remain to be completed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[http] Aborting a streaming response doesn't close the connection while the server is silent

1 participant