-
-
Notifications
You must be signed in to change notification settings - Fork 303
Respond 400 + Reset to malformed request #748
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
base: master
Are you sure you want to change the base?
Conversation
I'm not sure why clippy started complaining about this. I could amend this PR to appease clippy or push a fix in separate PR. |
Could be a newer clippy being a jerk. |
7b41f65
to
f98522a
Compare
`h2` returns `RST_STREAM` frames with the `PROTOCOL_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 in `hyper`, would result in an HTTP 400 Bad Request response returned to the client rather than a TCP reset (the HTTP/1 equivalent of a `RST_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 with `h2`. Make `h2` reply a `HEADERS`+`400`+`END_STREAM` frame followed by a `RST_STREAM`+`PROTOCOL_ERROR` frame to all the `malformed!()` macro invocations in `Peer::convert_poll_message()` in `src/server.rs`. The `Reset` variant in the `h2::proto::error::Error` Enum now contains an `Option<http::StatusCode>` value that is set by the `malformed!()` macro with a `Some(400)`. That value is propagated all the way until `h2::proto::streams::send::Send::send_reset()` where, if not `None`, a `h2::frame::headers::Headers` frame with the status code and the `END_STREAM` flag set will now be sent to the client before the `RST_STREAM` frame. Some of the parameters passed to `send_reset()` have been grouped into a new `SendResetContext` Struct in order to avoid a `clippy::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 the `RST_STREAM + PROTOCOL_ERROR` frame. This change has been validated with other clients like `curl`, a custom ad-hoc client written with `python3+httpx` and `varnishtest`.
f98522a
to
7481e41
Compare
@seanmonstar I'm taking over this one from Fran while he's on vacation for the next few weeks. I would offer to do the review myself, but I'm the coauthor of the internal predecessor to this patch; it probably would be good to have a third party perspective before landing this change. |
Hi! Is there anything I can do to help with the review of this PR? Thank you in advance! |
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