mz_ccsr/
config.rs
1use std::collections::BTreeMap;
11use std::fmt;
12use std::net::SocketAddr;
13use std::sync::Arc;
14use std::time::Duration;
15
16use serde::{Deserialize, Serialize};
17use url::Url;
18
19use crate::client::Client;
20use crate::tls::{Certificate, Identity};
21
22#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
23pub struct Auth {
24 pub username: String,
25 pub password: Option<String>,
26}
27
28#[derive(Clone)]
30pub struct ClientConfig {
31 url: Arc<dyn Fn() -> Url + Send + Sync + 'static>,
32 root_certs: Vec<Certificate>,
33 identity: Option<Identity>,
34 auth: Option<Auth>,
35 dns_overrides: BTreeMap<String, Vec<SocketAddr>>,
36}
37
38impl fmt::Debug for ClientConfig {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 f.debug_struct("ClientConfig")
41 .field("url", &"...")
42 .field("root_certs", &self.root_certs)
43 .field("identity", &self.identity)
44 .field("auth", &self.auth)
45 .field("dns_overrides", &self.dns_overrides)
46 .finish()
47 }
48}
49
50impl ClientConfig {
51 pub fn new(url: Url) -> ClientConfig {
54 ClientConfig {
55 url: Arc::new(move || url.clone()),
56 root_certs: Vec::new(),
57 identity: None,
58 auth: None,
59 dns_overrides: BTreeMap::new(),
60 }
61 }
62
63 pub fn add_root_certificate(mut self, cert: Certificate) -> ClientConfig {
67 self.root_certs.push(cert);
68 self
69 }
70
71 pub fn identity(mut self, identity: Identity) -> ClientConfig {
73 self.identity = Some(identity);
74 self
75 }
76
77 pub fn auth(mut self, username: String, password: Option<String>) -> ClientConfig {
80 self.auth = Some(Auth { username, password });
81 self
82 }
83
84 pub fn resolve_to_addrs(mut self, domain: &str, addrs: &[SocketAddr]) -> ClientConfig {
89 self.dns_overrides.insert(domain.into(), addrs.into());
90 self
91 }
92
93 pub fn dynamic_url<F: Fn() -> Url + Send + Sync + 'static>(
98 mut self,
99 callback: F,
100 ) -> ClientConfig {
101 self.url = Arc::new(callback);
102 self
103 }
104
105 pub fn build(self) -> Result<Client, anyhow::Error> {
107 let mut builder = reqwest::ClientBuilder::new();
108
109 for root_cert in self.root_certs {
110 builder = builder.add_root_certificate(root_cert.into());
111 }
112
113 if let Some(ident) = self.identity {
114 builder = builder.identity(ident.into());
115 }
116
117 for (domain, addrs) in self.dns_overrides {
118 builder = builder.resolve_to_addrs(&domain, &addrs);
119 }
120
121 let timeout = Duration::from_secs(60);
123
124 let inner = builder
125 .redirect(reqwest::redirect::Policy::none())
126 .timeout(timeout)
127 .build()
128 .unwrap();
129
130 Client::new(inner, self.url, self.auth, timeout)
131 }
132}