use std::sync::Arc;
use hyper::server::conn::AddrIncoming;
use pki_types::{CertificateDer, PrivateKeyDer};
use rustls::ServerConfig;
use super::TlsAcceptor;
pub struct AcceptorBuilder<State>(State);
pub struct WantsTlsConfig(());
impl AcceptorBuilder<WantsTlsConfig> {
pub fn new() -> Self {
Self(WantsTlsConfig(()))
}
pub fn with_tls_config(self, config: ServerConfig) -> AcceptorBuilder<WantsAlpn> {
AcceptorBuilder(WantsAlpn(config))
}
pub fn with_single_cert(
self,
cert_chain: Vec<CertificateDer<'static>>,
key_der: PrivateKeyDer<'static>,
) -> Result<AcceptorBuilder<WantsAlpn>, rustls::Error> {
Ok(AcceptorBuilder(WantsAlpn(
ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(cert_chain, key_der)?,
)))
}
}
impl Default for AcceptorBuilder<WantsTlsConfig> {
fn default() -> Self {
Self::new()
}
}
pub struct WantsAlpn(ServerConfig);
impl AcceptorBuilder<WantsAlpn> {
pub fn with_alpn_protocols(
mut self,
alpn_protocols: Vec<Vec<u8>>,
) -> AcceptorBuilder<WantsIncoming> {
self.0 .0.alpn_protocols = alpn_protocols;
AcceptorBuilder(WantsIncoming(self.0 .0))
}
pub fn with_http2_alpn(mut self) -> AcceptorBuilder<WantsIncoming> {
self.0 .0.alpn_protocols = vec![b"h2".to_vec()];
AcceptorBuilder(WantsIncoming(self.0 .0))
}
pub fn with_http10_alpn(mut self) -> AcceptorBuilder<WantsIncoming> {
self.0 .0.alpn_protocols = vec![b"http/1.0".to_vec()];
AcceptorBuilder(WantsIncoming(self.0 .0))
}
pub fn with_http11_alpn(mut self) -> AcceptorBuilder<WantsIncoming> {
self.0 .0.alpn_protocols = vec![b"http/1.1".to_vec()];
AcceptorBuilder(WantsIncoming(self.0 .0))
}
pub fn with_all_versions_alpn(mut self) -> AcceptorBuilder<WantsIncoming> {
self.0 .0.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec(), b"http/1.0".to_vec()];
AcceptorBuilder(WantsIncoming(self.0 .0))
}
}
pub struct WantsIncoming(ServerConfig);
impl AcceptorBuilder<WantsIncoming> {
pub fn with_incoming(self, incoming: impl Into<AddrIncoming>) -> TlsAcceptor {
self.with_acceptor(incoming.into())
}
pub fn with_acceptor<A>(self, acceptor: A) -> TlsAcceptor<A> {
TlsAcceptor {
config: Arc::new(self.0 .0),
acceptor,
}
}
}