Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/body/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,14 @@ impl Body {
#[cfg(all(feature = "http2", any(feature = "client", feature = "server")))]
pub(crate) fn h2(
recv: h2::RecvStream,
content_length: DecodedLength,
mut content_length: DecodedLength,
ping: ping::Recorder,
) -> Self {
// If the stream is already EOS, then the "unknown length" is clearly
// actually ZERO.
if !content_length.is_exact() && recv.is_end_stream() {
content_length = DecodedLength::ZERO;
}
let body = Body::new(Kind::H2 {
ping,
content_length,
Expand Down
10 changes: 10 additions & 0 deletions src/body/length.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,16 @@ impl DecodedLength {
}
}
}

/// Returns whether this represents an exact length.
///
/// This includes 0, which of course is an exact known length.
///
/// It would return false if "chunked" or otherwise size-unknown.
#[cfg(feature = "http2")]
pub(crate) fn is_exact(&self) -> bool {
self.0 <= MAX_LEN
}
}

impl fmt::Debug for DecodedLength {
Expand Down
9 changes: 5 additions & 4 deletions src/proto/h2/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,12 +484,13 @@ where
}
}

// automatically set Content-Length from body...
if let Some(len) = body.size_hint().exact() {
headers::set_content_length_if_missing(res.headers_mut(), len);
}

if !body.is_end_stream() {
// automatically set Content-Length from body...
if let Some(len) = body.size_hint().exact() {
headers::set_content_length_if_missing(res.headers_mut(), len);
}

let body_tx = reply!(me, res, false);
H2StreamState::Body {
pipe: PipeToSendStream::new(body, body_tx),
Expand Down
20 changes: 20 additions & 0 deletions tests/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,26 @@ mod response_body_lengths {
assert_eq!(res.headers().get("content-length").unwrap(), "10");
assert_eq!(res.body().size_hint().exact(), Some(10));
}

#[tokio::test]
async fn http2_implicit_empty_size_hint() {
use http_body::Body;

let server = serve();
let addr_str = format!("http://{}", server.addr());
server.reply();

let client = Client::builder()
.http2_only(true)
.build_http::<hyper::Body>();
let uri = addr_str
.parse::<hyper::Uri>()
.expect("server addr should parse");

let res = client.get(uri).await.unwrap();
assert_eq!(res.headers().get("content-length"), None);
assert_eq!(res.body().size_hint().exact(), Some(0));
}
}

#[test]
Expand Down