-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
http2: fix endless loop when writing empty string #18924
Conversation
27baa0a
to
b702ba3
Compare
Is there a way to standardize the behaviour between the various StreamBase implementations? As far as I can tell, the only place where we truly need these empty writes is (One side-effect of having a unique implementation of this logic for each StreamBase implementation is that |
@apapirovski I think the fact that TLS uses them makes “empty writes flush the underlying protocol” part of the I’d be open to changing that. In reality, TLS should probably work more like HTTP/2 and flush state automatically after making changes to the protocol state, like what we do with
Yeah, but it’s part of the |
It's not, just commenting that the way it works is kind of problematic. We probably can't do much about it now but the
Yeah, that would be nice. Anyway, it's a bit hard for me to find time to think about much of this right now but will revisit when I have a bit more time. In relation to this PR, I don't know how I feel about it vs the earlier one. There seem to be trade-offs with both. |
// This is done here so that .write('', cb) is still a meaningful way to | ||
// find out when the HTTP2 stream wants to consume data, and because the | ||
// StreamBase API allows empty input chunks. | ||
while (!stream->queue_.empty() && stream->queue_.front().buf.len == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One question, if we remove the empty buffer and do nothing, will the header be sent?
Refs: https://github.com/nodejs/node/pull/18673/files#diff-696b2cc418addca5f3fe5020058f8b15R1622
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@XadillaX Hm – I’m not sure I can wrap my head around everything, but this code here is only ever called by nghttp2 after the headers were sent anyway… does that answer your question?
So, yes, writing an empty buffer would trigger the headers to be sent, as I understand it.
PR-URL: #18924 Fixes: #18169 Refs: #18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Refs: #18673 PR-URL: #18924 Refs: #18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
PR-URL: nodejs#18924 Fixes: nodejs#18169 Refs: nodejs#18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Refs: nodejs#18673 PR-URL: nodejs#18924 Refs: nodejs#18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
PR-URL: nodejs#18924 Fixes: nodejs#18169 Refs: nodejs#18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Refs: nodejs#18673 PR-URL: nodejs#18924 Refs: nodejs#18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Backport-PR-URL: #20456 PR-URL: #18924 Fixes: #18169 Refs: #18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Refs: #18673 Backport-PR-URL: #20456 PR-URL: #18924 Refs: #18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
PR-URL: nodejs#18924 Fixes: nodejs#18169 Refs: nodejs#18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Refs: nodejs#18673 PR-URL: nodejs#18924 Refs: nodejs#18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Backport-PR-URL: #20456 PR-URL: #18924 Fixes: #18169 Refs: #18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Refs: #18673 Backport-PR-URL: #20456 PR-URL: #18924 Refs: #18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Backport-PR-URL: #20456 PR-URL: #18924 Fixes: #18169 Refs: #18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Khaidi Chu <i@2333.moe> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Refs: #18673 Backport-PR-URL: #20456 PR-URL: #18924 Refs: #18673 Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484 Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Alternative to #18673 that addresses the problem on the HTTP/2 level rather than the streams level itself. The test is taken from @XadillaX, whom I’d be very thankful if he could take a look at this :)
Refs: #18673
Fixes: #18169
Refs: https://github.com/nodejs/node/blob/v9.5.0/src/node_http2.cc#L1481-L1484
Refs: https://github.com/nodejs/node/blob/v9.5.0/lib/_http_outgoing.js#L659-L661
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
http2