use std::collections::HashSet;
use serde::{Serialize, Deserialize};
#[cfg(feature = "http")]
use reqwest::header::HeaderMap;
#[expect(unused_imports, reason = "Used in docs.")]
use crate::types::*;
use crate::glue::*;
use crate::util::*;
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Suitability)]
#[serde(deny_unknown_fields)]
pub struct HttpClientConfig {
#[serde(default, skip_serializing_if = "is_default", with = "serde_headermap")]
pub default_headers: HeaderMap,
#[serde(default, skip_serializing_if = "is_default")]
pub redirect_policy: RedirectPolicy,
#[serde(default, skip_serializing_if = "is_default")]
pub https_only: bool,
#[serde(default, skip_serializing_if = "is_default")]
pub referer: bool,
#[serde(default, skip_serializing_if = "is_default")]
pub proxies: Vec<ProxyConfig>,
#[serde(default, skip_serializing_if = "is_default")]
pub no_proxy: bool,
#[serde(default, skip_serializing_if = "is_default")]
pub extra_root_certificates: HashSet<String>
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Suitability)]
#[serde(deny_unknown_fields)]
pub enum RedirectPolicy {
Limited(usize),
None
}
impl Default for RedirectPolicy {
fn default() -> Self {
Self::Limited(10)
}
}
impl From<RedirectPolicy> for reqwest::redirect::Policy {
fn from(value: RedirectPolicy) -> Self {
match value {
RedirectPolicy::Limited(x) => Self::limited(x),
RedirectPolicy::None => Self::none()
}
}
}
impl HttpClientConfig {
pub fn make(&self) -> reqwest::Result<reqwest::blocking::Client> {
let mut temp = reqwest::blocking::Client::builder().default_headers(self.default_headers.clone())
.redirect(self.redirect_policy.clone().into())
.https_only(self.https_only)
.referer(self.referer);
for proxy in &self.proxies {
temp = temp.proxy(proxy.clone().make()?);
}
if self.no_proxy {temp = temp.no_proxy();}
for cert in &self.extra_root_certificates {
temp = temp.add_root_certificate(reqwest::tls::Certificate::from_pem(cert.as_bytes())?);
}
temp.build()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize, Suitability)]
#[serde(deny_unknown_fields)]
pub struct HttpClientConfigDiff {
#[serde(default, skip_serializing_if = "is_default")]
pub redirect_policy: Option<RedirectPolicy>,
#[serde(default, skip_serializing_if = "is_default", with = "serde_headermap")]
pub add_default_headers: HeaderMap,
#[serde(default, skip_serializing_if = "is_default")]
pub https_only: Option<bool>,
#[serde(default, skip_serializing_if = "is_default")]
pub set_proxies: Option<Vec<ProxyConfig>>,
#[serde(default, skip_serializing_if = "is_default")]
pub add_proxies: Vec<ProxyConfig>,
#[serde(default, skip_serializing_if = "is_default")]
pub no_proxy: Option<bool>,
#[serde(default, skip_serializing_if = "is_default")]
pub referer: Option<bool>,
#[serde(default, skip_serializing_if = "is_default")]
pub add_extra_root_certificates: HashSet<String>,
#[serde(default, skip_serializing_if = "is_default")]
pub remove_extra_root_certificates: HashSet<String>
}
impl HttpClientConfigDiff {
pub fn apply_once(self, to: &mut HttpClientConfig) {
debug!(HttpClientConfigDiff::apply_once, &self, to);
if let Some(new_redirect_policy) = self.redirect_policy {to.redirect_policy = new_redirect_policy;}
to.default_headers.extend(self.add_default_headers);
if let Some(https_only) = self.https_only {to.https_only = https_only;}
if let Some(set_proxies) = self.set_proxies {to.proxies = set_proxies;}
to.proxies.extend(self.add_proxies);
if let Some(no_proxy) = self.no_proxy {to.no_proxy = no_proxy;}
if let Some(referer) = self.referer {to.no_proxy = referer;}
to.extra_root_certificates.extend(self.add_extra_root_certificates);
to.extra_root_certificates.retain(|extra_root_certificate| !self.remove_extra_root_certificates.contains(extra_root_certificate));
}
pub fn apply_multiple(&self, to: &mut HttpClientConfig) {
debug!(HttpClientConfigDiff::apply_multiple, self, to);
if let Some(new_redirect_policy) = &self.redirect_policy {to.redirect_policy = new_redirect_policy.clone();}
to.default_headers.extend(self.add_default_headers.clone());
if let Some(https_only) = self.https_only {to.https_only = https_only;}
if let Some(set_proxies) = &self.set_proxies {to.proxies.clone_from(set_proxies);}
to.proxies.extend(self.add_proxies.clone());
if let Some(no_proxy) = self.no_proxy {to.no_proxy = no_proxy;}
if let Some(referer) = self.referer {to.no_proxy = referer;}
to.extra_root_certificates.extend(self.add_extra_root_certificates.clone());
to.extra_root_certificates.retain(|extra_root_certificate| !self.remove_extra_root_certificates.contains(extra_root_certificate));
}
}