4
4
//! Certificate and private key are hardcoded to sample files.
5
5
//! hyper will automatically use HTTP/2 if a client starts talking HTTP/2,
6
6
//! otherwise HTTP/1.1 will be used.
7
- use core:: task:: { Context , Poll } ;
8
- use futures_util:: ready;
9
- use hyper:: server:: accept:: Accept ;
10
- use hyper:: server:: conn:: { AddrIncoming , AddrStream } ;
7
+
8
+ #![ cfg( feature = "acceptor" ) ]
9
+
10
+ use std:: vec:: Vec ;
11
+ use std:: { env, fs, io} ;
12
+
13
+ use hyper:: server:: conn:: AddrIncoming ;
11
14
use hyper:: service:: { make_service_fn, service_fn} ;
12
15
use hyper:: { Body , Method , Request , Response , Server , StatusCode } ;
13
- use std:: future:: Future ;
14
- use std:: pin:: Pin ;
15
- use std:: sync:: Arc ;
16
- use std:: vec:: Vec ;
17
- use std:: { env, fs, io, sync} ;
18
- use tokio:: io:: { AsyncRead , AsyncWrite , ReadBuf } ;
19
- use tokio_rustls:: rustls:: ServerConfig ;
16
+ use hyper_rustls:: TlsAcceptor ;
20
17
21
18
fn main ( ) {
22
19
// Serve an echo service over HTTPS, with proper error handling.
@@ -39,139 +36,28 @@ async fn run_server() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
39
36
} ;
40
37
let addr = format ! ( "127.0.0.1:{}" , port) . parse ( ) ?;
41
38
39
+ // Load public certificate.
40
+ let certs = load_certs ( "examples/sample.pem" ) ?;
41
+ // Load private key.
42
+ let key = load_private_key ( "examples/sample.rsa" ) ?;
42
43
// Build TLS configuration.
43
- let tls_cfg = {
44
- // Load public certificate.
45
- let certs = load_certs ( "examples/sample.pem" ) ?;
46
- // Load private key.
47
- let key = load_private_key ( "examples/sample.rsa" ) ?;
48
- // Do not use client certificate authentication.
49
- let mut cfg = rustls:: ServerConfig :: builder ( )
50
- . with_safe_defaults ( )
51
- . with_no_client_auth ( )
52
- . with_single_cert ( certs, key)
53
- . map_err ( |e| error ( format ! ( "{}" , e) ) ) ?;
54
- // Configure ALPN to accept HTTP/2, HTTP/1.1, and HTTP/1.0 in that order.
55
- cfg. alpn_protocols = vec ! [ b"h2" . to_vec( ) , b"http/1.1" . to_vec( ) , b"http/1.0" . to_vec( ) ] ;
56
- sync:: Arc :: new ( cfg)
57
- } ;
58
44
59
45
// Create a TCP listener via tokio.
60
46
let incoming = AddrIncoming :: bind ( & addr) ?;
47
+ let acceptor = TlsAcceptor :: builder ( )
48
+ . with_single_cert ( certs, key)
49
+ . map_err ( |e| error ( format ! ( "{}" , e) ) ) ?
50
+ . with_all_versions_alpn ( )
51
+ . with_incoming ( incoming) ;
61
52
let service = make_service_fn ( |_| async { Ok :: < _ , io:: Error > ( service_fn ( echo) ) } ) ;
62
- let server = Server :: builder ( TlsAcceptor :: new ( tls_cfg , incoming ) ) . serve ( service) ;
53
+ let server = Server :: builder ( acceptor ) . serve ( service) ;
63
54
64
55
// Run the future, keep going until an error occurs.
65
56
println ! ( "Starting to serve on https://{}." , addr) ;
66
57
server. await ?;
67
58
Ok ( ( ) )
68
59
}
69
60
70
- enum State {
71
- Handshaking ( tokio_rustls:: Accept < AddrStream > ) ,
72
- Streaming ( tokio_rustls:: server:: TlsStream < AddrStream > ) ,
73
- }
74
-
75
- // tokio_rustls::server::TlsStream doesn't expose constructor methods,
76
- // so we have to TlsAcceptor::accept and handshake to have access to it
77
- // TlsStream implements AsyncRead/AsyncWrite handshaking tokio_rustls::Accept first
78
- pub struct TlsStream {
79
- state : State ,
80
- }
81
-
82
- impl TlsStream {
83
- fn new ( stream : AddrStream , config : Arc < ServerConfig > ) -> TlsStream {
84
- let accept = tokio_rustls:: TlsAcceptor :: from ( config) . accept ( stream) ;
85
- TlsStream {
86
- state : State :: Handshaking ( accept) ,
87
- }
88
- }
89
- }
90
-
91
- impl AsyncRead for TlsStream {
92
- fn poll_read (
93
- self : Pin < & mut Self > ,
94
- cx : & mut Context ,
95
- buf : & mut ReadBuf ,
96
- ) -> Poll < io:: Result < ( ) > > {
97
- let pin = self . get_mut ( ) ;
98
- match pin. state {
99
- State :: Handshaking ( ref mut accept) => match ready ! ( Pin :: new( accept) . poll( cx) ) {
100
- Ok ( mut stream) => {
101
- let result = Pin :: new ( & mut stream) . poll_read ( cx, buf) ;
102
- pin. state = State :: Streaming ( stream) ;
103
- result
104
- }
105
- Err ( err) => Poll :: Ready ( Err ( err) ) ,
106
- } ,
107
- State :: Streaming ( ref mut stream) => Pin :: new ( stream) . poll_read ( cx, buf) ,
108
- }
109
- }
110
- }
111
-
112
- impl AsyncWrite for TlsStream {
113
- fn poll_write (
114
- self : Pin < & mut Self > ,
115
- cx : & mut Context < ' _ > ,
116
- buf : & [ u8 ] ,
117
- ) -> Poll < io:: Result < usize > > {
118
- let pin = self . get_mut ( ) ;
119
- match pin. state {
120
- State :: Handshaking ( ref mut accept) => match ready ! ( Pin :: new( accept) . poll( cx) ) {
121
- Ok ( mut stream) => {
122
- let result = Pin :: new ( & mut stream) . poll_write ( cx, buf) ;
123
- pin. state = State :: Streaming ( stream) ;
124
- result
125
- }
126
- Err ( err) => Poll :: Ready ( Err ( err) ) ,
127
- } ,
128
- State :: Streaming ( ref mut stream) => Pin :: new ( stream) . poll_write ( cx, buf) ,
129
- }
130
- }
131
-
132
- fn poll_flush ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < io:: Result < ( ) > > {
133
- match self . state {
134
- State :: Handshaking ( _) => Poll :: Ready ( Ok ( ( ) ) ) ,
135
- State :: Streaming ( ref mut stream) => Pin :: new ( stream) . poll_flush ( cx) ,
136
- }
137
- }
138
-
139
- fn poll_shutdown ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < io:: Result < ( ) > > {
140
- match self . state {
141
- State :: Handshaking ( _) => Poll :: Ready ( Ok ( ( ) ) ) ,
142
- State :: Streaming ( ref mut stream) => Pin :: new ( stream) . poll_shutdown ( cx) ,
143
- }
144
- }
145
- }
146
-
147
- pub struct TlsAcceptor {
148
- config : Arc < ServerConfig > ,
149
- incoming : AddrIncoming ,
150
- }
151
-
152
- impl TlsAcceptor {
153
- pub fn new ( config : Arc < ServerConfig > , incoming : AddrIncoming ) -> TlsAcceptor {
154
- TlsAcceptor { config, incoming }
155
- }
156
- }
157
-
158
- impl Accept for TlsAcceptor {
159
- type Conn = TlsStream ;
160
- type Error = io:: Error ;
161
-
162
- fn poll_accept (
163
- self : Pin < & mut Self > ,
164
- cx : & mut Context < ' _ > ,
165
- ) -> Poll < Option < Result < Self :: Conn , Self :: Error > > > {
166
- let pin = self . get_mut ( ) ;
167
- match ready ! ( Pin :: new( & mut pin. incoming) . poll_accept( cx) ) {
168
- Some ( Ok ( sock) ) => Poll :: Ready ( Some ( Ok ( TlsStream :: new ( sock, pin. config . clone ( ) ) ) ) ) ,
169
- Some ( Err ( e) ) => Poll :: Ready ( Some ( Err ( e) ) ) ,
170
- None => Poll :: Ready ( None ) ,
171
- }
172
- }
173
- }
174
-
175
61
// Custom echo service, handling two different routes and a
176
62
// catch-all 404 responder.
177
63
async fn echo ( req : Request < Body > ) -> Result < Response < Body > , hyper:: Error > {
0 commit comments