Fix HTTP/2 requests failing with duplicate Content-Length

When Yaak moved compression, redirect, and multipart handling out of
reqwest, it started explicitly adding Content-Length as an HTTP header.
Over HTTP/2, hyper also sets content-length internally via DATA frame
sizing, causing a duplicate that HTTP/2 servers (like Node.js) reject
with PROTOCOL_ERROR.

Instead of setting Content-Length as an explicit header, carry the
content length through SendableBody::Stream and use http_body::Body's
size_hint() to let hyper handle it automatically for both HTTP/1.1
and HTTP/2.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Gregory Schier
2026-02-11 11:49:36 -08:00
co-authored by Claude Opus 4.6
parent 26aba6034f
commit e6dbdc1db5
6 changed files with 216 additions and 58 deletions
+2 -2
View File
@@ -414,7 +414,7 @@ async fn execute_transaction<R: Runtime>(
sendable_request.body = Some(SendableBody::Bytes(bytes));
None
}
Some(SendableBody::Stream(stream)) => {
Some(SendableBody::Stream { data: stream, content_length }) => {
// Wrap stream with TeeReader to capture data as it's read
// Use unbounded channel to ensure all data is captured without blocking the HTTP request
let (body_chunk_tx, body_chunk_rx) = tokio::sync::mpsc::unbounded_channel::<Vec<u8>>();
@@ -448,7 +448,7 @@ async fn execute_transaction<R: Runtime>(
None
};
sendable_request.body = Some(SendableBody::Stream(pinned));
sendable_request.body = Some(SendableBody::Stream { data: pinned, content_length });
handle
}
None => {