Skip to content
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 responses to long payload reqs #20084

Closed
wants to merge 5 commits into from

Conversation

apapirovski
Copy link
Member

When a request with a long payload is received, http2 does not allow a response that does not process all the incoming payload if the payload exceeds the initial window size. Add a conditional Http2Stream#close call that runs only if its a server-side stream, the user hasn't attempted to read the stream & there is no resume call scheduled.

With all that said, I hope someone has some good ideas that will make this less of a monster...

Also, FWIW this should make writes slightly less brittle because right now it's possible to trigger a follow-up write from the Done callback which would then trigger the assert in SendPendingData. In particular this tends to happen when using either destroy or close on a stream.

Fixes: #20060

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

@apapirovski apapirovski added the addons Issues and PRs related to native addons. label Apr 16, 2018
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. labels Apr 16, 2018
@apapirovski apapirovski added http2 Issues or PRs related to the http2 subsystem. and removed addons Issues and PRs related to native addons. labels Apr 16, 2018
@apapirovski
Copy link
Member Author

@apapirovski
Copy link
Member Author

Have to update this to support the new trailers implementation.

@apapirovski
Copy link
Member Author

There. That should get it compatible with the trailers stuff. Please review again if you could @addaleax & @jasnell. (Just the last commit is new.)

CI: https://ci.nodejs.org/job/node-test-pull-request/14344/

@apapirovski
Copy link
Member Author

apapirovski commented Apr 17, 2018

Ok, one related failure in parallel/test-http2-serve-file.js. Investigating.

Edit: I think this might be not directly related to this change but rather these changes are exposing another existing bug? Debugging. Hopefully have a fix soon.

@apapirovski
Copy link
Member Author

Ok, so there was indeed an unrelated issue around not flushing pending data when sending RST_STREAM. This commit takes care of that: 1f29ad5

This is tied into how nghttp2 handles RST_STREAM frames: nghttp2/nghttp2#692 (with higher priority than others).

Definitely open to suggestions on how to do it better!

@apapirovski
Copy link
Member Author

