From a0a7a53a143798d71884df36cfac4dd36cd087e6 Mon Sep 17 00:00:00 2001 From: cfal Date: Fri, 16 Oct 2026 12:38:23 +0000 Subject: [PATCH] fix: skip empty DATA frames when receiving body data --- h3/src/connection.rs | 3 ++- h3/src/tests/request.rs | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/h3/src/connection.rs b/h3/src/connection.rs index 44302f1a..cfac6d2d 100644 --- a/h3/src/connection.rs +++ b/h3/src/connection.rs @@ -855,7 +855,8 @@ where &mut self, cx: &mut Context<'_>, ) -> Poll, StreamError>> { - if !self.stream.has_data() { + // Empty DATA frames do not end the body. + while !self.stream.has_data() { match ready!(self.stream.poll_next(cx)) { Err(frame_stream_error) => { return Poll::Ready(Err( diff --git a/h3/src/tests/request.rs b/h3/src/tests/request.rs index 158db7b5..a8ecfa91 100644 --- a/h3/src/tests/request.rs +++ b/h3/src/tests/request.rs @@ -1091,6 +1091,27 @@ async fn request_valid_header_multiple_data_trailer() { .await; } +#[tokio::test] +async fn request_valid_empty_data_frames() { + for with_trailers in [false, true] { + request_sequence_ok(|mut buf| { + request_encode( + &mut buf, + Request::post("http://localhost/salut").body(()).unwrap(), + ); + for chunk in ["", "", "hello", "", "", " world", "", ""] { + Frame::Data(Bytes::from(chunk)).encode_with_payload(&mut buf); + } + if with_trailers { + let mut trailers = HeaderMap::new(); + trailers.insert("trailer", "value".parse().unwrap()); + trailers_encode(buf, trailers); + } + }) + .await; + } +} + #[tokio::test] async fn request_valid_header_trailer() { request_sequence_ok(|mut buf| {