[−][src]Struct hreq::Body
Body of an http request or response.
Creating a body
Bodies are created either by using a constructor function, or the Into
trait. The
into trait can be used where rust knows the result should be Body
such as in the request
builder .send()
.
use hreq::prelude::*; let res = Request::post("https://post-to-server/") // send has Into<Body> type, which means we can // provide the Into type straight up .send("some body content") .block().unwrap();
Or if we use .into()
explcitly.
use hreq::Body; // call into() to get a Body let body: Body = "some body content".into();
The constructor with corresponding expression usable with Into
.
Constructor | Into |
---|---|
Body::empty() | () |
Body::from_str("abc") | "abc" |
Body::from_string("abc".to_string()) | "abc".to_string() |
Body::from_bytes(&[42_u8, 43_u8]) | &[42_u8, 43_u8] |
Body::from_vec(vec![42_u8, 43_u8]) | vec![42_u8, 43_u8] |
Body::from_file(file) | file |
Body::from_async_read(reader, None) | - |
Body::from_sync_read(reader, None) | - |
Readers and performance
The most performant way provide a large body is as an AsyncRead
.
It will be streamed through hreq without using up too much memory.
Sync readers risks blocking the async runtime. This is not a big
concern if the reader is something like a std::io::Cursor
over
a slice of memory, or maybe even a std::fs::File
with a fast
disk. Choice of runtime also matters; async-std
tries to
automatically "parry" blocking operations. Use sync readers
with caution and prefer async readers.
charset encoding
hreq automatically encodes the request body's character encoding
for MIME types starting text/
.
The mechanic is triggered by setting a content-type
request header
with the charset that is wanted:
content-type: text/html charset=iso8859-1
The source material encoding is assumed to be utf-8
unless
changed by charset_encode_source
.
The behavior can be completely disabled using charset_encode
.
compression
hreq can compress the request body. The mechanic is triggered by setting
a content-encoding
header with the compression algorithm.
content-encoding: gzip
The only supported algorithm is gzip
.
Reading a body
hreq provides a number of ways to read the contents of a body.
Finaly Body
implements AsyncRead
, which means that in many cases, it can be used
as is in rust's async ecosystem.
use hreq::prelude::*; use futures_util::io::AsyncReadExt; let res = Request::get("https://my-special-host/") .call().block().unwrap(); let mut body = res.into_body(); let mut first_ten = vec![0_u8; 10]; // read_exact comes from AsyncReadExt body.read_exact(&mut first_ten[..]).block().unwrap();
charset decoding
hreq automatically decodes the response body's character encoding
for MIME types starting text/
.
The mechanic is triggered by receving a content-type
response header
with the charset of the incoming body:
content-type: text/html charset=iso8859-1
The wanted charset is assumed to be utf-8
unless changed by charset_decode_target
.
The function can be disabled by using charset_decode
.
compression
hreq decompresses the request body. The mechanic is triggered by the presence
of a content-encoding: gzip
response header.
One can "ask" the server to compress the response by providing a header like
accept-encoding: gzip
. There's however no guarantee the server will provide compression.
The only supported algorithm is currently gzip
.
Implementations
impl Body
[src]
pub fn empty() -> Self
[src]
Constructs an empty request body.
The content-length
is know to be 0
and will be set for requests where a body
is expected.
Examples
use hreq::Body; // The are the same. let body1: Body = Body::empty(); let body2: Body = ().into();
In Request.send()
we can skip the into()
use hreq::prelude::*; Request::get("https://get-from-here") .call().block().unwrap();
pub fn from_str(text: &str) -> Self
[src]
Creates a body from a &str
by cloning the data.
Will automatically set a content-length
header unless compression or
chunked encoding is used.
Examples
use hreq::Body; // The are the same. let body1: Body = Body::from_str("Hello world"); let body2: Body = "Hello world".into();
In Request.send()
we can skip the into()
use hreq::prelude::*; Request::post("https://post-to-here") .send("Hello world").block().unwrap();
pub fn from_string(text: String) -> Self
[src]
Creates a body from a String
.
Will automatically set a content-length
header unless compression or
chunked encoding is used.
Examples
use hreq::Body; // The are the same. let body1: Body = Body::from_string("Hello world".to_string()); let body2: Body = "Hello world".to_string().into();
In Request.send()
we can skip the into()
use hreq::prelude::*; Request::post("https://post-to-here") .send("Hello world".to_string()).block().unwrap();
pub fn from_bytes(bytes: &[u8]) -> Self
[src]
Creates a body from a &[u8]
by cloning the data.
Will automatically set a content-length
header unless compression or
chunked encoding is used.
Examples
use hreq::Body; let data = [0x42, 0x43]; // The are the same. let body1: Body = Body::from_bytes(&data[..]); let body2: Body = (&data[..]).into();
In Request.send()
we can skip the into()
use hreq::prelude::*; let data = [0x42, 0x43]; Request::post("https://post-to-here") .send(&data[..]).block().unwrap();
pub fn from_vec(bytes: Vec<u8>) -> Self
[src]
Creates a body from a Vec<u8>
.
Will automatically set a content-length
header unless compression or
chunked encoding is used.
Examples
use hreq::Body; // The are the same. let body1: Body = Body::from_vec(vec![0x42, 0x43]); let body2: Body = vec![0x42, 0x43].into();
In Request.send()
we can skip the into()
use hreq::prelude::*; Request::post("https://post-to-here") .send(vec![0x42, 0x43]).block().unwrap();
pub fn from_file(file: File) -> Self
[src]
Creates a body from a std::fs::File
.
Despite the std
origins, hreq will send this efficiently by reading
the file in a non-blocking way.
The request will have a content-length
header unless compression or
chunked encoding is used.
Examples
use hreq::Body; use std::fs::File; // The are the same. let body1: Body = Body::from_file(File::open("myfile.txt").unwrap()); let body2: Body = File::open("myfile.txt").unwrap().into();
In Request.send()
we can skip the into()
use hreq::prelude::*; use std::fs::File; Request::post("https://post-to-here") .send(File::open("myfile.txt").unwrap()).block().unwrap();
pub fn from_json<B: Serialize + ?Sized>(json: &B) -> Self
[src]
Creates a body from a JSON encodable type.
This also sets the content-type
and content-length
headers.
Example
use hreq::Body; use serde_derive::Serialize; #[derive(Serialize)] struct MyJsonThing { name: String, age: u8, } let json = MyJsonThing { name: "Karl Kajal".to_string(), age: 32, }; let body = Body::from_json(&json);
pub fn from_async_read<R>(reader: R, length: Option<u64>) -> Self where
R: AsyncRead + Unpin + Send + Sync + 'static,
[src]
R: AsyncRead + Unpin + Send + Sync + 'static,
Creates a body from anything implementing the AsyncRead
trait.
This is a very efficient way of sending bodies since the content
The content-length
header will be set depending on whether a
length
is provided. Combinations of charset and compression might
make it so content-length
is not known despite being provided.
pub fn from_sync_read<R>(reader: R, length: Option<u64>) -> Self where
R: Read + Send + Sync + 'static,
[src]
R: Read + Send + Sync + 'static,
Creates a body from anything implementing the (blocking) std::io::Read
trait.
Might block the async runtime, so whether using this is a good idea depends on
circumstances. If the Read
is just an std::io::Cursor
over some memory or
very fast file system, it might be ok. Some runtimes like async-std
further
have ways of detecting blocking operations.
Use with care.
The content-length
header will be set depending on whether a
length
is provided. Combinations of charset and compression might
make it so content-length
is not known despite being provided.
pub async fn read<'_, '_>(
&'_ mut self,
buf: &'_ mut [u8]
) -> Result<usize, Error>
[src]
&'_ mut self,
buf: &'_ mut [u8]
) -> Result<usize, Error>
Read some bytes from this body into the specified buffer, returning how many bytes were read.
If the returned amount is 0
, the end of the body has been reached.
See charset_decode
and charset_decode_target
of headers and options that will
affect text/
MIME types.
Examples
use hreq::prelude::*; let mut resp = Request::get("https://www.google.com") .call().block().unwrap(); let mut data = vec![0_u8; 100]; let amount = resp.body_mut().read(&mut data[..]).block().unwrap(); assert!(amount >= 15); assert_eq!(&data[..15], b"<!doctype html>");
pub async fn read_to_vec<'_>(&'_ mut self) -> Result<Vec<u8>, Error>
[src]
Reads to body to end into a new Vec
.
This can potentially take up a lot of memory (or even exhaust your RAM), depending on how big the response body is.
See charset_decode
and charset_decode_target
of headers and options that will
affect text/
MIME types.
Examples
use hreq::prelude::*; let mut resp = Request::get("https://www.google.com") .call().block().unwrap(); let data = resp.body_mut().read_to_vec().block().unwrap(); assert_eq!(&data[..15], b"<!doctype html>");
pub async fn read_to_string<'_>(&'_ mut self) -> Result<String, Error>
[src]
Reads to body to end into a new String
.
This can potentially take up a lot of memory (or even exhaust your RAM), depending on how big the response body is.
Since a rust string is always utf-8
, charset_decode_target
is ignored.
Panics if charset_decode
is disabled and incoming data is not valid UTF-8.
Examples
use hreq::prelude::*; let mut resp = Request::get("https://www.google.com") .call().block().unwrap(); let data = resp.body_mut().read_to_string().block().unwrap(); assert_eq!(&data[..15], "<!doctype html>");
pub async fn read_to_json<T: DeserializeOwned, '_>(
&'_ mut self
) -> Result<T, Error>
[src]
&'_ mut self
) -> Result<T, Error>
Reads to body to end as a JSON string into a deserialized object.
Examples
use hreq::Body; use serde_derive::Deserialize; #[derive(Deserialize)] struct MyJsonThing { name: String, age: String, } let req: MyJsonThing = Request::get("http://foo") .call().block().unwrap() .read_json().unwrap();
pub async fn read_to_end<'_>(&'_ mut self) -> Result<(), Error>
[src]
Reads to body to end and discards it.
HTTP/1.1 has no "multiplexing" of several concurrent request over the same socket; One must read the previous request's body to end before being able to read the next response header.
For pooled connections we can't reuse the connection until the previous body has been exhausted.
Examples
use hreq::prelude::*; let mut resp = Request::get("https://www.google.com") .call().block().unwrap(); resp.body_mut().read_to_end();
Trait Implementations
impl AsyncRead for Body
[src]
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context,
buf: &mut [u8]
) -> Poll<Result<usize>>
[src]
self: Pin<&mut Self>,
cx: &mut Context,
buf: &mut [u8]
) -> Poll<Result<usize>>
fn poll_read_vectored(
self: Pin<&mut Self>,
cx: &mut Context,
bufs: &mut [IoSliceMut]
) -> Poll<Result<usize, Error>>
[src]
self: Pin<&mut Self>,
cx: &mut Context,
bufs: &mut [IoSliceMut]
) -> Poll<Result<usize, Error>>
impl Debug for Body
[src]
impl<'a> From<&'a [u8]> for Body
[src]
impl<'a> From<&'a String> for Body
[src]
impl<'a> From<&'a Vec<u8>> for Body
[src]
impl<'a> From<&'a str> for Body
[src]
impl From<()> for Body
[src]
impl From<Body> for Reply
[src]
impl From<File> for Body
[src]
impl From<String> for Body
[src]
impl From<Vec<u8>> for Body
[src]
Auto Trait Implementations
impl !RefUnwindSafe for Body
impl Send for Body
impl Sync for Body
impl Unpin for Body
impl !UnwindSafe for Body
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<R> AsyncReadExt for R where
R: AsyncRead + ?Sized,
[src]
R: AsyncRead + ?Sized,
fn chain<R>(self, next: R) -> Chain<Self, R> where
R: AsyncRead,
[src]
R: AsyncRead,
fn read(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self> where
Self: Unpin,
[src]
Self: Unpin,
fn read_vectored(
&'a mut self,
bufs: &'a mut [IoSliceMut<'a>]
) -> ReadVectored<'a, Self> where
Self: Unpin,
[src]
&'a mut self,
bufs: &'a mut [IoSliceMut<'a>]
) -> ReadVectored<'a, Self> where
Self: Unpin,
fn read_exact(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self> where
Self: Unpin,
[src]
Self: Unpin,
fn read_to_end(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self> where
Self: Unpin,
[src]
Self: Unpin,
fn read_to_string(&'a mut self, buf: &'a mut String) -> ReadToString<'a, Self> where
Self: Unpin,
[src]
Self: Unpin,
fn split(self) -> (ReadHalf<Self>, WriteHalf<Self>) where
Self: AsyncWrite,
[src]
Self: AsyncWrite,
fn take(self, limit: u64) -> Take<Self>
[src]
impl<R> AsyncReadExt for R where
R: AsyncRead + ?Sized,
R: AsyncRead + ?Sized,
fn read(&'a mut self, buf: &'a mut [u8]) -> ReadFuture<'a, Self> where
Self: Unpin,
Self: Unpin,
fn read_vectored(
&'a mut self,
bufs: &'a mut [IoSliceMut<'a>]
) -> ReadVectoredFuture<'a, Self> where
Self: Unpin,
&'a mut self,
bufs: &'a mut [IoSliceMut<'a>]
) -> ReadVectoredFuture<'a, Self> where
Self: Unpin,
fn read_to_end(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEndFuture<'a, Self> where
Self: Unpin,
Self: Unpin,
fn read_to_string(
&'a mut self,
buf: &'a mut String
) -> ReadToStringFuture<'a, Self> where
Self: Unpin,
&'a mut self,
buf: &'a mut String
) -> ReadToStringFuture<'a, Self> where
Self: Unpin,
fn read_exact(&'a mut self, buf: &'a mut [u8]) -> ReadExactFuture<'a, Self> where
Self: Unpin,
Self: Unpin,
fn take(self, limit: u64) -> Take<Self>
fn bytes(self) -> Bytes<Self>
fn chain<R>(self, next: R) -> Chain<Self, R> where
R: AsyncRead,
R: AsyncRead,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T> Instrument for T
[src]
fn instrument(self, span: Span) -> Instrumented<Self>
[src]
fn in_current_span(self) -> Instrumented<Self>
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ReadExt for T where
T: AsyncRead + ?Sized,
T: AsyncRead + ?Sized,
fn read(&'a mut self, buf: &'a mut [u8]) -> ReadFuture<'a, Self> where
Self: Unpin,
Self: Unpin,
fn read_vectored(
&'a mut self,
bufs: &'a mut [IoSliceMut<'a>]
) -> ReadVectoredFuture<'a, Self> where
Self: Unpin,
&'a mut self,
bufs: &'a mut [IoSliceMut<'a>]
) -> ReadVectoredFuture<'a, Self> where
Self: Unpin,
fn read_to_end(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEndFuture<'a, Self> where
Self: Unpin,
Self: Unpin,
fn read_to_string(
&'a mut self,
buf: &'a mut String
) -> ReadToStringFuture<'a, Self> where
Self: Unpin,
&'a mut self,
buf: &'a mut String
) -> ReadToStringFuture<'a, Self> where
Self: Unpin,
fn read_exact(&'a mut self, buf: &'a mut [u8]) -> ReadExactFuture<'a, Self> where
Self: Unpin,
Self: Unpin,
fn take(self, limit: u64) -> Take<Self>
fn by_ref(&mut self) -> &mut Self
fn bytes(self) -> Bytes<Self>
fn chain<R>(self, next: R) -> Chain<Self, R> where
R: AsyncRead,
R: AsyncRead,
impl<T> Sealed<T> for T where
T: ?Sized,
T: ?Sized,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> WithSubscriber for T
[src]
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
[src]
S: Into<Dispatch>,