http_body_to_bytes/
lib.rs1use bytes::{BufMut as _, Bytes};
2use http_body::Body as HttpBody;
3use http_body_util::BodyExt as _;
4
5pub async fn http_body_to_bytes<T>(body: T) -> Result<Bytes, T::Error>
6where
7 T: HttpBody,
8{
9 Ok(body.collect().await?.to_bytes())
10}
11
12pub async fn http_body_to_bytes_with_max_length<T>(
13 mut body: T,
14 max_length: usize,
15) -> Result<Bytes, Box<dyn std::error::Error + Send + Sync>>
16where
17 T: HttpBody + Unpin,
18{
19 let mut buf = Vec::with_capacity(max_length);
20 while let Some(Ok(frame)) = body.frame().await {
21 match frame.into_data() {
22 Ok(data) => buf.put(data),
23 Err(_frame) => {}
24 }
25 if buf.len() >= max_length {
26 return Ok(buf.into());
27 }
28 }
29 Ok(buf.into())
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35
36 use core::convert::Infallible;
37
38 use http_body::Frame;
39 use http_body_util::{Full, StreamBody};
40
41 #[tokio::test]
42 async fn test_http_body_to_bytes() {
43 let body = Full::<Bytes>::from("foo");
44 assert_eq!(
45 http_body_to_bytes(body).await.unwrap(),
46 Bytes::copy_from_slice(b"foo")
47 );
48 }
49
50 #[tokio::test]
51 async fn test_http_body_to_bytes_with_max_length() {
52 let body = Full::<Bytes>::from("foobar");
53 assert_eq!(
54 http_body_to_bytes_with_max_length(body, 3).await.unwrap(),
55 Bytes::copy_from_slice(b"foobar")
56 );
57
58 let chunks: Vec<Result<_, Infallible>> = vec![
59 Ok(Frame::data(Bytes::from("hello"))),
60 Ok(Frame::data(Bytes::from(" "))),
61 Ok(Frame::data(Bytes::from("world"))),
62 ];
63 let body = StreamBody::new(futures_util::stream::iter(chunks));
64 assert_eq!(
65 http_body_to_bytes_with_max_length(body, 3).await.unwrap(),
66 Bytes::copy_from_slice(b"hello")
67 );
68
69 let chunks: Vec<Result<_, Infallible>> = vec![
70 Ok(Frame::data(Bytes::from("fo"))),
71 Ok(Frame::data(Bytes::from("o"))),
72 Ok(Frame::data(Bytes::from("bar"))),
73 ];
74 let body = StreamBody::new(futures_util::stream::iter(chunks));
75 assert_eq!(
76 http_body_to_bytes_with_max_length(body, 3).await.unwrap(),
77 Bytes::copy_from_slice(b"foo")
78 );
79 }
80}