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 {
129
129
130
130
// Try and find the first encoding that matches.
131
131
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 ( ) ) ;
134
134
}
135
135
}
136
136
@@ -420,4 +420,22 @@ mod test {
420
420
assert_eq ! ( accept. negotiate( & [ mime:: XML ] ) ?, mime:: XML ) ;
421
421
Ok ( ( ) )
422
422
}
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
+ }
423
441
}
Original file line number Diff line number Diff line change @@ -103,6 +103,45 @@ impl Mime {
103
103
. position ( |( k, _) | k == & name)
104
104
. map ( |pos| self . params . remove ( pos) . 1 )
105
105
}
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
+ }
106
145
}
107
146
108
147
impl Display for Mime {
You can’t perform that action at this time.
0 commit comments