Respond 400 + Reset to malformed request #748
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
h2
returnsRST_STREAM
frames with thePROTOCOL_ERROR
bit set as a response to many types of errors in client requests. Many of those cases, when handled by an HTTP/1 server such as the one used inhyper
, would result in an HTTP 400 Bad Request response returned to the client rather than a TCP reset (the HTTP/1 equivalent of aRST_STREAM
). As a consequence, a client will observe differences in behaviour between HTTP/1 and HTTP/2: a malformed request will result in a 400 response when HTTP/1 is used whereas the same request will result in a reset stream withh2
.This PR makes
h2
reply aHEADERS
+400
+END_STREAM
frame followed by aRST_STREAM
+PROTOCOL_ERROR
frame to all themalformed!()
macro invocations inPeer::convert_poll_message()
insrc/server.rs
.The
Reset
variant in theh2::proto::error::Error
Enum now contains anOption<http::StatusCode>
value that is set by themalformed!()
macro with aSome(400)
. That value is propagated all the way untilh2::proto::streams::send::Send::send_reset()
where, if notNone
, ah2::frame::headers::Headers
frame with the status code and theEND_STREAM
flag set will now be sent to the client before theRST_STREAM
frame.Some of the parameters passed to
send_reset()
have been grouped into a newSendResetContext
Struct in order to avoid aclippy::too_many_arguments
lint.Tests where malformed requests were sent have been updated to check that an additional
HEADERS
+400
+END_STREAM
frame is now received before theRST_STREAM + PROTOCOL_ERROR
frame.This change has been validated with other clients like
curl
, a custom ad-hoc client written withpython3+httpx
andvarnishtest
.Fixes #747