1 | use bytes::Buf; |
2 | |
3 | use super::HttpBody; |
4 | use crate::common::buf::BufList; |
5 | |
6 | /// Aggregate the data buffers from a body asynchronously. |
7 | /// |
8 | /// The returned `impl Buf` groups the `Buf`s from the `HttpBody` without |
9 | /// copying them. This is ideal if you don't require a contiguous buffer. |
10 | /// |
11 | /// # Note |
12 | /// |
13 | /// Care needs to be taken if the remote is untrusted. The function doesn't implement any length |
14 | /// checks and an malicious peer might make it consume arbitrary amounts of memory. Checking the |
15 | /// `Content-Length` is a possibility, but it is not strictly mandated to be present. |
16 | pub async fn aggregate<T>(body: T) -> Result<impl Buf, T::Error> |
17 | where |
18 | T: HttpBody, |
19 | { |
20 | let mut bufs: BufList<::Data> = BufList::new(); |
21 | |
22 | futures_util::pin_mut!(body); |
23 | while let Some(buf: Result<::Data, …>) = body.data().await { |
24 | let buf: ::Data = buf?; |
25 | if buf.has_remaining() { |
26 | bufs.push(buf); |
27 | } |
28 | } |
29 | |
30 | Ok(bufs) |
31 | } |
32 | |