a2a_protocol_client/
tls.rs1use http_body_util::Full;
17use hyper::body::Bytes;
18use hyper_util::client::legacy::connect::HttpConnector;
19use hyper_util::client::legacy::Client;
20use hyper_util::rt::TokioExecutor;
21use rustls::ClientConfig;
22
23pub(crate) type HttpsClient = Client<hyper_rustls::HttpsConnector<HttpConnector>, Full<Bytes>>;
25
26#[must_use]
30pub fn default_tls_config() -> ClientConfig {
31 ClientConfig::builder()
32 .with_root_certificates(root_cert_store())
33 .with_no_client_auth()
34}
35
36#[must_use]
42pub fn tls_config_with_extra_roots(
43 certs: Vec<rustls_pki_types::CertificateDer<'static>>,
44) -> ClientConfig {
45 let mut store = root_cert_store();
46 for cert in certs {
47 if let Err(_err) = store.add(cert) {
48 trace_warn!(error = %_err, "failed to add custom CA certificate to root store");
49 }
50 }
51 ClientConfig::builder()
52 .with_root_certificates(store)
53 .with_no_client_auth()
54}
55
56fn root_cert_store() -> rustls::RootCertStore {
58 let mut store = rustls::RootCertStore::empty();
59 store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
60 store
61}
62
63pub(crate) fn build_https_client() -> HttpsClient {
65 build_https_client_with_config(default_tls_config())
66}
67
68pub(crate) fn build_https_client_with_config(tls_config: ClientConfig) -> HttpsClient {
70 let https = hyper_rustls::HttpsConnectorBuilder::new()
71 .with_tls_config(tls_config)
72 .https_or_http()
73 .enable_all_versions()
74 .build();
75
76 Client::builder(TokioExecutor::new()).build(https)
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn default_tls_config_creates_valid_config() {
85 let _config = default_tls_config();
89 }
90
91 #[test]
92 fn tls_config_with_extra_roots_handles_empty() {
93 let _config = tls_config_with_extra_roots(vec![]);
94 }
95
96 #[test]
97 fn build_https_client_creates_client() {
98 let _client = build_https_client();
99 }
100
101 #[test]
102 fn build_https_client_with_custom_config() {
103 let config = default_tls_config();
104 let _client = build_https_client_with_config(config);
105 }
106}