use crate::config::Config;
use crate::llm::provider::LLMError;
use reqwest::{Client, NoProxy, Proxy};
pub fn build_proxy(config: &Config) -> Result<Option<Proxy>, LLMError> {
let http_proxy = config.http_proxy.trim();
let https_proxy = config.https_proxy.trim();
let proxy_url = if !http_proxy.is_empty() {
http_proxy
} else if !https_proxy.is_empty() {
https_proxy
} else {
return Ok(None);
};
let mut proxy = Proxy::all(proxy_url)?;
if let Some(auth) = config.proxy_auth.as_ref() {
proxy = proxy.basic_auth(&auth.username, &auth.password);
}
proxy = proxy.no_proxy(NoProxy::from_string("localhost,127.0.0.1,::1"));
Ok(Some(proxy))
}
pub fn build_http_client(config: &Config) -> Result<Client, LLMError> {
let mut builder = Client::builder();
if let Some(proxy) = build_proxy(config)? {
builder = builder.proxy(proxy);
}
Ok(builder.build()?)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn proxy_attaches_no_proxy_loopback_list() {
let mut cfg = Config::default();
cfg.http_proxy = "http://proxy.example.com:8080".to_string();
let proxy = build_proxy(&cfg).unwrap().expect("proxy");
let dbg = format!("{proxy:?}");
assert!(dbg.contains("localhost"));
assert!(dbg.contains("127.0.0.1"));
assert!(dbg.contains("::1"));
}
}