pub struct SharedBody<B>{ /* private fields */ }Expand description
A cloneable HTTP body wrapper that allows multiple consumers to share the same body.
SharedBody wraps any http_body::Body that is Unpin and whose data and error types
implement Clone, allowing it to be cloned and consumed by multiple tasks simultaneously.
All clones share the same underlying body state and position.
§Examples
Basic usage with concurrent consumers:
use shared_http_body::SharedBody;
use http_body_util::{BodyExt, StreamBody};
use http_body::Frame;
use bytes::Bytes;
use futures_util::stream;
let chunks = vec!["hello", "world"];
let stream = stream::iter(chunks.into_iter().map(|s| Ok::<_, std::convert::Infallible>(Frame::data(Bytes::from(s)))));
let body = StreamBody::new(stream);
let shared_body = SharedBody::new(body);
// Create multiple consumers
let consumer1 = shared_body.clone();
let consumer2 = shared_body.clone();
// Both will receive all frames
let result1 = consumer1.collect().await.unwrap().to_bytes();
let result2 = consumer2.collect().await.unwrap().to_bytes();
assert_eq!(result1, Bytes::from("helloworld"));
assert_eq!(result2, Bytes::from("helloworld"));Cloning after partial consumption:
use shared_http_body::SharedBody;
use http_body_util::{BodyExt, StreamBody};
use http_body::Frame;
use bytes::Bytes;
use futures_util::stream;
let chunks = vec!["first", "second", "third"];
let stream = stream::iter(chunks.into_iter().map(|s| Ok::<_, std::convert::Infallible>(Frame::data(Bytes::from(s)))));
let body = StreamBody::new(stream);
let mut shared_body = SharedBody::new(body);
// Consume first frame
use http_body_util::BodyExt;
let _ = http_body_util::BodyExt::frame(&mut shared_body).await;
// Clone after partial consumption
let cloned = shared_body.clone();
let remaining = cloned.collect().await.unwrap().to_bytes();
// Clone only sees remaining frames
assert_eq!(remaining, Bytes::from("secondthird"));§Requirements
The wrapped body must satisfy these bounds:
http_body::Body: The type must implement the Body traitUnpin: Required for safe polling without pinningCloneforBody::Data: The data type must be cloneableCloneforBody::Error: The error type must be cloneable
§Thread Safety
SharedBody is both Send and Sync when the underlying body and its data/error types
are Send and Sync. This means cloned bodies can be safely moved across threads
and shared between tasks running on different threads.
Implementations§
Sourcepub fn new(body: B) -> Self
pub fn new(body: B) -> Self
Creates a new SharedBody from the given HTTP body.
The body must implement Unpin, and both its data type (Body::Data) and
error type (Body::Error) must implement Clone. Once created, the SharedBody
can be cloned to create multiple consumers that all share the same underlying body state.
§Examples
use shared_http_body::SharedBody;
use http_body_util::StreamBody;
use http_body::Frame;
use bytes::Bytes;
use futures_util::stream;
let chunks = vec!["hello", "world"];
let stream = stream::iter(chunks.into_iter().map(|s| Ok::<_, std::convert::Infallible>(Frame::data(Bytes::from(s)))));
let body = StreamBody::new(stream);
let shared_body = SharedBody::new(body);§Panics
This method does not panic under normal circumstances.
Trait Implementations§
Auto Trait Implementations§
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
SharedBody. Read more