21
21
use crate :: router:: { Handler , HandlerObj , ResponseFuture , Router , RouterError } ;
22
22
use crate :: web:: response;
23
23
use futures:: channel:: oneshot;
24
- use futures:: TryStreamExt ;
25
24
use hyper:: server:: accept;
26
25
use hyper:: service:: make_service_fn;
27
26
use hyper:: { Body , Request , Server , StatusCode } ;
28
- use rustls :: internal :: pemfile;
27
+ use rustls_pemfile as pemfile;
29
28
use std:: convert:: Infallible ;
30
29
use std:: fs:: File ;
31
30
use std:: net:: SocketAddr ;
32
31
use std:: sync:: Arc ;
33
32
use std:: { io, thread} ;
34
33
use tokio:: net:: TcpListener ;
35
34
use tokio:: runtime:: Runtime ;
36
- use tokio:: stream:: StreamExt ;
37
35
use tokio_rustls:: TlsAcceptor ;
38
36
39
37
/// Errors that can be returned by an ApiEndpoint implementation.
@@ -83,8 +81,10 @@ impl TLSConfig {
83
81
} ) ?;
84
82
let mut reader = io:: BufReader :: new ( certfile) ;
85
83
86
- pemfile:: certs ( & mut reader)
87
- . map_err ( |_| Error :: Internal ( "failed to load certificate" . to_string ( ) ) )
84
+ let certs = pemfile:: certs ( & mut reader)
85
+ . map_err ( |_| Error :: Internal ( "failed to load certificate" . to_string ( ) ) ) ?;
86
+
87
+ Ok ( certs. into_iter ( ) . map ( rustls:: Certificate ) . collect ( ) )
88
88
}
89
89
90
90
fn load_private_key ( & self ) -> Result < rustls:: PrivateKey , Error > {
@@ -97,15 +97,19 @@ impl TLSConfig {
97
97
if keys. len ( ) != 1 {
98
98
return Err ( Error :: Internal ( "expected a single private key" . to_string ( ) ) ) ;
99
99
}
100
- Ok ( keys[ 0 ] . clone ( ) )
100
+ Ok ( rustls :: PrivateKey ( keys[ 0 ] . clone ( ) ) )
101
101
}
102
102
103
103
pub fn build_server_config ( & self ) -> Result < Arc < rustls:: ServerConfig > , Error > {
104
104
let certs = self . load_certs ( ) ?;
105
105
let key = self . load_private_key ( ) ?;
106
- let mut cfg = rustls:: ServerConfig :: new ( rustls:: NoClientAuth :: new ( ) ) ;
107
- cfg. set_single_cert ( certs, key)
106
+
107
+ let cfg = rustls:: ServerConfig :: builder ( )
108
+ . with_safe_defaults ( )
109
+ . with_no_client_auth ( )
110
+ . with_single_cert ( certs, key)
108
111
. map_err ( |e| Error :: Internal ( format ! ( "set single certificate failed {}" , e) ) ) ?;
112
+
109
113
Ok ( Arc :: new ( cfg) )
110
114
}
111
115
}
@@ -175,7 +179,7 @@ impl ApiServer {
175
179
server. await
176
180
} ;
177
181
178
- let mut rt = Runtime :: new ( )
182
+ let rt = Runtime :: new ( )
179
183
. map_err ( |e| eprintln ! ( "HTTP API server error: {}" , e) )
180
184
. unwrap ( ) ;
181
185
if let Err ( e) = rt. block_on ( server) {
@@ -214,13 +218,26 @@ impl ApiServer {
214
218
. name ( "apis" . to_string ( ) )
215
219
. spawn ( move || {
216
220
let server = async move {
217
- let mut listener = TcpListener :: bind ( & addr) . await . expect ( "failed to bind" ) ;
218
- let listener = listener
219
- . incoming ( )
220
- . and_then ( move |s| acceptor. accept ( s) )
221
- . filter ( |r| r. is_ok ( ) ) ;
221
+ let listener = TcpListener :: bind ( & addr) . await . expect ( "failed to bind" ) ;
222
+
223
+ let tls_stream = async_stream:: stream! {
224
+ loop {
225
+ let ( socket, _addr) = match listener. accept( ) . await {
226
+ Ok ( conn) => conn,
227
+ Err ( e) => {
228
+ eprintln!( "Error accepting connection: {}" , e) ;
229
+ continue ;
230
+ }
231
+ } ;
232
+
233
+ match acceptor. accept( socket) . await {
234
+ Ok ( stream) => yield Ok :: <_, std:: io:: Error >( stream) ,
235
+ Err ( _) => continue ,
236
+ }
237
+ }
238
+ } ;
222
239
223
- let server = Server :: builder ( accept:: from_stream ( listener ) )
240
+ let server = Server :: builder ( accept:: from_stream ( tls_stream ) )
224
241
. serve ( make_service_fn ( move |_| {
225
242
let router = router. clone ( ) ;
226
243
async move { Ok :: < _ , Infallible > ( router) }
@@ -232,7 +249,7 @@ impl ApiServer {
232
249
server. await
233
250
} ;
234
251
235
- let mut rt = Runtime :: new ( )
252
+ let rt = Runtime :: new ( )
236
253
. map_err ( |e| eprintln ! ( "HTTP API server error: {}" , e) )
237
254
. unwrap ( ) ;
238
255
if let Err ( e) = rt. block_on ( server) {
0 commit comments