-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Version
hyper = "0.14.18"
h2 = "0.3.13"
Platform
> uname -a
Linux <REDACTED> 5.17.5-76051705-generic #202204271406~1651504840~22.04~63e51bd SMP PREEMPT Mon May 2 15: x86_64 x86_64 x86_64 GNU/Linux
Description
I've found that Google Cloud Storage's API can respond with HTTP/2 RST_STREAM
frame with NO_ERROR
set for the reason, which appears to mean "stop sending the request body and read my response" according to https://datatracker.ietf.org/doc/html/rfc7540#section-8.1
A server can send a complete response prior to the client sending an entire
request if the response does not depend on any portion of the request
that has not been sent and received. When this is true, a server MAY
request that the client abort transmission of a request without error
by sending a RST_STREAM with an error code of NO_ERROR after sending
a complete response (i.e., a frame with the END_STREAM flag).
Clients MUST NOT discard responses as a result of receiving such a
RST_STREAM, though clients can always discard responses at their
discretion for other reasons.
I believe this is happening in response to a PutObject
request when the bucket is being rate limited for writes. The server is trying to tell the client to stop sending the request body because it won't be processed, and instead it should immediately read the response to discover the 429 Too Many Requests
error code.
However, Hyper's client implementation appears to just return the RST_STREAM
message as an error and discards the response instead of handling it, which gives a hilariously confusing error message of:
error reading a body from connection: stream error received: not a result of an error
To be compliant with the spec, the implementation should stop sending the body and immediately read the response and return it.
For context, I'm using the Gcloud Storage API via https://crates.io/crates/aws-sdk-s3 (because the Gcloud Rust SDK doesn't support streaming bodies, but thankfully Gcloud Storage exposes an S3-compatible API), which uses Hyper internally. aws-sdk-s3
appears to be returning the error from Hyper verbatim, however.