@@ -26,7 +26,7 @@ const obs = new PerformanceObserver(common.mustCall((items) => {
switch (entry.type) {
case 'server':
assert.strictEqual(entry.streamCount, 1);
assert.strictEqual(entry.framesReceived, 5);
Copy link
Member Author

Choose a reason for hiding this comment

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

This is already flaky on master but exacerbated by some of the changes here. I think it might be timing sensitive? Minimum seems to be 3.

Copy link
Member

Choose a reason for hiding this comment

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

+1 for the fix, can you add a comment?

@apapirovski
Copy link
Member Author

apapirovski commented Apr 17, 2018

@apapirovski
Copy link
Member Author

apapirovski commented Apr 17, 2018

This seems clean now of any hidden bugs. ping @nodejs/http2 @addaleax for another review. In particular these two commits: 1f29ad5 and 1ff5bc9. Thanks in advance!

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

LGTM

@ryzokuken
Copy link
Contributor

@BridgeAR still awaiting your final review on this before landing.

@BridgeAR
Copy link
Member

@ryzokuken I guess you meant @addaleax?

@ryzokuken
Copy link
Contributor

@BridgeAR wait, sorry. Wrong thread. I need more rest, I think.

@ryzokuken
Copy link
Contributor

P.S. It was #19898

@apapirovski apapirovski added this to the 10.0.0 milestone Apr 18, 2018
@jasnell
Copy link
Member

jasnell commented Apr 19, 2018

If this is going to make it in to 10.0.0 it really needs to get landed today.

@apapirovski
Copy link
Member Author

@jasnell it's ready to go on my end (I think?) but I could really use one more review for the C++ stuff from you or @addaleax.

@Trott
Copy link
Member

Trott commented Apr 20, 2018

@addaleax addaleax removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Apr 27, 2018
@apapirovski
Copy link
Member Author

apapirovski commented Apr 28, 2018

Last CI run before landing: https://ci.nodejs.org/job/node-test-pull-request/14564/

@addaleax addaleax added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Apr 28, 2018
@apapirovski
Copy link
Member Author

Landed in b55a11d

@apapirovski apapirovski deleted the fix-http2-bug-20060 branch April 28, 2018 16:17
apapirovski added a commit that referenced this pull request Apr 28, 2018
When a request with a long payload is received, http2 does
not allow a response that does not process all the incoming
payload. Add a conditional Http2Stream.close call that runs
only if the user hasn't attempted to read the stream.

PR-URL: #20084
Fixes: #20060
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
MylesBorins pushed a commit that referenced this pull request May 4, 2018
When a request with a long payload is received, http2 does
not allow a response that does not process all the incoming
payload. Add a conditional Http2Stream.close call that runs
only if the user hasn't attempted to read the stream.

PR-URL: #20084
Fixes: #20060
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
@MylesBorins MylesBorins mentioned this pull request May 8, 2018
kjin pushed a commit to kjin/node that referenced this pull request Aug 23, 2018
When a request with a long payload is received, http2 does
not allow a response that does not process all the incoming
payload. Add a conditional Http2Stream.close call that runs
only if the user hasn't attempted to read the stream.

PR-URL: nodejs#20084
Fixes: nodejs#20060
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
@kjin
Copy link
Contributor

kjin commented Sep 11, 2018

@apapirovski I've been trying to do a backport of http2 commits to 8.x, but this commit has been giving me some trouble, as its passing tests is reliant on a PR (#18438) that is marked as semver-major. A number of following PRs depend on this one, so this seems to be a big factor in what can be backported correctly. What are your thoughts on this? (cc/ @jasnell, @mcollina, @addaleax)

@apapirovski
Copy link
Member Author

@kjin I will have a look at it and see if I can help out. Do you have a branch you're working against that I could pull down to do my work on?

@kjin
Copy link
Contributor

kjin commented Sep 11, 2018

@apapirovski Thanks! The current branch is here and fairly up-to-date against v8.x-staging. If I were to add the commit associated with this PR it would go right on top.

@kjin
Copy link
Contributor

kjin commented Sep 19, 2018

Hi @apapirovski -- after going through the rest of the commits, it turns out that backporting the commits in #20772 seems to fix the failing tests from this PR. Given that you are the author of both PRs, does this seem logical to you, or do you know if any change in #20772 would mask the issues arising here?

kjin pushed a commit to kjin/node that referenced this pull request Sep 19, 2018
When a request with a long payload is received, http2 does
not allow a response that does not process all the incoming
payload. Add a conditional Http2Stream.close call that runs
only if the user hasn't attempted to read the stream.

PR-URL: nodejs#20084
Fixes: nodejs#20060
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
@kjin kjin mentioned this pull request Oct 3, 2018
4 tasks
kjin pushed a commit to kjin/node that referenced this pull request Oct 16, 2018
When a request with a long payload is received, http2 does
not allow a response that does not process all the incoming
payload. Add a conditional Http2Stream.close call that runs
only if the user hasn't attempted to read the stream.

PR-URL: nodejs#20084
Fixes: nodejs#20060
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
BethGriggs pushed a commit that referenced this pull request Oct 17, 2018
When a request with a long payload is received, http2 does
not allow a response that does not process all the incoming
payload. Add a conditional Http2Stream.close call that runs
only if the user hasn't attempted to read the stream.

Backport-PR-URL: #22850
PR-URL: #20084
Fixes: #20060
Reviewed-By: Anna Henningsen <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Matteo Collina <[email protected]>
@BethGriggs BethGriggs mentioned this pull request Oct 30, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
author ready PRs that have at least one approval, no pending requests for changes, and a CI started. c++ Issues and PRs that require attention from people who are familiar with C++. http2 Issues or PRs related to the http2 subsystem. lib / src Issues and PRs related to general changes in the lib or src directory.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

difference between http2 Compatibility API and http
10 participants