1use std::time::Duration;
11
12use defect_config::{HttpClientConfig, HttpProxyMode, HttpProxySettings};
13
14pub fn build_http_stack_config(
21 config: &HttpClientConfig,
22) -> anyhow::Result<defect_http::HttpStackConfig> {
23 let mut stack = defect_http::HttpStackConfig::default();
24 if let Some(ms) = config.total_timeout_ms {
25 stack.total_timeout = if ms == 0 {
26 None
27 } else {
28 Some(Duration::from_millis(ms))
29 };
30 }
31 if let Some(retries) = config.transport_retries {
32 stack.transport_retries = retries;
33 }
34 if let Some(ms) = config.initial_backoff_ms {
35 stack.initial_backoff = Duration::from_millis(ms);
36 }
37 if let Some(ua) = &config.user_agent {
38 stack.user_agent = Some(ua.clone());
39 }
40 stack.proxy = match config.proxy.mode {
41 HttpProxyMode::FromEnv => defect_http::ProxyConfig::FromEnv,
42 HttpProxyMode::Disabled => defect_http::ProxyConfig::Disabled,
43 HttpProxyMode::Explicit => {
44 defect_http::ProxyConfig::Explicit(parse_proxy_settings(&config.proxy.explicit)?)
45 }
46 };
47 Ok(stack)
48}
49
50fn parse_proxy_settings(
51 settings: &HttpProxySettings,
52) -> anyhow::Result<defect_http::ProxySettings> {
53 let parse_uri = |raw: &str, field: &str| -> anyhow::Result<http::Uri> {
54 raw.parse::<http::Uri>()
55 .map_err(|e| anyhow::anyhow!("invalid http.proxy.{field} `{raw}`: {e}"))
56 };
57 Ok(defect_http::ProxySettings {
58 http_proxy: settings
59 .http_proxy
60 .as_deref()
61 .map(|raw| parse_uri(raw, "http_proxy"))
62 .transpose()?,
63 https_proxy: settings
64 .https_proxy
65 .as_deref()
66 .map(|raw| parse_uri(raw, "https_proxy"))
67 .transpose()?,
68 no_proxy: settings.no_proxy.clone(),
69 })
70}