@@ -3,9 +3,10 @@ use std::iter::FromIterator;
33use std:: str:: FromStr ;
44use std:: time:: Duration ;
55
6+ use either:: Either ;
67use http:: { HeaderName , HeaderValue } ;
78
8- use crate :: util:: { self , csv, Seconds } ;
9+ use crate :: util:: { self , csv, iter_flat_csv , Seconds } ;
910use crate :: { Error , Header } ;
1011
1112/// `Cache-Control` header, defined in [RFC7234](https://tools.ietf.org/html/rfc7234#section-5.2)
@@ -241,7 +242,17 @@ impl Header for CacheControl {
241242 }
242243
243244 fn decode < ' i , I : Iterator < Item = & ' i HeaderValue > > ( values : & mut I ) -> Result < Self , Error > {
244- csv:: from_comma_delimited ( values) . map ( |FromIter ( cc) | cc)
245+ let directives = values. flat_map ( |value| {
246+ let Ok ( value) = value. to_str ( ) else {
247+ return Either :: Left ( std:: iter:: once ( Err ( ( ) ) ) ) ;
248+ } ;
249+ Either :: Right ( iter_flat_csv ( value, ',' ) . map ( KnownDirective :: from_str) )
250+ } ) ;
251+
252+ match directives. collect ( ) {
253+ Ok ( FromIter ( cc) ) => Ok ( cc) ,
254+ Err ( ( ) ) => Err ( Error :: invalid ( ) ) ,
255+ }
245256 }
246257
247258 fn encode < E : Extend < HeaderValue > > ( & self , values : & mut E ) {
@@ -489,12 +500,7 @@ mod tests {
489500 fn test_parse_quoted_comma ( ) {
490501 assert_eq ! (
491502 test_decode:: <CacheControl >( & [ "foo=\" a, private, immutable, b\" , no-cache" ] ) . unwrap( ) ,
492- CacheControl :: new( )
493- . with_no_cache( )
494- // These are wrong: these appear inside a quoted string and so
495- // should be treated as parameter for the "a" directive.
496- . with_private( )
497- . with_immutable( ) ,
503+ CacheControl :: new( ) . with_no_cache( ) ,
498504 "unknown extensions are ignored but shouldn't fail parsing" ,
499505 )
500506 }
0 commit comments