Struct Agent

Source
pub struct Agent { /* private fields */ }
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:
    1. Sending the request header (http::Request)
    2. Sending the request body (SendBody)
    3. Receiving the response header (http::Response)
  • 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§

Source§

impl Agent

Source

pub fn new_with_defaults() -> Self

Creates an agent with defaults.

Source

pub fn new_with_config(config: Config) -> Self

Creates an agent with config.

Source

pub fn config_builder() -> ConfigBuilder<AgentScope>

Shortcut to reach a ConfigBuilder

This is the same as doing Config::builder().

Source

pub fn with_parts( config: Config, connector: impl Connector, resolver: impl Resolver, ) -> Self

Creates an agent with a bespoke transport and resolver.

This is low level API that isn’t for regular use of ureq.

Source

pub fn cookie_jar_lock(&self) -> CookieJar<'_>

Access the shared cookie jar.

Used to persist and manipulate the cookies. The jar is shared between all clones of the same Agent, meaning you must drop the CookieJar before using the agent, or end up with a deadlock.

use std::io::Write;
use std::fs::File;

let agent = ureq::agent();

// Cookies set by www.google.com are stored in agent.
agent.get("https://www.google.com/").call()?;

// Saves (persistent) cookies
let mut file = File::create("cookies.json")?;
let jar = agent.cookie_jar_lock();

jar.save_json(&mut file)?;

// Release the cookie jar to use agents again.
jar.release();
Source

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()?;
Source

pub fn config(&self) -> &Config

Get the config for this agent.

Source

pub fn configure_request<S: AsSendBody>( &self, request: Request<S>, ) -> ConfigBuilder<HttpCrateScope<S>>

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.

Source

pub fn get<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<Error>,

Make a GET request using this agent.

Source

pub fn post<T>(&self, uri: T) -> RequestBuilder<WithBody>
where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<Error>,

Make a POST request using this agent.

Source

pub fn put<T>(&self, uri: T) -> RequestBuilder<WithBody>
where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<Error>,

Make a PUT request using this agent.

Source

pub fn delete<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<Error>,

Make a DELETE request using this agent.

Source

pub fn head<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<Error>,

Make a HEAD request using this agent.

Source

pub fn options<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<Error>,

Make an OPTIONS request using this agent.

Source

pub fn connect<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<Error>,

Make a CONNECT request using this agent.

Source

pub fn patch<T>(&self, uri: T) -> RequestBuilder<WithBody>
where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<Error>,

Make a PATCH request using this agent.

Source

pub fn trace<T>(&self, uri: T) -> RequestBuilder<WithoutBody>
where Uri: TryFrom<T>, <Uri as TryFrom<T>>::Error: Into<Error>,

Make a TRACE request using this agent.

Trait Implementations§

Source§

impl Clone for Agent

Source§

fn clone(&self) -> Agent

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Agent

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<Config> for Agent

Source§

fn from(value: Config) -> Self

Converts to this type from the input type.

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> ErasedDestructor for T
where T: 'static,