@@ -3,11 +3,12 @@ use async_std::net::TcpListener;
33
44use rustls:: ServerConfig ;
55
6- use super :: { TcpConnection , TlsListener , TlsListenerConfig } ;
6+ use super :: { CustomTlsAcceptor , TcpConnection , TlsListener , TlsListenerConfig } ;
77
88use std:: marker:: PhantomData ;
99use std:: net:: { SocketAddr , ToSocketAddrs } ;
1010use std:: path:: { Path , PathBuf } ;
11+ use std:: sync:: Arc ;
1112
1213/// # A builder for TlsListeners
1314///
@@ -38,6 +39,7 @@ pub struct TlsListenerBuilder<State> {
3839 key : Option < PathBuf > ,
3940 cert : Option < PathBuf > ,
4041 config : Option < ServerConfig > ,
42+ tls_acceptor : Option < Arc < dyn CustomTlsAcceptor > > ,
4143 tcp : Option < TcpListener > ,
4244 addrs : Option < Vec < SocketAddr > > ,
4345 _state : PhantomData < State > ,
@@ -49,6 +51,7 @@ impl<State> Default for TlsListenerBuilder<State> {
4951 key : None ,
5052 cert : None ,
5153 config : None ,
54+ tls_acceptor : None ,
5255 tcp : None ,
5356 addrs : None ,
5457 _state : PhantomData ,
@@ -69,6 +72,14 @@ impl<State> std::fmt::Debug for TlsListenerBuilder<State> {
6972 "None"
7073 } ,
7174 )
75+ . field (
76+ "tls_acceptor" ,
77+ & if self . tls_acceptor . is_some ( ) {
78+ "Some(_)"
79+ } else {
80+ "None"
81+ } ,
82+ )
7283 . field ( "tcp" , & self . tcp )
7384 . field ( "addrs" , & self . addrs )
7485 . finish ( )
@@ -108,6 +119,17 @@ impl<State> TlsListenerBuilder<State> {
108119 self
109120 }
110121
122+ /// Provides a custom acceptor for TLS connections. This is mutually
123+ /// exclusive with any of [`TlsListenerBuilder::key`],
124+ /// [`TlsListenerBuilder::cert`], and [`TlsListenerBuilder::config`], but
125+ /// gives total control over accepting TLS connections, including
126+ /// multiplexing other streams or ALPN negotiations on the same TLS
127+ /// connection that tide should ignore.
128+ pub fn tls_acceptor ( mut self , acceptor : Arc < dyn CustomTlsAcceptor > ) -> Self {
129+ self . tls_acceptor = Some ( acceptor) ;
130+ self
131+ }
132+
111133 /// Provides a bound tcp listener (either async-std or std) to
112134 /// build this tls listener on. This is mutually exclusive with
113135 /// [`TlsListenerBuilder::addrs`], but one of them is mandatory.
@@ -134,26 +156,29 @@ impl<State> TlsListenerBuilder<State> {
134156 /// * either of these is provided, but not both
135157 /// * [`TlsListenerBuilder::tcp`]
136158 /// * [`TlsListenerBuilder::addrs`]
137- /// * either of these is provided, but not both
159+ /// * exactly one of these is provided
138160 /// * both [`TlsListenerBuilder::cert`] AND [`TlsListenerBuilder::key`]
139161 /// * [`TlsListenerBuilder::config`]
162+ /// * [`TlsListenerBuilder::tls_acceptor`]
140163 pub fn finish ( self ) -> io:: Result < TlsListener < State > > {
141164 let Self {
142165 key,
143166 cert,
144167 config,
168+ tls_acceptor,
145169 tcp,
146170 addrs,
147171 ..
148172 } = self ;
149173
150- let config = match ( key, cert, config) {
151- ( Some ( key) , Some ( cert) , None ) => TlsListenerConfig :: Paths { key, cert } ,
152- ( None , None , Some ( config) ) => TlsListenerConfig :: ServerConfig ( config) ,
174+ let config = match ( key, cert, config, tls_acceptor) {
175+ ( Some ( key) , Some ( cert) , None , None ) => TlsListenerConfig :: Paths { key, cert } ,
176+ ( None , None , Some ( config) , None ) => TlsListenerConfig :: ServerConfig ( config) ,
177+ ( None , None , None , Some ( tls_acceptor) ) => TlsListenerConfig :: Acceptor ( tls_acceptor) ,
153178 _ => {
154179 return Err ( io:: Error :: new (
155180 io:: ErrorKind :: InvalidInput ,
156- "either cert + key are required or a ServerConfig " ,
181+ "need exactly one of cert + key, ServerConfig, or TLS acceptor " ,
157182 ) )
158183 }
159184 } ;
0 commit comments