tide_rustls/custom_tls_acceptor.rs
1use async_rustls::server::TlsStream;
2use async_std::net::TcpStream;
3
4/// The CustomTlsAcceptor trait provides a custom implementation of accepting
5/// TLS connections from a [`TcpStream`]. tide-rustls will call the
6/// [`CustomTlsAcceptor::accept`] function for each new [`TcpStream`] it
7/// accepts, to obtain a [`TlsStream`]).
8///
9/// Implementing this trait gives you control over the TLS negotiation process,
10/// and allows you to process some TLS connections internally without passing
11/// them through to tide, such as for multiplexing or custom ALPN negotiation.
12#[tide::utils::async_trait]
13pub trait CustomTlsAcceptor: Send + Sync {
14 /// Accept a [`TlsStream`] from a [`TcpStream`].
15 ///
16 /// If TLS negotiation succeeds, but does not result in a stream that tide
17 /// should process HTTP connections from, return `Ok(None)`.
18 async fn accept(&self, stream: TcpStream) -> std::io::Result<Option<TlsStream<TcpStream>>>;
19}
20
21/// Crate-private adapter to make `async_rustls::TlsAcceptor` implement
22/// `CustomTlsAcceptor`, without creating a conflict between the two `accept`
23/// methods.
24pub(crate) struct StandardTlsAcceptor(pub(crate) async_rustls::TlsAcceptor);
25
26#[tide::utils::async_trait]
27impl CustomTlsAcceptor for StandardTlsAcceptor {
28 async fn accept(&self, stream: TcpStream) -> std::io::Result<Option<TlsStream<TcpStream>>> {
29 self.0.accept(stream).await.map(Some)
30 }
31}