     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31

    use bytes::Buf;

    use super::HttpBody;
    use crate::common::buf::BufList;

    /// Aggregate the data buffers from a body asynchronously.
    ///
    /// The returned `impl Buf` groups the `Buf`s from the `HttpBody` without
    /// copying them. This is ideal if you don't require a contiguous buffer.
    ///
    /// # Note
    ///
    /// Care needs to be taken if the remote is untrusted. The function doesn't implement any length
    /// checks and an malicious peer might make it consume arbitrary amounts of memory. Checking the
    /// `Content-Length` is a possibility, but it is not strictly mandated to be present.
    pub async fn aggregate<T>(body: T) -> Result<impl Buf, T::Error>
    where
        T: HttpBody,
    {
        let mut bufs = BufList::new();

        futures_util::pin_mut!(body);
        while let Some(buf) = body.data().await {
            let buf = buf?;
            if buf.has_remaining() {
                bufs.push(buf);
            }
        }

        Ok(bufs)
    }