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
Correctly handle Upgrade-requests for HTTP/2 by ignoring them #1642
Conversation
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.
If we look for should_upgrade
on the httptools
implementation, why is the same logic not needed on on_body
and on_message_complete
?
upgrade_http2 = False | ||
for name, value in self.headers: | ||
if name == b"upgrade": | ||
upgrade_value = value.lower() | ||
if upgrade_value == b"h2c": | ||
upgrade_http2 = True | ||
break | ||
if not upgrade_http2: | ||
return |
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.
We can add a self.is_http2
, and set as True
on the on_header
method.
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.
Oh indeed, the code looks like, we should also replace the self.parser.should_upgrade()
in on_body
and on_message_complete
with (self.parser.should_upgrade() and not self.is_http2)
.
Sorry, I had overlooked that because no unit test failed for this edge case.
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.
We can probably benefit from more tests that consider those conditionals 🙌
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.
The drop on coverage threshold shouldn't be needed if we add the necessary tests here. Would you like to work on those, @hajs ?
Yeah this is normally not a good idea. The coverage declined only after re-formatting this commit 0cffedc into multiple lines. I am not sure how to test for different request-response-cycles. Do you have any idea? |
(Fix for #1501)
MDN (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade) says:
The server can choose to ignore the request, for any reason, in which case it should just respond as though the Upgrade header had not been sent (for example, with a 200 OK).
The previous implementation could only upgrade requests for WebSockets and generated errors for "Upgrade: h2c".
Example for
uvicorn example:app
:With this patch the server will send the correct result:
Previous behaviour: