Struct Agent
pub struct Agent { /* private fields */ }
dep_ureq
only.Expand description
Agents keep state between requests.
By default, no state, such as cookies, is kept between requests. But by creating an agent as entry point for the request, we can keep a state.
§Example
let mut agent = ureq::agent();
agent
.post("http://example.com/post/login")
.send(b"my password")?;
let secret = agent
.get("http://example.com/get/my-protected-page")
.call()?
.body_mut()
.read_to_string()?;
println!("Secret is: {}", secret);
§About threads and cloning
Agent uses inner Arc
. Cloning an Agent results in an instance
that shares the same underlying connection pool and other state.
The connection pool contains an inner Mutex
which is (briefly)
held when borrowing a pooled connection, or returning a connection to the pool.
All request functions in ureq have a signature similar to this:
fn run(request: http::Request<impl AsSendBody>) -> Result<http::Response<Body>, Error> {
// <something>
}
It follows that:
- An Agent is borrowed for the duration of:
- Sending the request header (
http::Request
) - Sending the request body (
SendBody
) - Receiving the response header (
http::Response
)
- Sending the request header (
- The
Body
of the response is not bound to the lifetime of the Agent.
A response Body
can be streamed (for instance via Body::into_reader()
). The Body
implements Send
, which means it’s possible to read the response body on another thread than
the one that run the request. Behind the scenes, the Body
retains the connection to the remote
server and it is returned to the agent’s pool, once the Body instance (or reader) is dropped.
There is an asymmetry in that sending a request body will borrow the Agent instance, while receiving
the response body does not. This inconvencience is somewhat mitigated by that Agent::run()
(or
going via the methods such as Agent::get()
), borrows &self
, i.e. not exclusive mut
borrows.
That cloning the agent shares the connection pool is considered a feature. It is often useful to
retain a single pool for the entire process, while dispatching requests from different threads.
And if we want separate pools, we can create multiple agents via one of the constructors
(such as Agent::new_with_config()
).
Note that both Config::clone()
and Agent::clone()
are “cheap” meaning they should not
incur any heap allocation.
Implementations§
§impl Agent
impl Agent
pub fn new_with_defaults() -> Agent
pub fn new_with_defaults() -> Agent
Creates an agent with defaults.
pub fn new_with_config(config: Config) -> Agent
pub fn new_with_config(config: Config) -> Agent
Creates an agent with config.
pub fn config_builder() -> ConfigBuilder<AgentScope>
pub fn config_builder() -> ConfigBuilder<AgentScope>
Shortcut to reach a ConfigBuilder
This is the same as doing Config::builder()
.
pub fn with_parts(
config: Config,
connector: impl Connector,
resolver: impl Resolver,
) -> Agent
pub fn with_parts( config: Config, connector: impl Connector, resolver: impl Resolver, ) -> Agent
Creates an agent with a bespoke transport and resolver.
This is low level API that isn’t for regular use of ureq.
pub fn run(
&self,
request: Request<impl AsSendBody>,
) -> Result<Response<Body>, Error> ⓘ
pub fn run( &self, request: Request<impl AsSendBody>, ) -> Result<Response<Body>, Error> ⓘ
Run a http::Request<impl AsSendBody>
.
Used to execute http crate http::Request
directly on this agent.
§Example
use ureq::{http, Agent};
let agent: Agent = Agent::new_with_defaults();
let mut request =
http::Request::get("http://httpbin.org/get")
.body(())?;
let body = agent.run(request)?
.body_mut()
.read_to_string()?;
pub fn configure_request<S>(
&self,
request: Request<S>,
) -> ConfigBuilder<HttpCrateScope<S>>where
S: AsSendBody,
pub fn configure_request<S>(
&self,
request: Request<S>,
) -> ConfigBuilder<HttpCrateScope<S>>where
S: AsSendBody,
Alter the configuration for an http crate request.
Notice: It’s an error to configure a http::Request
using
one instance of Agent
and run using another instance. The
library does not currently detect this situation, but it is
not considered a breaking change if this is enforced in
the future.
pub fn get<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
pub fn get<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
Make a GET request using this agent.
pub fn post<T>(&self, uri: T) -> RequestBuilder<WithBody>
pub fn post<T>(&self, uri: T) -> RequestBuilder<WithBody>
Make a POST request using this agent.
pub fn put<T>(&self, uri: T) -> RequestBuilder<WithBody>
pub fn put<T>(&self, uri: T) -> RequestBuilder<WithBody>
Make a PUT request using this agent.
pub fn delete<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
pub fn delete<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
Make a DELETE request using this agent.
pub fn head<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
pub fn head<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
Make a HEAD request using this agent.
pub fn options<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
pub fn options<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
Make an OPTIONS request using this agent.
pub fn connect<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
pub fn connect<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
Make a CONNECT request using this agent.
pub fn patch<T>(&self, uri: T) -> RequestBuilder<WithBody>
pub fn patch<T>(&self, uri: T) -> RequestBuilder<WithBody>
Make a PATCH request using this agent.
pub fn trace<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
pub fn trace<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
Make a TRACE request using this agent.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Agent
impl !RefUnwindSafe for Agent
impl Send for Agent
impl Sync for Agent
impl Unpin for Agent
impl !UnwindSafe for Agent
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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