chateau/
lib.rs

1//! Client and server primitives for tower-style services.
2
3use std::{fmt, pin::Pin};
4
5pub mod info;
6mod notify;
7pub mod rt;
8pub mod server;
9pub mod services;
10pub mod stream;
11
12type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
13type BoxError = Box<dyn std::error::Error + Send + Sync>;
14
15/// Utility struct for formatting a `Display` type in a `Debug` context.
16#[allow(unused)]
17pub(crate) struct DebugLiteral<T: fmt::Display>(T);
18
19impl<T: fmt::Display> fmt::Debug for DebugLiteral<T> {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        write!(f, "{}", self.0)
22    }
23}
24
25/// Utility function for attaching a `follows_from` relationship to the current span
26/// in a polling context.
27#[allow(unused)]
28#[track_caller]
29pub(crate) fn polled_span(span: &tracing::Span) {
30    tracing::dispatcher::get_default(|dispatch| {
31        let id = span.id().expect("Missing ID; this is a bug");
32        if let Some(current) = dispatch.current_span().id() {
33            dispatch.record_follows_from(&id, current)
34        }
35    });
36}
37
38pub(crate) mod private {
39
40    #[allow(unused)]
41    pub trait Sealed<T> {}
42}
43
44/// Test fixtures for the `hyperdriver` crate.
45#[cfg(test)]
46#[allow(dead_code)]
47pub(crate) mod fixtures {
48
49    use std::sync::Once;
50
51    use rustls::ServerConfig;
52
53    /// Registers a global default tracing subscriber when called for the first time. This is intended
54    /// for use in tests.
55    pub fn subscribe() {
56        static INSTALL_TRACING_SUBSCRIBER: Once = Once::new();
57        INSTALL_TRACING_SUBSCRIBER.call_once(|| {
58            let subscriber = tracing_subscriber::FmtSubscriber::builder()
59                .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
60                .with_test_writer()
61                .finish();
62            tracing::subscriber::set_global_default(subscriber).unwrap();
63        });
64    }
65
66    #[cfg(feature = "tls")]
67    pub(crate) fn tls_server_config() -> rustls::ServerConfig {
68        let (_, cert) = pem_rfc7468::decode_vec(include_bytes!(concat!(
69            env!("CARGO_MANIFEST_DIR"),
70            "/tests/minica/example.com/cert.pem"
71        )))
72        .unwrap();
73        let (label, key) = pem_rfc7468::decode_vec(include_bytes!(concat!(
74            env!("CARGO_MANIFEST_DIR"),
75            "/tests/minica/example.com/key.pem"
76        )))
77        .unwrap();
78
79        let cert = rustls::pki_types::CertificateDer::from(cert);
80        let key = match label {
81            "PRIVATE KEY" => rustls::pki_types::PrivateKeyDer::Pkcs8(key.into()),
82            "RSA PRIVATE KEY" => rustls::pki_types::PrivateKeyDer::Pkcs1(key.into()),
83            "EC PRIVATE KEY" => rustls::pki_types::PrivateKeyDer::Sec1(key.into()),
84            _ => panic!("unknown key type"),
85        };
86
87        let mut cfg = ServerConfig::builder()
88            .with_no_client_auth()
89            .with_single_cert(vec![cert], key)
90            .unwrap();
91
92        cfg.alpn_protocols.push(b"h2".to_vec());
93        cfg.alpn_protocols.push(b"http/1.1".to_vec());
94
95        cfg
96    }
97
98    #[cfg(feature = "tls")]
99    fn tls_root_store() -> rustls::RootCertStore {
100        let mut root_store = rustls::RootCertStore::empty();
101        let (_, cert) = pem_rfc7468::decode_vec(include_bytes!(concat!(
102            env!("CARGO_MANIFEST_DIR"),
103            "/tests/minica/minica.pem"
104        )))
105        .unwrap();
106        root_store
107            .add(rustls::pki_types::CertificateDer::from(cert))
108            .unwrap();
109        root_store
110    }
111
112    #[cfg(feature = "tls")]
113    pub(crate) fn tls_client_config() -> rustls::ClientConfig {
114        let mut config = rustls::ClientConfig::builder()
115            .with_root_certificates(tls_root_store())
116            .with_no_client_auth();
117        config.alpn_protocols.push(b"h2".to_vec());
118        config.alpn_protocols.push(b"http/1.1".to_vec());
119        config
120    }
121
122    #[cfg(feature = "tls")]
123    pub(crate) fn tls_install_default() {
124        #[cfg(feature = "tls-ring")]
125        {
126            let _ = rustls::crypto::ring::default_provider().install_default();
127        }
128
129        #[cfg(all(feature = "tls-aws-lc", not(feature = "tls-ring")))]
130        {
131            let _ = rustls::crypto::aws_lc_rs::default_provider().install_default();
132        }
133
134        #[cfg(not(any(feature = "tls-aws-lc", feature = "tls-ring")))]
135        {
136            panic!("No TLS backend enabled, please enable one of `tls-ring` or `tls-aws-lc`");
137        }
138    }
139}