mirror of
https://github.com/servo/servo.git
synced 2025-07-22 14:53:49 +01:00
Use data_url::Mime to parse the MIME Types
This commit follows the spectification https://fetch.spec.whatwg.org/#concept-header-extract-mime-type
This commit is contained in:
parent
15a435a7ae
commit
43b3d93aec
10 changed files with 147 additions and 60 deletions
|
@ -10,8 +10,9 @@ use crate::dom::bindings::reflector::{reflect_dom_object, Reflector};
|
|||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::str::{is_token, ByteString};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use data_url::mime::Mime as DataUrlMime;
|
||||
use dom_struct::dom_struct;
|
||||
use http::header::{self, HeaderMap as HyperHeaders, HeaderName, HeaderValue};
|
||||
use http::header::{HeaderMap as HyperHeaders, HeaderName, HeaderValue};
|
||||
use net_traits::request::is_cors_safelisted_request_header;
|
||||
use std::cell::Cell;
|
||||
use std::str::{self, FromStr};
|
||||
|
@ -269,10 +270,7 @@ impl Headers {
|
|||
|
||||
// https://fetch.spec.whatwg.org/#concept-header-extract-mime-type
|
||||
pub fn extract_mime_type(&self) -> Vec<u8> {
|
||||
self.header_list
|
||||
.borrow()
|
||||
.get(header::CONTENT_TYPE)
|
||||
.map_or(vec![], |v| v.as_bytes().to_owned())
|
||||
extract_mime_type(&*self.header_list.borrow()).unwrap_or(vec![])
|
||||
}
|
||||
|
||||
pub fn sort_header_list(&self) -> Vec<(String, Vec<u8>)> {
|
||||
|
@ -469,3 +467,72 @@ pub fn is_obs_text(x: u8) -> bool {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-header-extract-mime-type
|
||||
// This function uses data_url::Mime to parse the MIME Type because
|
||||
// mime::Mime does not provide a parser following the Fetch spec
|
||||
// see https://github.com/hyperium/mime/issues/106
|
||||
pub fn extract_mime_type(headers: &HyperHeaders) -> Option<Vec<u8>> {
|
||||
let mut charset: Option<String> = None;
|
||||
let mut essence: String = "".to_string();
|
||||
let mut mime_type: Option<DataUrlMime> = None;
|
||||
|
||||
// Step 4
|
||||
let headers_values = headers.get_all(http::header::CONTENT_TYPE).iter();
|
||||
|
||||
// Step 5
|
||||
if headers_values.size_hint() == (0, Some(0)) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Step 6
|
||||
for header_value in headers_values {
|
||||
// Step 6.1
|
||||
match DataUrlMime::from_str(header_value.to_str().unwrap_or("")) {
|
||||
// Step 6.2
|
||||
Err(_) => continue,
|
||||
Ok(temp_mime) => {
|
||||
let temp_essence = format!("{}/{}", temp_mime.type_, temp_mime.subtype);
|
||||
|
||||
// Step 6.2
|
||||
if temp_essence == "*/*" {
|
||||
continue;
|
||||
}
|
||||
|
||||
let temp_charset = &temp_mime.get_parameter("charset");
|
||||
|
||||
// Step 6.3
|
||||
mime_type = Some(DataUrlMime {
|
||||
type_: temp_mime.type_.to_string(),
|
||||
subtype: temp_mime.subtype.to_string(),
|
||||
parameters: temp_mime.parameters.clone(),
|
||||
});
|
||||
|
||||
// Step 6.4
|
||||
if temp_essence != essence {
|
||||
charset = temp_charset.map(|c| c.to_string());
|
||||
essence = temp_essence.to_owned();
|
||||
} else {
|
||||
// Step 6.5
|
||||
if temp_charset.is_none() && charset.is_some() {
|
||||
let DataUrlMime {
|
||||
type_: t,
|
||||
subtype: st,
|
||||
parameters: p,
|
||||
} = mime_type.unwrap();
|
||||
let mut params = p;
|
||||
params.push(("charset".to_string(), charset.clone().unwrap()));
|
||||
mime_type = Some(DataUrlMime {
|
||||
type_: t.to_string(),
|
||||
subtype: st.to_string(),
|
||||
parameters: params,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Step 7, 8
|
||||
return mime_type.map(|m| format!("{}", m).into_bytes());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue