Skip to main content

zagens_runtime_adapters/
http_client.rs

1//! Shared HTTP client builder helpers (proxy from environment).
2
3use std::env;
4
5use anyhow::{Context, Result};
6use reqwest::{Client, ClientBuilder, NoProxy, Proxy};
7
8/// Apply `HTTP(S)_PROXY` and `NO_PROXY` from the environment to a reqwest builder.
9///
10/// Workspace `reqwest` is built with `default-features = false`, so system proxy
11/// is not inherited unless we configure it explicitly.
12pub fn apply_env_proxy(mut builder: ClientBuilder) -> ClientBuilder {
13    let proxy_url = env::var("HTTPS_PROXY")
14        .or_else(|_| env::var("https_proxy"))
15        .or_else(|_| env::var("HTTP_PROXY"))
16        .or_else(|_| env::var("http_proxy"))
17        .ok()
18        .filter(|s| !s.trim().is_empty());
19
20    let Some(proxy_url) = proxy_url else {
21        return builder;
22    };
23
24    if let Ok(mut proxy) = Proxy::all(&proxy_url) {
25        if let Some(no_proxy) = NoProxy::from_env() {
26            proxy = proxy.no_proxy(Some(no_proxy));
27        }
28        builder = builder.proxy(proxy);
29    }
30    builder
31}
32
33/// Build a reqwest client with environment proxy settings applied.
34pub fn build_http_client() -> Result<Client> {
35    apply_env_proxy(Client::builder())
36        .build()
37        .context("failed to build HTTP client")
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn apply_env_proxy_does_not_panic_without_env() {
46        let _ = apply_env_proxy(Client::builder());
47    }
48}