Skip to content

Commit

Permalink
ConfigBuilder and friends
Browse files Browse the repository at this point in the history
  • Loading branch information
algesten committed Oct 12, 2024
1 parent cc9aed9 commit 77f9087
Show file tree
Hide file tree
Showing 18 changed files with 510 additions and 360 deletions.
47 changes: 27 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,12 @@ holds a connection pool for reuse, and a cookie store if you use the
an Agent also allows setting options like the TLS configuration.

```rust
use ureq::{Agent, Config, Timeouts};
use ureq::Agent;
use std::time::Duration;

let mut config = Config::new();
config.timeouts.global = Some(Duration::from_secs(5));
let mut config = Agent::config_builder()
.timeout_global(Some(Duration::from_secs(5)))
.build();

let agent: Agent = config.into();

Expand Down Expand Up @@ -122,7 +123,8 @@ ureq returns errors via `Result<T, ureq::Error>`. That includes I/O errors,
protocol errors. By default, also HTTP status code errors (when the
server responded 4xx or 5xx) results in `Error`.

This behavior can be turned off via [`Config::http_status_as_error`].
This behavior can be turned off via
[`http_status_as_error()`][crate::config::ConfigBuilder::http_status_as_error].

```rust
use ureq::Error;
Expand Down Expand Up @@ -184,11 +186,17 @@ up as a default or used by the crate level convenience calls (`ureq::get` etc)
must be configured on the agent.

```rust
use ureq::{Config, tls::TlsProvider};

let mut config = Config::new();
// requires the native-tls feature
config.tls_config.provider = TlsProvider::NativeTls;
use ureq::config::Config;
use ureq::tls::{TlsConfig, TlsProvider};

let mut config = Config::builder()
.tls_config(
TlsConfig::builder()
// requires the native-tls feature
.provider(TlsProvider::NativeTls)
.build()
)
.build();

let agent = config.new_agent();

Expand Down Expand Up @@ -318,13 +326,13 @@ Proxies settings are configured on an [Agent]. All request sent through the agen
### Example using HTTP

```rust
use ureq::{Agent, Config, Proxy};
use ureq::{Agent, Proxy};
// Configure an http connect proxy.
let proxy = Proxy::new("http://user:password@cool.proxy:9090")?;
let agent: Agent = Config {
proxy: Some(proxy),
..Default::default()
}.into();
let agent: Agent = Agent::config_builder()
.proxy(Some(proxy))
.build()
.into();

// This is proxied.
let resp = agent.get("http://cool.server").call()?;
Expand All @@ -333,15 +341,14 @@ let resp = agent.get("http://cool.server").call()?;
### Example using SOCKS5

```rust
use ureq::{Agent, Config, Proxy};
use ureq::{Agent, Proxy};
// Configure a SOCKS proxy.
let proxy = Proxy::new("socks5://user:password@cool.proxy:9090")?;
let agent: Agent = Config {
proxy: Some(proxy),
..Default::default()
}.into();
let agent: Agent = Agent::config_builder()
.proxy(Some(proxy))
.build()
.into();

// This is proxied.
let resp = agent.get("http://cool.server").call()?;
```

23 changes: 10 additions & 13 deletions examples/cureq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::time::Duration;

use auto_args::AutoArgs;
use ureq::tls::TlsConfig;
use ureq::{Agent, Config, Timeouts};
use ureq::Agent;

#[derive(Debug, AutoArgs)]
struct Opt {
Expand All @@ -31,18 +31,15 @@ fn main() {
}

fn run(opt: &Opt) -> Result<(), ureq::Error> {
let agent: Agent = Config {
timeouts: Timeouts {
global: opt.max_time.map(|t| Duration::from_secs(t.into())),
..Default::default()
},
tls_config: TlsConfig {
disable_verification: opt.insecure.unwrap_or(false),
..Default::default()
},
..Default::default()
}
.into();
let agent: Agent = Agent::config_builder()
.timeout_global(opt.max_time.map(|t| Duration::from_secs(t.into())))
.tls_config(
TlsConfig::builder()
.disable_verification(opt.insecure.unwrap_or(false))
.build(),
)
.build()
.into();

let mut res = agent.get(&opt.url).call()?;

Expand Down
22 changes: 13 additions & 9 deletions src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ use std::sync::Arc;
use http::{Method, Request, Response, Uri};

use crate::body::Body;
use crate::config::RequestLevelConfig;
use crate::config::{AgentScope, Config, ConfigBuilder, HttpCrateScope, RequestLevelConfig};
use crate::middleware::MiddlewareNext;
use crate::pool::ConnectionPool;
use crate::resolver::{DefaultResolver, Resolver};
use crate::send_body::AsSendBody;
use crate::transport::{Connector, DefaultConnector};
use crate::{Config, Error, RequestBuilder, SendBody};
use crate::{Error, RequestBuilder, SendBody};
use crate::{WithBody, WithoutBody};

/// Agents keep state between requests.
Expand Down Expand Up @@ -110,6 +110,13 @@ impl Agent {
)
}

/// Shortcut to reach a [`ConfigBuilder`]
///
/// This is the same as doing [`Config::builder()`].
pub fn config_builder() -> ConfigBuilder<AgentScope> {
Config::builder()
}

/// Creates an agent with a bespoke transport and resolver.
///
/// _This is low level API that isn't for regular use of ureq._
Expand Down Expand Up @@ -201,20 +208,17 @@ impl Agent {
/// library does not currently detect this situation, but it is
/// not considered a breaking change if this is enforced in
/// the future.
pub fn configure_request<'a>(
pub fn configure_request<S: AsSendBody>(
&self,
request: &'a mut Request<impl AsSendBody + 'static>,
) -> &'a mut Config {
mut request: Request<S>,
) -> ConfigBuilder<HttpCrateScope<S>> {
let exts = request.extensions_mut();

if exts.get::<RequestLevelConfig>().is_none() {
exts.insert(self.new_request_level_config());
}

// Unwrap is OK because of above check
let req_level: &mut RequestLevelConfig = exts.get_mut().unwrap();

&mut req_level.0
ConfigBuilder(HttpCrateScope(request))
}

pub(crate) fn new_request_level_config(&self) -> RequestLevelConfig {
Expand Down
8 changes: 2 additions & 6 deletions src/body/charset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,10 @@ mod test {
#[cfg(feature = "charset")]
fn non_ascii_reason() {
use crate::test::init_test_log;
use crate::{Agent, Config};
use crate::Agent;

init_test_log();
let agent: Agent = Config {
max_redirects: 0,
..Default::default()
}
.into();
let agent: Agent = Agent::config_builder().max_redirects(0).build().into();

let res = agent
.get("https://my.test/non-ascii-reason")
Expand Down
Loading

0 comments on commit 77f9087

Please sign in to comment.