@@ -3,11 +3,12 @@ use async_std::net::TcpListener;
3
3
4
4
use rustls:: ServerConfig ;
5
5
6
- use super :: { TcpConnection , TlsListener , TlsListenerConfig } ;
6
+ use super :: { CustomTlsAcceptor , TcpConnection , TlsListener , TlsListenerConfig } ;
7
7
8
8
use std:: marker:: PhantomData ;
9
9
use std:: net:: { SocketAddr , ToSocketAddrs } ;
10
10
use std:: path:: { Path , PathBuf } ;
11
+ use std:: sync:: Arc ;
11
12
12
13
/// # A builder for TlsListeners
13
14
///
@@ -38,6 +39,7 @@ pub struct TlsListenerBuilder<State> {
38
39
key : Option < PathBuf > ,
39
40
cert : Option < PathBuf > ,
40
41
config : Option < ServerConfig > ,
42
+ tls_acceptor : Option < Arc < dyn CustomTlsAcceptor > > ,
41
43
tcp : Option < TcpListener > ,
42
44
addrs : Option < Vec < SocketAddr > > ,
43
45
_state : PhantomData < State > ,
@@ -49,6 +51,7 @@ impl<State> Default for TlsListenerBuilder<State> {
49
51
key : None ,
50
52
cert : None ,
51
53
config : None ,
54
+ tls_acceptor : None ,
52
55
tcp : None ,
53
56
addrs : None ,
54
57
_state : PhantomData ,
@@ -69,6 +72,14 @@ impl<State> std::fmt::Debug for TlsListenerBuilder<State> {
69
72
"None"
70
73
} ,
71
74
)
75
+ . field (
76
+ "tls_acceptor" ,
77
+ & if self . tls_acceptor . is_some ( ) {
78
+ "Some(_)"
79
+ } else {
80
+ "None"
81
+ } ,
82
+ )
72
83
. field ( "tcp" , & self . tcp )
73
84
. field ( "addrs" , & self . addrs )
74
85
. finish ( )
@@ -108,6 +119,17 @@ impl<State> TlsListenerBuilder<State> {
108
119
self
109
120
}
110
121
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
+
111
133
/// Provides a bound tcp listener (either async-std or std) to
112
134
/// build this tls listener on. This is mutually exclusive with
113
135
/// [`TlsListenerBuilder::addrs`], but one of them is mandatory.
@@ -134,26 +156,29 @@ impl<State> TlsListenerBuilder<State> {
134
156
/// * either of these is provided, but not both
135
157
/// * [`TlsListenerBuilder::tcp`]
136
158
/// * [`TlsListenerBuilder::addrs`]
137
- /// * either of these is provided, but not both
159
+ /// * exactly one of these is provided
138
160
/// * both [`TlsListenerBuilder::cert`] AND [`TlsListenerBuilder::key`]
139
161
/// * [`TlsListenerBuilder::config`]
162
+ /// * [`TlsListenerBuilder::tls_acceptor`]
140
163
pub fn finish ( self ) -> io:: Result < TlsListener < State > > {
141
164
let Self {
142
165
key,
143
166
cert,
144
167
config,
168
+ tls_acceptor,
145
169
tcp,
146
170
addrs,
147
171
..
148
172
} = self ;
149
173
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) ,
153
178
_ => {
154
179
return Err ( io:: Error :: new (
155
180
io:: ErrorKind :: InvalidInput ,
156
- "either cert + key are required or a ServerConfig " ,
181
+ "need exactly one of cert + key, ServerConfig, or TLS acceptor " ,
157
182
) )
158
183
}
159
184
} ;
0 commit comments