Skip to content

Fix Windows proxy response loss on pipelined requests - #432

Merged
Tryanks merged 1 commit into
mainfrom
fix/proxy-graceful-close
Sep 14, 2026
Merged

Tryanks merged 1 commit into
mainfrom
fix/proxy-graceful-close

Conversation

@Tryanks

@Tryanks Tryanks commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Behaviour

The preview forward proxy handles one HTTP request per authenticated connection and intentionally leaves pipelined bytes unread so they never reach the origin. Returning from the handler dropped the client socket with those bytes still in the receive buffer, which closes with RST rather than FIN. On Windows a reset discards data the peer has not read yet, so the client could lose the already-sent response. This is the pipelined_request_and_chunk_trailers_never_reach_origin failure (Os { code: 10054, kind: ConnectionReset } at proxy.rs:83) seen on the Windows runner for main (cba07d3) and PR #430.

After relaying the origin's response the proxy now shuts down its write side, then discards whatever the client sends until the client closes, capped at one second. The existing idle and shutdown watchdogs still bound the connection. CONNECT and upgrade tunnels already waited for both directions to finish and are unchanged.

Test contract

pipelined_request_and_chunk_trailers_never_reach_origin now also asserts that the client reads an orderly EOF after the response. Without the proxy change this assertion fails deterministically on macOS with ECONNRESET; with it, the proxy test suite passes. The origin-side assertion that pipelined bytes never arrive is unchanged.

Checks

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets --locked -- -D warnings
  • cargo test -p tcode-remote --test proxy (11 passed), including the strengthened test failing without the fix
  • Windows itself is left to CI; the change is platform-independent socket teardown.

The forward proxy serves one HTTP request per authenticated connection and
deliberately never reads bytes the client pipelined after it. Dropping the
socket while those bytes sit unread sends RST instead of FIN, and on Windows
a reset discards data the peer has not read yet, so the client can lose the
200 response it was about to read. The `pipelined_request_and_chunk_trailers_never_reach_origin`
test hit this intermittently on the Windows CI runner.

After the origin's response is relayed, shut down the write side first and
discard whatever the client sends until it closes, bounded to one second.
The pipelined request still never reaches the origin. The test now also
requires an orderly EOF after the response; that assertion fails with
ECONNRESET on macOS without this change.
@Tryanks
Tryanks merged commit a986ef3 into main Sep 14, 2026
10 of 12 checks passed
@Tryanks
Tryanks deleted the fix/proxy-graceful-close branch September 14, 2026 15:15
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.

1 participant