Skip to content

Commit beea332

Browse files
authored
fix decoding extra empty frame (#2508)
1 parent 177cc7f commit beea332

File tree

1 file changed

+44
-32
lines changed

1 file changed

+44
-32
lines changed

src/async_impl/decoder.rs

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -378,14 +378,10 @@ impl HttpBody for Decoder {
378378
Some(Err(err)) => Poll::Ready(Some(Err(crate::error::decode_io(err)))),
379379
None => {
380380
// poll inner connection until EOF after gzip stream is finished
381-
let inner_stream = decoder.get_mut().get_mut().get_mut().get_mut();
382-
match futures_core::ready!(Pin::new(inner_stream).poll_next(cx)) {
383-
Some(Ok(_)) => Poll::Ready(Some(Err(crate::error::decode(
384-
"there are extra bytes after body has been decompressed",
385-
)))),
386-
Some(Err(err)) => Poll::Ready(Some(Err(crate::error::decode_io(err)))),
387-
None => Poll::Ready(None),
388-
}
381+
poll_inner_should_be_empty(
382+
decoder.get_mut().get_mut().get_mut().get_mut(),
383+
cx,
384+
)
389385
}
390386
}
391387
}
@@ -396,14 +392,10 @@ impl HttpBody for Decoder {
396392
Some(Err(err)) => Poll::Ready(Some(Err(crate::error::decode_io(err)))),
397393
None => {
398394
// poll inner connection until EOF after brotli stream is finished
399-
let inner_stream = decoder.get_mut().get_mut().get_mut().get_mut();
400-
match futures_core::ready!(Pin::new(inner_stream).poll_next(cx)) {
401-
Some(Ok(_)) => Poll::Ready(Some(Err(crate::error::decode(
402-
"there are extra bytes after body has been decompressed",
403-
)))),
404-
Some(Err(err)) => Poll::Ready(Some(Err(crate::error::decode_io(err)))),
405-
None => Poll::Ready(None),
406-
}
395+
poll_inner_should_be_empty(
396+
decoder.get_mut().get_mut().get_mut().get_mut(),
397+
cx,
398+
)
407399
}
408400
}
409401
}
@@ -414,14 +406,10 @@ impl HttpBody for Decoder {
414406
Some(Err(err)) => Poll::Ready(Some(Err(crate::error::decode_io(err)))),
415407
None => {
416408
// poll inner connection until EOF after zstd stream is finished
417-
let inner_stream = decoder.get_mut().get_mut().get_mut().get_mut();
418-
match futures_core::ready!(Pin::new(inner_stream).poll_next(cx)) {
419-
Some(Ok(_)) => Poll::Ready(Some(Err(crate::error::decode(
420-
"there are extra bytes after body has been decompressed",
421-
)))),
422-
Some(Err(err)) => Poll::Ready(Some(Err(crate::error::decode_io(err)))),
423-
None => Poll::Ready(None),
424-
}
409+
poll_inner_should_be_empty(
410+
decoder.get_mut().get_mut().get_mut().get_mut(),
411+
cx,
412+
)
425413
}
426414
}
427415
}
@@ -432,14 +420,10 @@ impl HttpBody for Decoder {
432420
Some(Err(err)) => Poll::Ready(Some(Err(crate::error::decode_io(err)))),
433421
None => {
434422
// poll inner connection until EOF after deflate stream is finished
435-
let inner_stream = decoder.get_mut().get_mut().get_mut().get_mut();
436-
match futures_core::ready!(Pin::new(inner_stream).poll_next(cx)) {
437-
Some(Ok(_)) => Poll::Ready(Some(Err(crate::error::decode(
438-
"there are extra bytes after body has been decompressed",
439-
)))),
440-
Some(Err(err)) => Poll::Ready(Some(Err(crate::error::decode_io(err)))),
441-
None => Poll::Ready(None),
442-
}
423+
poll_inner_should_be_empty(
424+
decoder.get_mut().get_mut().get_mut().get_mut(),
425+
cx,
426+
)
443427
}
444428
}
445429
}
@@ -461,6 +445,34 @@ impl HttpBody for Decoder {
461445
}
462446
}
463447

448+
#[cfg(any(
449+
feature = "gzip",
450+
feature = "zstd",
451+
feature = "brotli",
452+
feature = "deflate"
453+
))]
454+
fn poll_inner_should_be_empty(
455+
inner: &mut PeekableIoStream,
456+
cx: &mut Context,
457+
) -> Poll<Option<Result<Frame<Bytes>, crate::Error>>> {
458+
// poll inner connection until EOF after deflate stream is finished
459+
// loop in case of empty frames
460+
let mut inner = Pin::new(inner);
461+
loop {
462+
match futures_core::ready!(inner.as_mut().poll_next(cx)) {
463+
// ignore any empty frames
464+
Some(Ok(bytes)) if bytes.is_empty() => continue,
465+
Some(Ok(_)) => {
466+
return Poll::Ready(Some(Err(crate::error::decode(
467+
"there are extra bytes after body has been decompressed",
468+
))))
469+
}
470+
Some(Err(err)) => return Poll::Ready(Some(Err(crate::error::decode_io(err)))),
471+
None => return Poll::Ready(None),
472+
}
473+
}
474+
}
475+
464476
#[cfg(any(
465477
feature = "gzip",
466478
feature = "zstd",

0 commit comments

Comments
 (0)