Skip to content

http: always call response.write() callback - #27709

Closed
lpinca wants to merge 1 commit into
nodejs:masterfrom
lpinca:gh-22066
Closed

http: always call response.write() callback#27709
lpinca wants to merge 1 commit into
nodejs:masterfrom
lpinca:gh-22066

Conversation

@lpinca

Copy link
Copy Markdown
Member

Ensure that the callback of OutgoingMessage.prototype.write() is
called even when writing empty chunks.

Fixes: #22066

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines

Ensure that the callback of `OutgoingMessage.prototype.write()` is
called even when writing empty chunks.
Fixes: nodejs#22066
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-botnodejs-github-bot added the http Issues or PRs related to the http subsystem. label May 15, 2019
@lpinca

Copy link
Copy Markdown
MemberAuthor

This is an attempt to fix #22066.
The idea is to treat empty chunks like all other chunks and write them to the socket. In this way

  • The callback is called in and called the correct order.
  • We can return the correct boolean value, the one returned by socket.write(), instead of blindly returning true.

The downside is that internal empty writes like

this._send('','latin1',finish);
now trigger a socket.write() call which in turn calls into C++. This could have an impact on performance if writev is not supported. A possible way to mitigate the issue is to not call writeGeneric() if the chunk is empty here
req=writeGeneric(this,data,encoding,cb);

If we don't care about the callbacks order, we can simplify everything and just call the callback of OutgoingMessage.prototype.write() in the next tick when an empty chunk is written.

@addaleaxaddaleax left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this is my preferred approach as well 👍

@TrottTrott added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label May 18, 2019
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@addaleax

Copy link
Copy Markdown
Member

Landed in 0df581c

addaleax pushed a commit that referenced this pull request May 19, 2019
Ensure that the callback of `OutgoingMessage.prototype.write()` is
called even when writing empty chunks.
Fixes: #22066
PR-URL: #27709
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@lpinca
lpinca deleted the gh-22066 branch May 20, 2019 05:19
lpinca added a commit to lpinca/node that referenced this pull request May 20, 2019
Ensure that the callback of `OutgoingMessage.prototype.write()` is
called when `outgoingMessage._hasBody` is `false` (HEAD method, 204
status code, etc.).
Refs: nodejs#27709
targos pushed a commit that referenced this pull request May 20, 2019
Ensure that the callback of `OutgoingMessage.prototype.write()` is
called even when writing empty chunks.
Fixes: #22066
PR-URL: #27709
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@BridgeARBridgeAR mentioned this pull request May 21, 2019
4 tasks
Trott pushed a commit to Trott/io.js that referenced this pull request Jun 1, 2019
Ensure that the callback of `OutgoingMessage.prototype.write()` is
called when `outgoingMessage._hasBody` is `false` (HEAD method, 204
status code, etc.).
Refs: nodejs#27709
PR-URL: nodejs#27777
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Rich Trott <rtrott@gmail.com>
targos pushed a commit that referenced this pull request Jun 1, 2019
Ensure that the callback of `OutgoingMessage.prototype.write()` is
called when `outgoingMessage._hasBody` is `false` (HEAD method, 204
status code, etc.).
Refs: #27709
PR-URL: #27777
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Rich Trott <rtrott@gmail.com>
@awwrightawwright mentioned this pull request Sep 20, 2019
@awwright

awwright commented Sep 24, 2019

Copy link
Copy Markdown
Contributor

What's the test case that this fixes?

This PR seemed to introduce a bug where the callback for OutgoingMessage#end is not always called, since the callback for Writable#write doesn't always call if passed an empty string (where as before this PR, OutgoingMessage#_writeRaw did guarantee this).

But this PR was supposed to fix such an issue, so I'm not sure what's going on here.

@lpinca

Copy link
Copy Markdown
MemberAuthor

@awwright see #22066 (comment) and included tests.

@awwright

Copy link
Copy Markdown
Contributor

But #22066 (comment) is incorrect, Stream#write has no guarantee in the code that the callback will always be called, see #29649 for an example

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

Labels

author readyPRs that have at least one approval, no pending requests for changes, and a CI started.httpIssues or PRs related to the http subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

http: Stream#write with an empty buffer does not call callback

6 participants

@lpinca@nodejs-github-bot@addaleax@awwright@jasnell@Trott