hyper_rustls/acceptor/
builder.rs

1use std::sync::Arc;
2
3use hyper::server::conn::AddrIncoming;
4use rustls::ServerConfig;
5
6use super::TlsAcceptor;
7/// Builder for [`TlsAcceptor`]
8pub struct AcceptorBuilder<State>(State);
9
10/// State of a builder that needs a TLS client config next
11pub struct WantsTlsConfig(());
12
13impl AcceptorBuilder<WantsTlsConfig> {
14    /// Creates a new [`AcceptorBuilder`]
15    pub fn new() -> Self {
16        Self(WantsTlsConfig(()))
17    }
18
19    /// Passes a rustls [`ServerConfig`] to configure the TLS connection
20    pub fn with_tls_config(self, config: ServerConfig) -> AcceptorBuilder<WantsAlpn> {
21        AcceptorBuilder(WantsAlpn(config))
22    }
23
24    /// Use rustls [defaults][with_safe_defaults] without [client authentication][with_no_client_auth]
25    ///
26    /// [with_safe_defaults]: rustls::ConfigBuilder::with_safe_defaults
27    /// [with_no_client_auth]: rustls::ConfigBuilder::with_no_client_auth
28    pub fn with_single_cert(
29        self,
30        cert_chain: Vec<rustls::Certificate>,
31        key_der: rustls::PrivateKey,
32    ) -> Result<AcceptorBuilder<WantsAlpn>, rustls::Error> {
33        Ok(AcceptorBuilder(WantsAlpn(
34            ServerConfig::builder()
35                .with_safe_defaults()
36                .with_no_client_auth()
37                .with_single_cert(cert_chain, key_der)?,
38        )))
39    }
40}
41
42impl Default for AcceptorBuilder<WantsTlsConfig> {
43    fn default() -> Self {
44        Self::new()
45    }
46}
47
48/// State of a builder that needs a incoming address next
49pub struct WantsAlpn(ServerConfig);
50
51impl AcceptorBuilder<WantsAlpn> {
52    /// Configure ALPN accept protocols in order
53    pub fn with_alpn_protocols(
54        mut self,
55        alpn_protocols: Vec<Vec<u8>>,
56    ) -> AcceptorBuilder<WantsIncoming> {
57        self.0 .0.alpn_protocols = alpn_protocols;
58        AcceptorBuilder(WantsIncoming(self.0 .0))
59    }
60
61    /// Configure ALPN to accept HTTP/2
62    pub fn with_http2_alpn(mut self) -> AcceptorBuilder<WantsIncoming> {
63        self.0 .0.alpn_protocols = vec![b"h2".to_vec()];
64        AcceptorBuilder(WantsIncoming(self.0 .0))
65    }
66
67    /// Configure ALPN to accept HTTP/1.0
68    pub fn with_http10_alpn(mut self) -> AcceptorBuilder<WantsIncoming> {
69        self.0 .0.alpn_protocols = vec![b"http/1.0".to_vec()];
70        AcceptorBuilder(WantsIncoming(self.0 .0))
71    }
72
73    /// Configure ALPN to accept HTTP/1.1
74    pub fn with_http11_alpn(mut self) -> AcceptorBuilder<WantsIncoming> {
75        self.0 .0.alpn_protocols = vec![b"http/1.1".to_vec()];
76        AcceptorBuilder(WantsIncoming(self.0 .0))
77    }
78
79    /// Configure ALPN to accept HTTP/2, HTTP/1.1, HTTP/1.0 in that order.
80    pub fn with_all_versions_alpn(mut self) -> AcceptorBuilder<WantsIncoming> {
81        self.0 .0.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()];
82        AcceptorBuilder(WantsIncoming(self.0 .0))
83    }
84}
85
86/// State of a builder that needs a incoming address next
87pub struct WantsIncoming(ServerConfig);
88
89impl AcceptorBuilder<WantsIncoming> {
90    /// Passes a [`AddrIncoming`] to configure the TLS connection and
91    /// creates the [`TlsAcceptor`]
92    pub fn with_incoming(self, incoming: impl Into<AddrIncoming>) -> TlsAcceptor {
93        self.with_acceptor(incoming.into())
94    }
95
96    /// Passes an acceptor implementing [`Accept`] to configure the TLS connection and
97    /// creates the [`TlsAcceptor`]
98    ///
99    /// [`Accept`]: hyper::server::accept::Accept
100    pub fn with_acceptor<A>(self, acceptor: A) -> TlsAcceptor<A> {
101        TlsAcceptor {
102            config: Arc::new(self.0 .0),
103            acceptor,
104        }
105    }
106}