Skip to content

fix(http2): prevent end-stream data from stalling under flow control - #2003

Open
renta0426 wants to merge 2 commits into
dart-lang:masterfrom
renta0426:fix/1998-flow-controlled-end-stream
Open

renta0426 wants to merge 2 commits into
dart-lang:masterfrom
renta0426:fix/1998-flow-controlled-end-stream

Conversation

@renta0426

Copy link
Copy Markdown

Fixes #1998.

StreamMessageQueueOut.enqueueMessage calls startClosing() before adding the final message to the queue. Because startClosing() checks for completion synchronously, an empty queue can be marked done before the final message has been queued.

If the incoming side has also completed, the stream can be removed while outgoing DATA is still waiting for flow-control credit. Subsequent stream WINDOW_UPDATE frames no longer reach the queue, leaving the response incomplete.

Queue the message before calling startClosing(), then drain the queue. This keeps pending data visible to the completion check and ensures that synchronous drain callbacks observe the closing state. The incoming queue already follows the same ordering.

Tests

Tests cover:

  • Terminal DATA blocked by an empty or partially available stream window
  • Completion after WINDOW_UPDATE releases the remaining DATA
  • Empty terminal DATA with no available window credit
  • Reentrant enqueue during the initial drain, which must observe the queue as closing and reject further DATA
  • Real TCP responses at and beyond the initial 65,535-byte window boundary

Validation

The focused tests reproduce the failure on the unpatched parent and all pass with this change. The full http2 VM suite passes with seven existing capability skips. dart analyze --fatal-infos and formatting checks also pass on Dart 3.13.5 / Linux.

AI assistance

This change was prepared with assistance from OpenAI Codex. I reviewed, tested, and understand the changes and validation results, and can address review feedback directly.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

http2 server: a response body larger than the peer's window stalls when sent with endStream

1 participant