@@ -5,7 +5,7 @@ use crate::{
55 client:: Client ,
66 connect:: Connect ,
77 error:: Error ,
8- http:: { Request , Version } ,
8+ http:: { HeaderName , Request , Version } ,
99 pool:: { exclusive, shared} ,
1010 response:: Response ,
1111 uri:: Uri ,
@@ -227,6 +227,9 @@ pub(crate) fn base_service() -> HttpService {
227227 Ok ( Ok ( ( res, buf, decoder, is_close) ) ) => {
228228 if is_close {
229229 _conn. destroy_on_drop ( ) ;
230+ } else {
231+ let ( timeout, max) = parse_keep_alive ( & res) ;
232+ _conn. keep_alive_hint ( timeout, max) ;
230233 }
231234 let body = crate :: h1:: body:: ResponseBody :: new ( _conn, buf, decoder) ;
232235 let res = res. map ( |_| crate :: body:: ResponseBody :: H1 ( body) ) ;
@@ -263,11 +266,71 @@ pub(crate) fn base_service() -> HttpService {
263266 Box :: new ( HttpService )
264267}
265268
269+ const KEEP_ALIVE : HeaderName = HeaderName :: from_static ( "keep-alive" ) ;
270+
271+ fn parse_keep_alive < B > ( res : & crate :: http:: Response < B > ) -> ( Option < Duration > , Option < usize > ) {
272+ let header = match res. headers ( ) . get ( KEEP_ALIVE ) . map ( |h| h. to_str ( ) ) {
273+ Some ( Ok ( header) ) => header,
274+ _ => return ( None , None ) ,
275+ } ;
276+
277+ let mut timeout = None ;
278+ let mut max = None ;
279+
280+ for ( key, value) in header. split ( ',' ) . map ( |item| {
281+ let mut kv = item. splitn ( 2 , '=' ) ;
282+
283+ (
284+ kv. next ( ) . map ( |s| s. trim ( ) ) . unwrap_or_default ( ) ,
285+ kv. next ( ) . map ( |s| s. trim ( ) ) . unwrap_or_default ( ) ,
286+ )
287+ } ) {
288+ match key. to_lowercase ( ) . as_str ( ) {
289+ "timeout" => {
290+ timeout = value. parse :: < u64 > ( ) . ok ( ) . map ( Duration :: from_secs) ;
291+ }
292+ "max" => {
293+ max = value. parse ( ) . ok ( ) ;
294+ }
295+ _ => { }
296+ }
297+ }
298+
299+ ( timeout, max)
300+ }
301+
266302#[ cfg( test) ]
267303pub ( crate ) use test:: mock_service;
268304
269305#[ cfg( test) ]
270306mod test {
307+ #[ test]
308+ fn test_parse_keep_alive ( ) {
309+ let mut res = http:: Response :: new ( ( ) ) ;
310+ res. headers_mut ( ) . insert ( "keep-alive" , "timeout=5, max=100" . try_into ( ) . unwrap ( ) ) ;
311+
312+ let ( timeout, max) = super :: parse_keep_alive ( & res) ;
313+
314+ assert_eq ! ( timeout, Some ( Duration :: from_secs( 5 ) ) ) ;
315+ assert_eq ! ( max, Some ( 100 ) ) ;
316+
317+ let mut res = http:: Response :: new ( ( ) ) ;
318+ res. headers_mut ( ) . insert ( "keep-alive" , "timeout=5" . try_into ( ) . unwrap ( ) ) ;
319+
320+ let ( timeout, max) = super :: parse_keep_alive ( & res) ;
321+
322+ assert_eq ! ( timeout, Some ( Duration :: from_secs( 5 ) ) ) ;
323+ assert_eq ! ( max, None ) ;
324+
325+ let mut res = http:: Response :: new ( ( ) ) ;
326+ res. headers_mut ( ) . insert ( "keep-alive" , "max=5" . try_into ( ) . unwrap ( ) ) ;
327+
328+ let ( timeout, max) = super :: parse_keep_alive ( & res) ;
329+
330+ assert_eq ! ( timeout, None ) ;
331+ assert_eq ! ( max, Some ( 5 ) ) ;
332+ }
333+
271334 use core:: time:: Duration ;
272335
273336 use std:: sync:: Arc ;
0 commit comments