pub struct ResponseBody<'a> { /* private fields */ }Expand description
A response body received from a server.
Most of the time this represents a body that will be read from the underlying transport, but it
can also wrap an override body installed by middleware via ConnExt::set_response_body
— e.g. cache hits, mocked responses, or circuit-breaker short-circuits. Reads, encoding
handling, and max_len enforcement work transparently across both cases.
use trillium_client::Client;
use trillium_testing::{client_config, with_server};
with_server("hello from trillium", |url| async move {
let client = Client::new(client_config());
let mut conn = client.get(url).await?;
let body = conn.response_body(); //<-
assert_eq!(Some(19), body.content_length());
assert_eq!("hello from trillium", body.read_string().await?);
Ok(())
});§Bounds checking
Every ResponseBody has a maximum length beyond which it will return an error, expressed as a
u64. To override this on the specific ResponseBody, use ResponseBody::with_max_len or
ResponseBody::set_max_len. The bound is enforced on override bodies as well as
transport-backed ones, so a user-set memory cap holds even when middleware has replaced the
body with externally-sourced bytes.
Implementations§
Source§impl ResponseBody<'_>
impl ResponseBody<'_>
Sourcepub async fn read_bytes(self) -> Result<Vec<u8>, Error>
pub async fn read_bytes(self) -> Result<Vec<u8>, Error>
Similar to ResponseBody::read_string, but returns the raw bytes. This is useful for
bodies that are not text.
You can use this in conjunction with encoding if you need different handling of malformed
character encoding than the lossy conversion provided by ResponseBody::read_string.
An empty or nonexistent body will yield an empty Vec, not an error.
§Errors
This will return an error if there is an IO error on the underlying transport such as a disconnect.
This will also return an error if the length exceeds the maximum length. To configure the
value on this specific request body, use ResponseBody::with_max_len or
ResponseBody::set_max_len
Sourcepub async fn read_string(self) -> Result<String, Error>
pub async fn read_string(self) -> Result<String, Error>
Reads the entire body to a String.
Uses the encoding determined by the content-type (mime) charset. If an encoding problem
is encountered, the returned String will contain utf8 replacement characters.
Note that this can only be performed once per Conn, as the underlying data is not cached anywhere. This is the only copy of the body contents.
An empty or nonexistent body will yield an empty String, not an error
§Errors
This will return an error if there is an IO error on the underlying transport such as a disconnect
This will also return an error if the length exceeds the maximum length. To configure the
value on this specific response body, use ResponseBody::with_max_len or
ResponseBody::set_max_len.
Sourcepub fn with_max_len(self, max_len: u64) -> Self
pub fn with_max_len(self, max_len: u64) -> Self
Set the maximum content length to read, returning self
This protects against a memory-use denial-of-service attack wherein an untrusted peer sends
an unbounded request body. This is especially important when using
ResponseBody::read_string and ResponseBody::read_bytes instead of streaming with
AsyncRead.
The default value can be found documented in the trillium-http crate
Sourcepub fn set_max_len(&mut self, max_len: u64) -> &mut Self
pub fn set_max_len(&mut self, max_len: u64) -> &mut Self
Set the maximum content length to read
This protects against a memory-use denial-of-service attack wherein an untrusted peer sends
an unbounded request body. This is especially important when using
ResponseBody::read_string and ResponseBody::read_bytes instead of streaming with
AsyncRead.
The default value can be found documented in the trillium-http crate
Sourcepub fn content_length(&self) -> Option<u64>
pub fn content_length(&self) -> Option<u64>
The content-length of this body, if available.
Usually derived from the content-length header. If the response uses
transfer-encoding chunked, this will be None.
Source§impl ResponseBody<'static>
impl ResponseBody<'static>
Sourcepub async fn recycle(self)
pub async fn recycle(self)
Drains and pools the underlying transport when worthwhile, closes it otherwise.
Use this to release a keepalive transport synchronously before reissuing a request on
the same client — the redirect/retry handler pattern. For an h1.1 keepalive transport
this drives the body to EOF and returns the transport to the pool. For a non-keepalive
transport this calls transport.close() directly without draining (since draining
would just waste bytes on a connection we’re about to close).
For an Override body (cache hit, mocked response, tee), this is a no-op — the body’s own components handle their own teardown when dropped.
Trait Implementations§
Source§impl AsyncRead for ResponseBody<'_>
impl AsyncRead for ResponseBody<'_>
Source§impl BodySource for ResponseBody<'static>
impl BodySource for ResponseBody<'static>
Source§impl Debug for ResponseBody<'_>
impl Debug for ResponseBody<'_>
Source§impl Drop for ResponseBody<'_>
impl Drop for ResponseBody<'_>
Source§impl<'a> From<ReceivedBody<'a, Box<dyn Transport>>> for ResponseBody<'a>
impl<'a> From<ReceivedBody<'a, Box<dyn Transport>>> for ResponseBody<'a>
Source§impl<'a> IntoFuture for ResponseBody<'a>
impl<'a> IntoFuture for ResponseBody<'a>
Source§type IntoFuture = Pin<Box<dyn Future<Output = <ResponseBody<'a> as IntoFuture>::Output> + Send + 'a>>
type IntoFuture = Pin<Box<dyn Future<Output = <ResponseBody<'a> as IntoFuture>::Output> + Send + 'a>>
Source§fn into_future(self) -> Self::IntoFuture
fn into_future(self) -> Self::IntoFuture
Auto Trait Implementations§
impl<'a> Freeze for ResponseBody<'a>
impl<'a> !RefUnwindSafe for ResponseBody<'a>
impl<'a> Send for ResponseBody<'a>
impl<'a> Sync for ResponseBody<'a>
impl<'a> Unpin for ResponseBody<'a>
impl<'a> UnsafeUnpin for ResponseBody<'a>
impl<'a> !UnwindSafe for ResponseBody<'a>
Blanket Implementations§
Source§impl<R> AsyncReadExt for R
impl<R> AsyncReadExt for R
Source§fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadFuture<'a, Self>where
Self: Unpin,
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadFuture<'a, Self>where
Self: Unpin,
Source§fn read_vectored<'a>(
&'a mut self,
bufs: &'a mut [IoSliceMut<'a>],
) -> ReadVectoredFuture<'a, Self>where
Self: Unpin,
fn read_vectored<'a>(
&'a mut self,
bufs: &'a mut [IoSliceMut<'a>],
) -> ReadVectoredFuture<'a, Self>where
Self: Unpin,
Source§fn read_to_end<'a>(
&'a mut self,
buf: &'a mut Vec<u8>,
) -> ReadToEndFuture<'a, Self>where
Self: Unpin,
fn read_to_end<'a>(
&'a mut self,
buf: &'a mut Vec<u8>,
) -> ReadToEndFuture<'a, Self>where
Self: Unpin,
Source§fn read_to_string<'a>(
&'a mut self,
buf: &'a mut String,
) -> ReadToStringFuture<'a, Self>where
Self: Unpin,
fn read_to_string<'a>(
&'a mut self,
buf: &'a mut String,
) -> ReadToStringFuture<'a, Self>where
Self: Unpin,
Source§fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExactFuture<'a, Self>where
Self: Unpin,
fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExactFuture<'a, Self>where
Self: Unpin,
buf. Read moreSource§fn take(self, limit: u64) -> Take<Self>where
Self: Sized,
fn take(self, limit: u64) -> Take<Self>where
Self: Sized,
limit bytes from it. Read more