Struct Body
pub struct Body { /* private fields */ }
dep_ureq
only.Expand description
A response body returned as http::Response<Body>
.
§Body lengths
HTTP/1.1 has two major modes of transfering body data. Either a Content-Length
header defines exactly how many bytes to transfer, or Transfer-Encoding: chunked
facilitates a streaming style when the size is not known up front.
To protect against a problem called request smuggling, ureq has heuristics for
how to interpret a server sending both Transfer-Encoding
and Content-Length
headers.
chunked
takes precedence if there both headers are present (not for HTTP/1.0)content-length
is used if there is no chunked- If there are no headers, fall back on “close delimited” meaning the socket must close to end the body
When a Content-Length
header is used, ureq will ensure the received body is EXACTLY
as many bytes as declared (it cannot be less). This mechanic is in ureq-proto
and is different to the BodyWithConfig::limit()
below.
§Pool reuse
To return a connection (aka Transport
)
to the Agent’s pool, the body must be read to end. If BodyWithConfig::limit()
is set
shorter size than the actual response body, the connection will not be reused.
§Example
use std::io::Read;
let mut res = ureq::get("http://httpbin.org/bytes/100")
.call()?;
assert!(res.headers().contains_key("Content-Length"));
let len: usize = res.headers().get("Content-Length")
.unwrap().to_str().unwrap().parse().unwrap();
let mut bytes: Vec<u8> = Vec::with_capacity(len);
res.body_mut().as_reader()
.read_to_end(&mut bytes)?;
assert_eq!(bytes.len(), len);
Implementations§
§impl Body
impl Body
pub fn builder() -> BodyBuilder
pub fn builder() -> BodyBuilder
Builder for creating a body
This is useful for testing, or for Middleware
that
returns another body than the requested one.
pub fn mime_type(&self) -> Option<&str> ⓘ
pub fn mime_type(&self) -> Option<&str> ⓘ
The mime-type of the content-type
header.
For the below header, we would get Some("text/plain")
:
Content-Type: text/plain; charset=iso-8859-1
Caution: A bad server might set Content-Type
to one thing and send
something else. There is no way ureq can verify this.
§Example
let res = ureq::get("https://www.google.com/")
.call()?;
assert_eq!(res.body().mime_type(), Some("text/html"));
pub fn charset(&self) -> Option<&str> ⓘ
pub fn charset(&self) -> Option<&str> ⓘ
The charset of the content-type
header.
For the below header, we would get Some("iso-8859-1")
:
Content-Type: text/plain; charset=iso-8859-1
Caution: A bad server might set Content-Type
to one thing and send
something else. There is no way ureq can verify this.
§Example
let res = ureq::get("https://www.google.com/")
.call()?;
assert_eq!(res.body().charset(), Some("ISO-8859-1"));
pub fn content_length(&self) -> Option<u64> ⓘ
pub fn content_length(&self) -> Option<u64> ⓘ
The content length of the body.
This is the value of the Content-Length
header, if there is one. For chunked
responses (Transfer-Encoding: chunked
) , this will be None
. Similarly for
HTTP/1.0 without a Content-Length
header, the response is close delimited,
which means the length is unknown.
A bad server might set Content-Length
to one thing and send something else.
ureq will double check this, see section on body length heuristics.
§Example
let res = ureq::get("https://httpbin.org/bytes/100")
.call()?;
assert_eq!(res.body().content_length(), Some(100));
pub fn as_reader(&mut self) -> BodyReader<'_> ⓘ
pub fn as_reader(&mut self) -> BodyReader<'_> ⓘ
Handle this body as a shared impl Read
of the body.
This is the regular API which goes via http::Response::body_mut()
to get a
mut reference to the Body
, and then use as_reader()
. It is also possible to
get a non-shared, owned reader via Body::into_reader()
.
- Reader is not limited. To set a limit use
Body::with_config()
.
§Example
use std::io::Read;
let mut res = ureq::get("http://httpbin.org/bytes/100")
.call()?;
let mut bytes: Vec<u8> = Vec::with_capacity(1000);
res.body_mut().as_reader()
.read_to_end(&mut bytes)?;
pub fn into_reader(self) -> BodyReader<'static> ⓘ
pub fn into_reader(self) -> BodyReader<'static> ⓘ
Turn this response into an owned impl Read
of the body.
Sometimes it might be useful to disconnect the body reader from the body.
The reader returned by Body::as_reader()
borrows the body, while this
variant consumes the body and turns it into a reader with lifetime 'static
.
The reader can for instance be sent to another thread.
- Reader is not limited. To set a limit use
Body::into_with_config()
.
use std::io::Read;
let res = ureq::get("http://httpbin.org/bytes/100")
.call()?;
let (_, body) = res.into_parts();
let mut bytes: Vec<u8> = Vec::with_capacity(1000);
body.into_reader()
.read_to_end(&mut bytes)?;
pub fn read_to_string(&mut self) -> Result<String, Error> ⓘ
pub fn read_to_string(&mut self) -> Result<String, Error> ⓘ
Read the response as a string.
- Response is limited to 10MB
- Replaces incorrect utf-8 chars to
?
To change these defaults use Body::with_config()
.
let mut res = ureq::get("http://httpbin.org/robots.txt")
.call()?;
let s = res.body_mut().read_to_string()?;
assert_eq!(s, "User-agent: *\nDisallow: /deny\n");
pub fn read_to_vec(&mut self) -> Result<Vec<u8>, Error> ⓘ
pub fn read_to_vec(&mut self) -> Result<Vec<u8>, Error> ⓘ
Read the response to a vec.
- Response is limited to 10MB.
To change this default use Body::with_config()
.
let mut res = ureq::get("http://httpbin.org/bytes/100")
.call()?;
let bytes = res.body_mut().read_to_vec()?;
assert_eq!(bytes.len(), 100);
pub fn with_config(&mut self) -> BodyWithConfig<'_>
pub fn with_config(&mut self) -> BodyWithConfig<'_>
Read the body data with configuration.
This borrows the body which gives easier use with http::Response::body_mut()
.
To get a non-borrowed reader use Body::into_with_config()
.
§Example
let reader = ureq::get("http://httpbin.org/bytes/100")
.call()?
.body_mut()
.with_config()
// Reader will only read 50 bytes
.limit(50)
.reader();
pub fn into_with_config(self) -> BodyWithConfig<'static>
pub fn into_with_config(self) -> BodyWithConfig<'static>
Consume self and read the body with configuration.
This consumes self and returns a reader with 'static
lifetime.
§Example
// Get the body out of http::Response
let (_, body) = ureq::get("http://httpbin.org/bytes/100")
.call()?
.into_parts();
let reader = body
.into_with_config()
// Reader will only read 50 bytes
.limit(50)
.reader();
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for Body
impl !RefUnwindSafe for Body
impl Send for Body
impl Sync for Body
impl Unpin for Body
impl !UnwindSafe for Body
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> ByteSized for T
impl<T> ByteSized for T
Source§const BYTE_ALIGN: usize = _
const BYTE_ALIGN: usize = _
Source§fn byte_align(&self) -> usize
fn byte_align(&self) -> usize
Source§fn ptr_size_ratio(&self) -> [usize; 2]
fn ptr_size_ratio(&self) -> [usize; 2]
Source§impl<T, R> Chain<R> for Twhere
T: ?Sized,
impl<T, R> Chain<R> for Twhere
T: ?Sized,
Source§impl<T> ExtAny for T
impl<T> ExtAny for T
Source§fn type_hash_with<H: Hasher>(&self, hasher: H) -> u64
fn type_hash_with<H: Hasher>(&self, hasher: H) -> u64
TypeId
of Self
using a custom hasher.Source§fn as_any_mut(&mut self) -> &mut dyn Anywhere
Self: Sized,
fn as_any_mut(&mut self) -> &mut dyn Anywhere
Self: Sized,
Source§impl<T> ExtMem for Twhere
T: ?Sized,
impl<T> ExtMem for Twhere
T: ?Sized,
Source§const NEEDS_DROP: bool = _
const NEEDS_DROP: bool = _
Source§fn mem_align_of<T>() -> usize
fn mem_align_of<T>() -> usize
Source§fn mem_align_of_val(&self) -> usize
fn mem_align_of_val(&self) -> usize
Source§fn mem_size_of<T>() -> usize
fn mem_size_of<T>() -> usize
Source§fn mem_size_of_val(&self) -> usize
fn mem_size_of_val(&self) -> usize
Source§fn mem_needs_drop(&self) -> bool
fn mem_needs_drop(&self) -> bool
true
if dropping values of this type matters. Read moreSource§fn mem_forget(self)where
Self: Sized,
fn mem_forget(self)where
Self: Sized,
self
without running its destructor. Read moreSource§fn mem_replace(&mut self, other: Self) -> Selfwhere
Self: Sized,
fn mem_replace(&mut self, other: Self) -> Selfwhere
Self: Sized,
Source§unsafe fn mem_zeroed<T>() -> T
unsafe fn mem_zeroed<T>() -> T
unsafe_layout
only.T
represented by the all-zero byte-pattern. Read moreSource§unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst
unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst
unsafe_layout
only.T
represented by the all-zero byte-pattern. Read moreSource§fn mem_as_bytes(&self) -> &[u8] ⓘ
fn mem_as_bytes(&self) -> &[u8] ⓘ
unsafe_slice
only.§impl<S> FromSample<S> for S
impl<S> FromSample<S> for S
fn from_sample_(s: S) -> S
Source§impl<T> Hook for T
impl<T> Hook for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more