From fec64cf0abdc678e30ca5f1b310c5118b2e01999 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 19 Jun 2023 11:16:43 -0400 Subject: [PATCH] fix(http1): properly end chunked bodies when it was known to be empty (#3254) Closes #3252 --- src/proto/h1/dispatch.rs | 7 ++++++- tests/server.rs | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/proto/h1/dispatch.rs b/src/proto/h1/dispatch.rs index 912375b4ab..7f0d4c338d 100644 --- a/src/proto/h1/dispatch.rs +++ b/src/proto/h1/dispatch.rs @@ -368,7 +368,12 @@ where self.conn.end_body()?; } } else { - return Poll::Pending; + // If there's no body_rx, end the body + if self.conn.can_write_body() { + self.conn.end_body()?; + } else { + return Poll::Pending; + } } } } diff --git a/tests/server.rs b/tests/server.rs index 8561ab487c..7a1a5dd430 100644 --- a/tests/server.rs +++ b/tests/server.rs @@ -92,6 +92,7 @@ mod response_body_lengths { } fn run_test(case: TestCase) { + let _ = pretty_env_logger::try_init(); assert!( case.version == 0 || case.version == 1, "TestCase.version must 0 or 1" @@ -155,18 +156,22 @@ mod response_body_lengths { let n = body.find("\r\n\r\n").unwrap() + 4; if case.expects_chunked { - let len = body.len(); - assert_eq!( - &body[n + 1..n + 3], - "\r\n", - "expected body chunk size header" - ); - assert_eq!(&body[n + 3..len - 7], body_str, "expected body"); - assert_eq!( - &body[len - 7..], - "\r\n0\r\n\r\n", - "expected body final chunk size header" - ); + if body_str.len() > 0 { + let len = body.len(); + assert_eq!( + &body[n + 1..n + 3], + "\r\n", + "expected body chunk size header" + ); + assert_eq!(&body[n + 3..len - 7], body_str, "expected body"); + assert_eq!( + &body[len - 7..], + "\r\n0\r\n\r\n", + "expected body final chunk size header" + ); + } else { + assert_eq!(&body[n..], "0\r\n\r\n"); + } } else { assert_eq!(&body[n..], body_str, "expected body"); } @@ -217,6 +222,17 @@ mod response_body_lengths { }); } + #[test] + fn chunked_response_known_empty() { + run_test(TestCase { + version: 1, + headers: &[("transfer-encoding", "chunked")], + body: Bd::Known(""), + expects_chunked: true, // should still send chunked, and 0\r\n\r\n + expects_con_len: false, + }); + } + #[test] fn chunked_response_unknown() { run_test(TestCase {