File tree Expand file tree Collapse file tree 2 files changed +59
-2
lines changed Expand file tree Collapse file tree 2 files changed +59
-2
lines changed Original file line number Diff line number Diff line change @@ -129,8 +129,8 @@ impl Accept {
129129
130130 // Try and find the first encoding that matches.
131131 for accept in & self . entries {
132- if available. contains ( accept) {
133- return Ok ( accept. media_type . clone ( ) . into ( ) ) ;
132+ if let Some ( accept ) = available. iter ( ) . find ( |m| m . subset_eq ( accept. media_type ( ) ) ) {
133+ return Ok ( accept. clone ( ) . into ( ) ) ;
134134 }
135135 }
136136
@@ -420,4 +420,22 @@ mod test {
420420 assert_eq ! ( accept. negotiate( & [ mime:: XML ] ) ?, mime:: XML ) ;
421421 Ok ( ( ) )
422422 }
423+
424+ #[ test]
425+ fn negotiate_missing_encoding ( ) -> crate :: Result < ( ) > {
426+ let mime_html = "text/html" . parse :: < Mime > ( ) ?;
427+
428+ let mut browser_accept = Accept :: new ( ) ;
429+ browser_accept. push ( MediaTypeProposal :: new ( mime_html, None ) ?) ;
430+
431+ let acceptable = & [ mime:: HTML ] ;
432+
433+ let content_type = browser_accept. negotiate ( acceptable) ;
434+
435+ assert ! (
436+ content_type. is_ok( ) ,
437+ "server is expected to return HTML content"
438+ ) ;
439+ Ok ( ( ) )
440+ }
423441}
Original file line number Diff line number Diff line change @@ -103,6 +103,45 @@ impl Mime {
103103 . position ( |( k, _) | k == & name)
104104 . map ( |pos| self . params . remove ( pos) . 1 )
105105 }
106+
107+ /// Check if this mime is a subtype of another mime.
108+ ///
109+ /// # Examples
110+ ///
111+ /// ```
112+ /// // All mime types are subsets of */*
113+ /// use http_types::mime::Mime;
114+ /// use std::str::FromStr;
115+ ///
116+ /// assert!(Mime::from_str("text/css").unwrap().subset_eq(&Mime::from_str("*/*").unwrap()));
117+ ///
118+ /// // A mime type is subset of itself
119+ /// assert!(Mime::from_str("text/css").unwrap().subset_eq(&Mime::from_str("text/css").unwrap()));
120+ ///
121+ /// // A mime type which is otherwise a subset with extra parameters is a subset of a mime type without those parameters
122+ /// assert!(Mime::from_str("text/css;encoding=utf-8").unwrap().subset_eq(&Mime::from_str("text/css").unwrap()));
123+ ///
124+ /// // A mime type more general than another mime type is not a subset
125+ /// assert!(!Mime::from_str("*/css;encoding=utf-8").unwrap().subset_eq(&Mime::from_str("text/css").unwrap()));
126+ /// ```
127+ pub fn subset_eq ( & self , other : & Mime ) -> bool {
128+ if other. basetype ( ) != "*" && self . basetype ( ) != other. basetype ( ) {
129+ return false ;
130+ }
131+ if other. subtype ( ) != "*" && self . subtype ( ) != other. subtype ( ) {
132+ return false ;
133+ }
134+ for ( name, value) in other. params . iter ( ) {
135+ if !self
136+ . param ( name. clone ( ) )
137+ . map ( |v| v == value)
138+ . unwrap_or ( false )
139+ {
140+ return false ;
141+ }
142+ }
143+ true
144+ }
106145}
107146
108147impl Display for Mime {
You can’t perform that action at this time.
0 commit comments