@@ -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,72 @@ 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 ( )
311+ . insert ( "keep-alive" , "timeout=5, max=100" . try_into ( ) . unwrap ( ) ) ;
312+
313+ let ( timeout, max) = super :: parse_keep_alive ( & res) ;
314+
315+ assert_eq ! ( timeout, Some ( Duration :: from_secs( 5 ) ) ) ;
316+ assert_eq ! ( max, Some ( 100 ) ) ;
317+
318+ let mut res = http:: Response :: new ( ( ) ) ;
319+ res. headers_mut ( ) . insert ( "keep-alive" , "timeout=5" . try_into ( ) . unwrap ( ) ) ;
320+
321+ let ( timeout, max) = super :: parse_keep_alive ( & res) ;
322+
323+ assert_eq ! ( timeout, Some ( Duration :: from_secs( 5 ) ) ) ;
324+ assert_eq ! ( max, None ) ;
325+
326+ let mut res = http:: Response :: new ( ( ) ) ;
327+ res. headers_mut ( ) . insert ( "keep-alive" , "max=5" . try_into ( ) . unwrap ( ) ) ;
328+
329+ let ( timeout, max) = super :: parse_keep_alive ( & res) ;
330+
331+ assert_eq ! ( timeout, None ) ;
332+ assert_eq ! ( max, Some ( 5 ) ) ;
333+ }
334+
271335 use core:: time:: Duration ;
272336
273337 use std:: sync:: Arc ;
0 commit comments