1#[cfg(any(feature = "native-tls", feature = "rustls"))]
2use {compio::tls::TlsConnector, std::io};
3
4#[derive(Debug, Clone)]
6pub enum TlsBackend {
7 None,
9 #[cfg(feature = "native-tls")]
11 NativeTls,
12 #[cfg(feature = "rustls")]
14 Rustls(std::sync::Arc<compio::tls::rustls::ClientConfig>),
15}
16
17impl Default for TlsBackend {
18 fn default() -> Self {
19 cfg_if::cfg_if! {
20 if #[cfg(feature = "native-tls")] {
21 Self::NativeTls
22 } else if #[cfg(feature = "rustls")] {
23 Self::default_rustls()
24 } else {
25 Self::None
26 }
27 }
28 }
29}
30
31impl TlsBackend {
32 #[cfg(feature = "rustls")]
34 pub fn default_rustls() -> Self {
35 use std::sync::Arc;
36
37 use compio::rustls::ClientConfig;
38 use rustls_platform_verifier::ConfigVerifierExt;
39
40 let mut config = ClientConfig::with_platform_verifier();
41 config.alpn_protocols = if cfg!(feature = "http2") {
42 vec![b"h2".into(), b"http/1.1".into()]
43 } else {
44 vec![b"http/1.1".into()]
45 };
46 config.key_log = Arc::new(compio::rustls::KeyLogFile::new());
47 Self::Rustls(Arc::new(config))
48 }
49
50 #[cfg(any(feature = "native-tls", feature = "rustls"))]
51 pub(crate) fn create_connector(&self) -> io::Result<TlsConnector> {
52 match self {
53 Self::None => Err(io::Error::new(
54 io::ErrorKind::Other,
55 "could not create TLS connector without TLS backend",
56 )),
57 #[cfg(feature = "native-tls")]
58 Self::NativeTls => Ok(TlsConnector::from(
59 compio::tls::native_tls::TlsConnector::builder()
60 .request_alpns(if cfg!(feature = "http2") {
61 &["h2", "http/1.1"]
62 } else {
63 &["http/1.1"]
64 })
65 .build()
66 .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?,
67 )),
68 #[cfg(feature = "rustls")]
69 Self::Rustls(config) => Ok(TlsConnector::from(config.clone())),
70 }
71 }
72}