use std::sync::{Arc, Once};
use torsh_core::error::{Result, TorshError};
fn install_default_provider() {
static ONCE: Once = Once::new();
ONCE.call_once(|| {
let _ = oxitls_rustcrypto_provider::provider().install_default();
});
}
fn rustls_config() -> Result<rustls::ClientConfig> {
let mut roots = rustls::RootCertStore::empty();
roots.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());
let mut config = rustls::ClientConfig::builder_with_provider(Arc::new(
oxitls_rustcrypto_provider::provider(),
))
.with_safe_default_protocol_versions()
.map_err(|e| TorshError::Other(format!("failed to configure rustls TLS: {e}")))?
.with_root_certificates(roots)
.with_no_client_auth();
config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
Ok(config)
}
pub(crate) fn blocking_client_builder() -> Result<reqwest::blocking::ClientBuilder> {
install_default_provider();
Ok(reqwest::blocking::Client::builder().use_preconfigured_tls(rustls_config()?))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rustls_config_builds_with_webpki_roots() {
let config = rustls_config().expect("pure-Rust TLS config must build");
assert!(config.alpn_protocols.contains(&b"h2".to_vec()));
assert!(config.alpn_protocols.contains(&b"http/1.1".to_vec()));
}
#[test]
fn blocking_client_builder_builds_a_client() {
let client = blocking_client_builder()
.expect("builder")
.build()
.expect("blocking client must build with the pure-Rust TLS stack");
drop(client);
}
}