@@ -6,6 +6,7 @@ use http_types::headers::{CONNECTION, UPGRADE};
6
6
use http_types:: upgrade:: Connection ;
7
7
use http_types:: { Request , Response , StatusCode } ;
8
8
use std:: { marker:: PhantomData , time:: Duration } ;
9
+ use stopper:: Stopper ;
9
10
mod body_reader;
10
11
mod decode;
11
12
mod encode;
@@ -17,13 +18,16 @@ pub use encode::Encoder;
17
18
#[ derive( Debug , Clone ) ]
18
19
pub struct ServerOptions {
19
20
/// Timeout to handle headers. Defaults to 60s.
20
- headers_timeout : Option < Duration > ,
21
+ pub headers_timeout : Option < Duration > ,
22
+ /// Stopper to shutdown the server. Defaults to None.
23
+ pub stopper : Option < Stopper > ,
21
24
}
22
25
23
26
impl Default for ServerOptions {
24
27
fn default ( ) -> Self {
25
28
Self {
26
29
headers_timeout : Some ( Duration :: from_secs ( 60 ) ) ,
30
+ stopper : None ,
27
31
}
28
32
}
29
33
}
@@ -113,17 +117,30 @@ where
113
117
// Decode a new request, timing out if this takes longer than the timeout duration.
114
118
let fut = decode ( self . io . clone ( ) ) ;
115
119
116
- let ( req, mut body) = if let Some ( timeout_duration) = self . opts . headers_timeout {
117
- match timeout ( timeout_duration, fut) . await {
120
+ let ( req, mut body) = match ( self . opts . headers_timeout , & self . opts . stopper ) {
121
+ ( Some ( timeout_duration) , Some ( stopper) ) => {
122
+ match timeout ( timeout_duration, stopper. stop_future ( fut) ) . await {
123
+ Ok ( Some ( Ok ( Some ( r) ) ) ) => r,
124
+ Ok ( Some ( Ok ( None ) ) ) | Err ( TimeoutError { .. } ) | Ok ( None ) => {
125
+ return Ok ( ConnectionStatus :: Close ) ;
126
+ } /* EOF, timeout, or stopped by stopper */
127
+ Ok ( Some ( Err ( e) ) ) => return Err ( e) ,
128
+ }
129
+ }
130
+ ( Some ( timeout_duration) , None ) => match timeout ( timeout_duration, fut) . await {
118
131
Ok ( Ok ( Some ( r) ) ) => r,
119
132
Ok ( Ok ( None ) ) | Err ( TimeoutError { .. } ) => return Ok ( ConnectionStatus :: Close ) , /* EOF or timeout */
120
133
Ok ( Err ( e) ) => return Err ( e) ,
121
- }
122
- } else {
123
- match fut. await ? {
134
+ } ,
135
+ ( None , Some ( stopper) ) => match stopper. stop_future ( fut) . await {
136
+ Some ( Ok ( Some ( r) ) ) => r,
137
+ Some ( Ok ( None ) ) | None => return Ok ( ConnectionStatus :: Close ) , /* EOF or stopped by stopper */
138
+ Some ( Err ( e) ) => return Err ( e) ,
139
+ } ,
140
+ ( None , None ) => match fut. await ? {
124
141
Some ( r) => r,
125
142
None => return Ok ( ConnectionStatus :: Close ) , /* EOF */
126
- }
143
+ } ,
127
144
} ;
128
145
129
146
let has_upgrade_header = req. header ( UPGRADE ) . is_some ( ) ;
0 commit comments