Skip to main content

lean_ctx/core/
http_client.rs

1use std::time::Duration;
2
3/// Shared TLS config for every ureq client so OS/enterprise root CAs are honored
4/// (#643). ureq's default `RootCerts::WebPki` ignores the system store, so requests
5/// fail with `UnknownIssuer` behind TLS-intercepting corporate proxies. Inject this
6/// into a `ureq::config::Config::builder().tls_config(platform_tls_config())` at each
7/// call site — ureq's builder scope typestate is private, so a shared *builder*
8/// cannot be returned from a function; the shared piece is this `TlsConfig`.
9pub fn platform_tls_config() -> ureq::tls::TlsConfig {
10    ureq::tls::TlsConfig::builder()
11        .root_certs(ureq::tls::RootCerts::PlatformVerifier)
12        .build()
13}
14
15/// Builds a ureq agent from an already-assembled config (kept as a thin, nameable
16/// wrapper so call sites read uniformly alongside `platform_tls_config`).
17pub fn ureq_agent(config: ureq::config::Config) -> ureq::Agent {
18    ureq::Agent::new_with_config(config)
19}
20
21/// Agent that honors platform roots and bounds only the connection-setup phases
22/// (DNS/connect/first-byte) — a large but progressing download stays uncapped.
23pub fn ureq_agent_with_timeouts(
24    timeout_resolve: Option<Duration>,
25    timeout_connect: Option<Duration>,
26    timeout_recv_response: Option<Duration>,
27) -> ureq::Agent {
28    agent_with_redirect_policy(
29        timeout_resolve,
30        timeout_connect,
31        timeout_recv_response,
32        false,
33    )
34}
35
36/// Source credentials and request bodies must stay at the selected endpoint.
37pub(crate) fn ureq_agent_without_redirects(
38    timeout_resolve: Option<Duration>,
39    timeout_connect: Option<Duration>,
40    timeout_recv_response: Option<Duration>,
41) -> ureq::Agent {
42    agent_with_redirect_policy(
43        timeout_resolve,
44        timeout_connect,
45        timeout_recv_response,
46        true,
47    )
48}
49
50fn agent_with_redirect_policy(
51    timeout_resolve: Option<Duration>,
52    timeout_connect: Option<Duration>,
53    timeout_recv_response: Option<Duration>,
54    deny_redirects: bool,
55) -> ureq::Agent {
56    let mut config = ureq::config::Config::builder()
57        .tls_config(platform_tls_config())
58        .timeout_resolve(timeout_resolve)
59        .timeout_connect(timeout_connect)
60        .timeout_recv_response(timeout_recv_response);
61    if deny_redirects {
62        config = config.max_redirects(0);
63    }
64    config.build().into()
65}