-
Notifications
You must be signed in to change notification settings - Fork 237
Description
Summary
aws_smithy_http_client::test_util::dvr::RecordingClient can cause real AWS SDK requests with non-streaming request bodies to fail (observed as 400 Bad Request from awselb/2.0). The same request succeeds when using the standard client without RecordingClient.
Reproduction
- Use
RecordingClientas the SDK HTTP client (viaaws_config::defaults(...).http_client(recording_client.clone())). - Call an operation with a small JSON request body (non-streaming;
SdkBody::bytes()is available), e.g. Bedrock Runtimeconverse_stream.
Observed failure:
- Response is
400 Bad Requestwithcontent-type: text/htmlfromawselb/2.0 - The request is correctly signed and has
Content-Length, etc. - If request body recording is disabled (i.e., don't swap the request body), the request succeeds.
Root cause
RecordingClient records request bodies by replacing the body with a channel-backed streaming body and spawning a task to forward data from the original body into that channel. For non-streaming request bodies, this channel-based approach can cause timing/framing issues (particularly with HTTP/2), leading to malformed requests on the wire.
Proposed fix
For non-streaming request bodies (SdkBody::bytes() returns Some), buffer the bytes up front:
- Copy the bytes.
- Record them into the DVR event stream.
- Replace the request body with a new
SdkBodycreated from the same bytes.
For streaming request bodies, keep the existing channel-based path.
Additionally, preserve size hints for the channel-backed body by passing through content_length() to keep the replacement body's size_hint() consistent with Content-Length.
Notes
- Response body recording continues to use the channel-based approach (works fine since we're consuming, not producing).
- This is in test-util DVR code; no change to production client stacks.
I've already fixed the issue locally and I'll be making a PR momentarily.