Skip to content

fix: preserve HTTP body activity and bound stream cancellation - #18

Merged
cppla merged 1 commit into
mainfrom
codex/stream-cancellation-hardening
Sep 22, 2026
Merged

cppla merged 1 commit into
mainfrom
codex/stream-cancellation-hardening

Conversation

@cppla

@cppla cppla commented Sep 22, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Keep ordinary HTTP uploads and downloads alive while body data is progressing, including small buffered responses. Preserve external header/hijack deadlines and independent blocked-write bounds.
  • Bound H2 post-TLS preface/SETTINGS initialization by the handshake budget, caller cancellation, and client shutdown. Detach the cancellation watcher before session handoff and preserve cancellation causes.
  • Release stalled destination I/O on H2 request cancellation, H3 send-side stream errors, and H3 physical-connection shutdown without terminating sibling streams or normal H3 half-closes.

Verification

Exact head: 82a05108c141920fb6123ad93d94d37fdf8cf78c.

  • Final local tree: make check, make race, make stealth-tools-check, and git diff --check passed.
  • Direct and real-H2 HTTP body regressions passed with race detection, repeated three times. Baseline negative controls failed all four active upload/download cases.
  • H2 initialization regression covers native and Chrome-133 TLS, caller cancellation/custom cause, deadline, client Close, initialization timeout, successful handoff, and Close during handoff. Baseline failed all eight cancellation/timeout combinations.
  • Server cancellation regressions cover admission release, sibling survival, normal H3 response FIN followed by upload, and shutdown after response FIN. Repeated race runs passed; baseline failed all four original stalled-destination cases.
  • Independent code review and scoped secrets/artifact audit completed. No dependencies, captured traffic, test-host credentials, or binary artifacts are included.
  • Exact-head GitHub CI, CodeQL, and Linux netem all passed. CI includes Go 1.25.13/1.27.x tests, race detection, macOS tests, vulnerability scanning, four platform builds, container integration, and the OCI image-index build.
  • No unresolved review threads or requested changes at the pre-merge check.

Remaining boundary

After a clean H3 response FIN, resetting only that stream still cannot interrupt an already blocked destination upload write via the current QUIC API. The slot is released when the destination unblocks or the physical connection closes; documented explicitly. This PR does not claim complete cancellation coverage or browser indistinguishability.

No tag or release is created.

Merged-main verification

Merged as c372b3d95470772da741483f25c2e7f642bdb31d; its tree is identical to the tested head (b0b86efbc77813efbeff3ee87d76dcbdae26226b). The exact merged main passed CI, CodeQL, and Linux netem, including the container integration step. Local main is fast-forwarded and clean. No tag/release was created.

Copilot AI lite review requested due to automatic review settings September 22, 2026 12:54
@cppla
cppla merged commit c372b3d into main Sep 22, 2026
14 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Two moderate issues remain around write-deadline rearming and H2 handoff deadline detection.

Review effort: Lite
Findings: None

What changed in this PR

Improves HTTP body activity tracking and cancellation handling across HTTP, H2, and H3 relay paths.

Changes:

  • Preserves activity during progressing bodies while bounding stalled writes.
  • Bounds H2 initialization and safely cancels stalled destinations.
  • Adds regression coverage and documents timeout and cancellation behavior.
File Description
internal/​tunnel/​web_server_cancellation_test.go Tests stalled H2/H3 destination cleanup.
internal/​tunnel/​web_handler.go Adds stream and connection cancellation handling.
internal/​tunnel/​web_h2_initialization_test.go Tests bounded H2 initialization and handoff races.
internal/​tunnel/​web_h2_client.go Bounds post-TLS H2 setup.
internal/​proxy/​relay.go Refreshes origin read activity.
internal/​proxy/​lifecycle.go Tracks HTTP connection activity deadlines.
internal/​proxy/​http.go Applies activity tracking to forwarded responses.
internal/​proxy/​http_activity_test.go Tests HTTP activity and deadline behavior.
internal/​proxy/​config.go Documents HTTP body timeout semantics.
integration/​proxy_activity_test.go Adds end-to-end H2 body-activity coverage.
docs/​WEB_COVER.md Documents stream cancellation behavior.
docs/​DEPLOYMENT.md Documents HTTP body timeout behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

2 participants