agnt_tools/http.rs
1//! Deprecated shared HTTP client.
2//!
3//! v0.3.1 moved `Fetch` to a per-instance `ureq::Agent` with a custom
4//! [`crate::ssrf::SsrfResolver`] so DNS resolution and SSRF validation
5//! happen atomically — closing the v0.2/v0.3 TOCTOU window where the
6//! pre-request `ssrf_check` and ureq's internal lookup could see
7//! different addresses (DNS rebinding).
8//!
9//! The process-wide shared agent that used to live here had no way to
10//! carry a per-`Fetch` allowlist, so keeping it as the `Fetch` backend
11//! blocked the security fix. The shim is preserved *only* so external
12//! crates that called `agnt_tools::http::agent()` directly keep
13//! compiling; it is now marked `#[deprecated]` and will be removed in
14//! v0.4.
15//!
16//! **Do not use this for new code.** It has no SSRF guard — build your
17//! own `ureq::Agent` (with an `SsrfResolver` if the URL is attacker-
18//! influenced) or use [`crate::Fetch`] directly.
19
20use std::sync::{Arc, OnceLock};
21
22static AGENT: OnceLock<ureq::Agent> = OnceLock::new();
23
24/// Deprecated: returns a shared ureq Agent with `redirects(0)` and the
25/// system TLS store, but *without* the SSRF resolver. Use
26/// [`crate::Fetch`] for any attacker-influenced URL.
27#[deprecated(
28 since = "0.3.1",
29 note = "use agnt_tools::Fetch directly; this shim has no SSRF guard and will be removed in v0.4"
30)]
31pub fn agent() -> &'static ureq::Agent {
32 AGENT.get_or_init(|| {
33 match native_tls::TlsConnector::new() {
34 Ok(connector) => ureq::AgentBuilder::new()
35 .tls_connector(Arc::new(connector))
36 .redirects(0)
37 .build(),
38 Err(_) => ureq::AgentBuilder::new().redirects(0).build(),
39 }
40 })
41}