Skip to content

http: fix drain event with cork/uncork#64038

Open
davidje13 wants to merge 1 commit into
nodejs:mainfrom
davidje13:cork-drain
Open

http: fix drain event with cork/uncork#64038
davidje13 wants to merge 1 commit into
nodejs:mainfrom
davidje13:cork-drain

Conversation

@davidje13

Copy link
Copy Markdown

Fixes #60432

This is a copy of PR #60437, so credit for the fix goes to @ThierryMT. Sadly that PR was abandoned and I wasn't able to get a response from the author. I've just applied their changes to the latest main, patched up the lint errors, and applied the suggested change to the tests. I've signed the certificate of origin on the basis that the test is based on the reproduction I provided in the original bug report #60432 (hence, created in part by me), but let me know if this is too tenuous and I can write a new test from scratch instead. The fix itself is so trivial that I'm not sure there's a way to write it which isn't effectively the same code.


Original PR description:

When using cork() and uncork() with ServerResponse, the drain event was not reliably emitted after uncorking. This occurred because the uncork() method did not check if a drain was pending (kNeedDrain flag) after flushing the chunked buffer.

The Problem:

  • When corked, write() buffers data in kChunkedBuffer instead of sending immediately
  • If write() returns false, kNeedDrain is set to true
  • When uncork() is called, it flushes the buffer by calling _send()
  • After flushing, uncork() never checked if drain was needed or emitted the event
  • This left the response waiting for a drain event that would never fire

The Fix:
This commit ensures that when uncork() successfully flushes buffered data and a drain was needed, the drain event is emitted immediately.

Changes:

  • Modified OutgoingMessage.prototype.uncork() in lib/_http_outgoing.js
  • Capture return value from final _send() call
  • Check if drain was pending after successful flush
  • Emit drain event when appropriate

Testing:
The issue could be reproduced by using cork() with multiple large writes and checking for drain events. With this fix, the drain event now fires correctly after uncork().

When using cork() and uncork() with ServerResponse, the drain
event was not reliably emitted after uncorking. This occurred
because the uncork() method did not check if a drain was pending
(kNeedDrain flag) after flushing the chunked buffer.

This fix ensures that when uncork() successfully flushes buffered
data and a drain was needed, the drain event is emitted
immediately.

This commit is a copy of PR nodejs#60437 (abandoned) with minor linting
fixes.

Fixes: nodejs#60432
Signed-off-by: David Evans <davidje13@users.noreply.github.com>
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/http
  • @nodejs/net

@nodejs-github-bot nodejs-github-bot added http Issues or PRs related to the http subsystem. needs-ci PRs that need a full CI run. labels Jun 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

http Issues or PRs related to the http subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

drain event is unreliable when using cork/uncork with ServerResponse

2 participants