Skip to content

fix(node): do not retry cancelled HTTP requests - #36801

Open
boyam01 wants to merge 2 commits into
denoland:mainfrom
boyam01:fix/36786-no-retry-cancelled-http
Open

fix(node): do not retry cancelled HTTP requests#36801
boyam01 wants to merge 2 commits into
denoland:mainfrom
boyam01:fix/36786-no-retry-cancelled-http

Conversation

@boyam01

@boyam01 boyam01 commented Sep 8, 2026

Copy link
Copy Markdown

Fixes #36786.

canRetryRequest() currently accepts a request that the caller has already destroyed. Socket close/error/end handling can then enter maybeRetryRequest(), reset destroyed, and resend the buffered POST on a new connection.

Exclude destroyed requests in the shared retry predicate. This also covers abort(), AbortSignal cancellation, and timeout callbacks that call destroy(), while leaving retries for genuinely stale pooled connections intact.

The regression waits until the server has received the complete POST and asserts that the socket was actually reused before cancelling. It then checks that the body was received only once, no response was delivered, and the cancellation error was preserved. There are 10 cancellation cases across HTTP/HTTPS plus 2 fresh-socket controls, using the existing TLS fixtures and spec harness.

Testing:

  • The 10 reused-socket cancellation cases fail before the fix; the 2 fresh-socket controls pass. All 12 pass on Node.js 22.12.0.
  • Linux debug build: all 32 specs::node::http_ cases pass, including the 12 new cases and existing stale-socket retry, body preservation, streaming, and permission tests.
  • Linux debug build: all 5 test files selected by unit_node::http pass through the official harness.
  • Full-repository formatting check and JS lint pass.

The patched runtime has not been built/tested locally on Windows or macOS; the full compatibility suite has not been run locally.

AI disclosure: OpenAI Codex assisted with the implementation, tests, review, and this description. The results above come from executed local checks.

boyam01 and others added 2 commits September 8, 2026 23:31
Respect ClientRequest.destroyed before retrying reused keep-alive sockets so cancellation cannot replay a POST or swallow its original error.

Cover destroy(), abort(), AbortSignal, and timeout cancellation over HTTP and HTTPS, with fresh-socket controls.

Fixes denoland#36786

AI assistance: OpenAI Codex.
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.

node:http retries an explicitly destroyed POST on a reused connection

1 participant