@@ -6,6 +6,7 @@ use http_types::headers::{CONNECTION, UPGRADE};
66use http_types:: upgrade:: Connection ;
77use http_types:: { Request , Response , StatusCode } ;
88use std:: { marker:: PhantomData , time:: Duration } ;
9+ use stopper:: Stopper ;
910mod body_reader;
1011mod decode;
1112mod encode;
@@ -17,13 +18,16 @@ pub use encode::Encoder;
1718#[ derive( Debug , Clone ) ]
1819pub struct ServerOptions {
1920 /// 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 > ,
2124}
2225
2326impl Default for ServerOptions {
2427 fn default ( ) -> Self {
2528 Self {
2629 headers_timeout : Some ( Duration :: from_secs ( 60 ) ) ,
30+ stopper : None ,
2731 }
2832 }
2933}
@@ -113,17 +117,30 @@ where
113117 // Decode a new request, timing out if this takes longer than the timeout duration.
114118 let fut = decode ( self . io . clone ( ) ) ;
115119
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 {
118131 Ok ( Ok ( Some ( r) ) ) => r,
119132 Ok ( Ok ( None ) ) | Err ( TimeoutError { .. } ) => return Ok ( ConnectionStatus :: Close ) , /* EOF or timeout */
120133 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 ? {
124141 Some ( r) => r,
125142 None => return Ok ( ConnectionStatus :: Close ) , /* EOF */
126- }
143+ } ,
127144 } ;
128145
129146 let has_upgrade_header = req. header ( UPGRADE ) . is_some ( ) ;
0 commit comments