-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Fix HTTP/2: retry requests rejected with REFUSED_STREAM
#2081
Fix HTTP/2: retry requests rejected with REFUSED_STREAM
#2081
Conversation
Thanks for this! I think this might be something we can do, I'll have to go carefully read the spec about |
Sure, I'll add a unit test! |
Added two test cases in f6ad3c6. |
A related topic; thinking a bit further about the fact that we get REFUSED_STREAM errors when making too many concurrent requests, doing retry is certainly a mitigation, but another approach would be that we start with the relatively small number of concurrent streams until the server's initial SETTINGS frame arrives. This should reduce the chance of getting rejected with REFUSED_STREAM in the first place. |
Saw CI failed due to missing |
Thank you for starting the CI many times! I now understand how the test suite works against many feature flags. |
Bumps reqwest from 0.11.23 to 0.11.24. Release notes Sourced from reqwest's releases. v0.11.24 What's Changed Add Certificate::from_pem_bundle() to add a bundle. Add http3_prior_knowledge() to blocking client builder. Remove Sync bounds requirement for Body::wrap_stream(). Fix HTTP/2 to retry REFUSED_STREAM requests. Fix instances of converting Url to Uri that could panic. New Contributors @magurotuna made their first contribution in seanmonstar/reqwest#2081 @michaelciraci made their first contribution in seanmonstar/reqwest#2102 @basic-bgnr made their first contribution in seanmonstar/reqwest#2110 @jgraef made their first contribution in seanmonstar/reqwest#2114 @LucasPickering made their first contribution in seanmonstar/reqwest#2040 @gibbz00 made their first contribution in seanmonstar/reqwest#2032 Full Changelog: seanmonstar/[email protected] Changelog Sourced from reqwest's changelog. v0.11.24 Add Certificate::from_pem_bundle() to add a bundle. Add http3_prior_knowledge() to blocking client builder. Remove Sync bounds requirement for Body::wrap_stream(). Fix HTTP/2 to retry REFUSED_STREAM requests. Fix instances of converting Url to Uri that could panic. Commits c9b4b65 v0.11.24 ddf7f24 Add Certificate::from_pem_bundle() (#2032) 5d8443d fix panic when parsing invalid Url to Uri (#2040) e3bf090 docs: explain TLS backend features better (#2117) 1bd939b update wasm-streams dependency (#2114) 87cdf12 doc: clarify Cookie API usage (#2111) b3feff6 Add http3 feature to blocking client (#2110) 2332936 Update cookie crates (#2089) ef2c8ee Upgrading env_logger dep (#2102) 4ab5fb0 Fix HTTP/2: retry requests rejected with REFUSED_STREAM (#2081) Additional commits viewable in compare view Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase. Dependabot commands and options You can trigger Dependabot actions by commenting on this PR: @dependabot rebase will rebase this PR @dependabot recreate will recreate this PR, overwriting any edits that have been made to it @dependabot merge will merge this PR after your CI passes on it @dependabot squash and merge will squash and merge this PR after your CI passes on it @dependabot cancel merge will cancel a previously requested merge and block automerging @dependabot reopen will reopen this PR if it is closed @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
This patch gets the client to retry HTTP/2 requests rejected with
REFUSED_STREAM
by inspecting the error detail.I found the issue with highly concurrent requests in HTTP/2 made to the server that is configured to allow the smaller number of concurrent streams. So for example, a client makes, say, 500 concurrent requests to an HTTP/2 server while the server's
max_concurrent_streams
is set to 100. In this case the client is allowed to initiate 500 concurrent streams until the initialSETTINGS
frame from the server reaches to the client, though the server will reject 400 streams by respondingREFUSED_STREAM
.From the standpoint of users of
reqwest
crate, I would expect the crate to deal with this kind of situation behind the scenes. Actually, as far as I searched, Go and libcurl provides the retry logic when they encounterREFUSED_STREAM
. Considering the "ergonomic, batteries-included" characteristic ofreqwest
, I believe automatic retry would be very nice to have.Here's a repo containing reproducible code written in a couple different languages. It also has
rust-patched
code which demonstrates that this patch does fix the issue.https://github.com/magurotuna/deno-fetch-h2-stream-error-repro