mirror of
https://github.com/servo/servo.git
synced 2025-06-13 19:04:30 +00:00
Update hyper to 0.12
This commit is contained in:
parent
95bfaa0a77
commit
024b40b39d
122 changed files with 3835 additions and 3448 deletions
|
@ -31,13 +31,13 @@ tinyfiledialogs = "3.0"
|
|||
[dependencies]
|
||||
app_units = "0.7"
|
||||
backtrace = {version = "0.3", optional = true}
|
||||
base64 = "0.6"
|
||||
base64 = "0.9"
|
||||
bitflags = "1.0"
|
||||
bluetooth_traits = {path = "../bluetooth_traits"}
|
||||
byteorder = "1.0"
|
||||
canvas_traits = {path = "../canvas_traits"}
|
||||
caseless = "0.2"
|
||||
cookie = "0.10"
|
||||
cookie = "0.11"
|
||||
chrono = "0.4"
|
||||
cssparser = "0.24"
|
||||
deny_public_fields = {path = "../deny_public_fields"}
|
||||
|
@ -51,9 +51,12 @@ euclid = "0.19"
|
|||
fnv = "1.0"
|
||||
gleam = "0.6"
|
||||
half = "1.0"
|
||||
headers-core = "0.0.1"
|
||||
headers-ext = "0.0.3"
|
||||
html5ever = "0.22"
|
||||
hyper = "0.10"
|
||||
hyper_serde = "0.8"
|
||||
http = "0.1"
|
||||
hyper = "0.12"
|
||||
hyper_serde = "0.9"
|
||||
image = "0.19"
|
||||
ipc-channel = "0.11"
|
||||
itertools = "0.7.6"
|
||||
|
@ -66,8 +69,8 @@ malloc_size_of = { path = "../malloc_size_of" }
|
|||
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
|
||||
metrics = {path = "../metrics"}
|
||||
mitochondria = "1.1.2"
|
||||
mime = "0.2.1"
|
||||
mime_guess = "1.8.0"
|
||||
mime = "0.3"
|
||||
mime_guess = "2.0.0-alpha.6"
|
||||
mozjs = "0.9.3"
|
||||
msg = {path = "../msg"}
|
||||
net_traits = {path = "../net_traits"}
|
||||
|
|
|
@ -22,7 +22,7 @@ use js::jsval::UndefinedValue;
|
|||
use js::rust::wrappers::JS_GetPendingException;
|
||||
use js::rust::wrappers::JS_ParseJSON;
|
||||
use js::typedarray::{ArrayBuffer, CreateWith};
|
||||
use mime::{Mime, TopLevel, SubLevel};
|
||||
use mime::{self, Mime};
|
||||
use std::cell::Ref;
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
@ -175,23 +175,22 @@ fn run_form_data_algorithm(
|
|||
} else {
|
||||
""
|
||||
};
|
||||
let mime: Mime = mime_str
|
||||
.parse()
|
||||
.map_err(|_| Error::Type("Inappropriate MIME-type for Body".to_string()))?;
|
||||
match mime {
|
||||
// TODO
|
||||
// ... Parser for Mime(TopLevel::Multipart, SubLevel::FormData, _)
|
||||
// ... is not fully determined yet.
|
||||
Mime(TopLevel::Application, SubLevel::WwwFormUrlEncoded, _) => {
|
||||
let entries = form_urlencoded::parse(&bytes);
|
||||
let formdata = FormData::new(None, root);
|
||||
for (k, e) in entries {
|
||||
formdata.Append(USVString(k.into_owned()), USVString(e.into_owned()));
|
||||
}
|
||||
return Ok(FetchedData::FormData(formdata));
|
||||
},
|
||||
_ => return Err(Error::Type("Inappropriate MIME-type for Body".to_string())),
|
||||
let mime: Mime = mime_str.parse().map_err(
|
||||
|_| Error::Type("Inappropriate MIME-type for Body".to_string()))?;
|
||||
|
||||
// TODO
|
||||
// ... Parser for Mime(TopLevel::Multipart, SubLevel::FormData, _)
|
||||
// ... is not fully determined yet.
|
||||
if mime.type_() == mime::APPLICATION && mime.subtype() == mime::WWW_FORM_URLENCODED {
|
||||
let entries = form_urlencoded::parse(&bytes);
|
||||
let formdata = FormData::new(None, root);
|
||||
for (k, e) in entries {
|
||||
formdata.Append(USVString(k.into_owned()), USVString(e.into_owned()));
|
||||
}
|
||||
return Ok(FetchedData::FormData(formdata));
|
||||
}
|
||||
|
||||
Err(Error::Type("Inappropriate MIME-type for Body".to_string()))
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
|
|
|
@ -55,10 +55,9 @@ use euclid::Length as EuclidLength;
|
|||
use html5ever::{Prefix, LocalName, Namespace, QualName};
|
||||
use html5ever::buffer_queue::BufferQueue;
|
||||
use html5ever::tendril::IncompleteUtf8;
|
||||
use hyper::header::Headers;
|
||||
use hyper::method::Method;
|
||||
use hyper::mime::Mime;
|
||||
use hyper::status::StatusCode;
|
||||
use http::header::HeaderMap;
|
||||
use hyper::Method;
|
||||
use hyper::StatusCode;
|
||||
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
||||
use js::glue::{CallObjectTracer, CallValueTracer};
|
||||
use js::jsapi::{GCTraceKindToAscii, Heap, JSObject, JSTracer, TraceKind};
|
||||
|
@ -67,6 +66,7 @@ use js::rust::{GCMethods, Handle, Runtime};
|
|||
use js::typedarray::TypedArray;
|
||||
use js::typedarray::TypedArrayElement;
|
||||
use metrics::{InteractiveMetrics, InteractiveWindow};
|
||||
use mime::Mime;
|
||||
use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId, TopLevelBrowsingContextId};
|
||||
use net_traits::{Metadata, NetworkError, ReferrerPolicy, ResourceThreads};
|
||||
use net_traits::filemanager_thread::RelativePos;
|
||||
|
@ -391,7 +391,7 @@ unsafe_no_jsmanaged_fields!(TimelineMarkerType);
|
|||
unsafe_no_jsmanaged_fields!(WorkerId);
|
||||
unsafe_no_jsmanaged_fields!(BufferQueue, QuirksMode, IncompleteUtf8);
|
||||
unsafe_no_jsmanaged_fields!(Runtime);
|
||||
unsafe_no_jsmanaged_fields!(Headers, Method);
|
||||
unsafe_no_jsmanaged_fields!(HeaderMap, Method);
|
||||
unsafe_no_jsmanaged_fields!(WindowProxyHandler);
|
||||
unsafe_no_jsmanaged_fields!(UntrustedNodeAddress);
|
||||
unsafe_no_jsmanaged_fields!(LengthOrPercentageOrAuto);
|
||||
|
|
|
@ -95,14 +95,13 @@ use encoding_rs::{Encoding, UTF_8};
|
|||
use euclid::Point2D;
|
||||
use fetch::FetchCanceller;
|
||||
use html5ever::{LocalName, Namespace, QualName};
|
||||
use hyper::header::{Header, SetCookie};
|
||||
use hyper_serde::Serde;
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use js::jsapi::{JSContext, JSObject, JSRuntime};
|
||||
use js::jsapi::JS_GetRuntime;
|
||||
use keyboard_types::{Key, KeyState, Modifiers};
|
||||
use metrics::{InteractiveFlag, InteractiveMetrics, InteractiveWindow, ProfilerMetadataFactory, ProgressiveWebMetric};
|
||||
use mime::{Mime, TopLevel, SubLevel};
|
||||
use mime::{self, Mime};
|
||||
use msg::constellation_msg::BrowsingContextId;
|
||||
use net_traits::{FetchResponseMsg, IpcSend, ReferrerPolicy};
|
||||
use net_traits::CookieSource::NonHTTP;
|
||||
|
@ -2530,14 +2529,12 @@ impl Document {
|
|||
implementation: Default::default(),
|
||||
content_type: match content_type {
|
||||
Some(mime_data) => mime_data,
|
||||
None => Mime::from(match is_html_document {
|
||||
None => match is_html_document {
|
||||
// https://dom.spec.whatwg.org/#dom-domimplementation-createhtmldocument
|
||||
IsHTMLDocument::HTMLDocument => Mime(TopLevel::Text, SubLevel::Html, vec![]),
|
||||
IsHTMLDocument::HTMLDocument => mime::TEXT_HTML,
|
||||
// https://dom.spec.whatwg.org/#concept-document-content-type
|
||||
IsHTMLDocument::NonHTMLDocument => {
|
||||
Mime(TopLevel::Application, SubLevel::Xml, vec![])
|
||||
},
|
||||
}),
|
||||
IsHTMLDocument::NonHTMLDocument => "application/xml".parse().unwrap(),
|
||||
},
|
||||
},
|
||||
last_modified: last_modified,
|
||||
url: DomRefCell::new(url),
|
||||
|
@ -3345,8 +3342,10 @@ impl DocumentMethods for Document {
|
|||
local_name.make_ascii_lowercase();
|
||||
}
|
||||
|
||||
let is_xhtml = self.content_type.0 == TopLevel::Application &&
|
||||
self.content_type.1.as_str() == "xhtml+xml";
|
||||
let is_xhtml = self.content_type.type_() == mime::APPLICATION &&
|
||||
self.content_type.subtype().as_str() == "xhtml" &&
|
||||
self.content_type.suffix() == Some(mime::XML);
|
||||
|
||||
let ns = if self.is_html_document || is_xhtml {
|
||||
ns!(html)
|
||||
} else {
|
||||
|
@ -3947,18 +3946,16 @@ impl DocumentMethods for Document {
|
|||
return Err(Error::Security);
|
||||
}
|
||||
|
||||
if let Ok(cookie_header) = SetCookie::parse_header(&vec![cookie.to_string().into_bytes()]) {
|
||||
let cookies = cookie_header
|
||||
.0
|
||||
.into_iter()
|
||||
.filter_map(|cookie| cookie_rs::Cookie::parse(cookie).ok().map(Serde))
|
||||
.collect();
|
||||
let _ = self
|
||||
.window
|
||||
let cookies = if let Some(cookie) = cookie_rs::Cookie::parse(cookie.to_string()).ok().map(Serde) {
|
||||
vec![cookie]
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
|
||||
let _ = self.window
|
||||
.upcast::<GlobalScope>()
|
||||
.resource_threads()
|
||||
.send(SetCookiesForUrl(self.url(), cookies, NonHTTP));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ use dom::node::Node;
|
|||
use dom::text::Text;
|
||||
use dom::xmldocument::XMLDocument;
|
||||
use dom_struct::dom_struct;
|
||||
use mime::{Mime, TopLevel, SubLevel};
|
||||
use mime;
|
||||
use script_traits::DocumentActivity;
|
||||
|
||||
// https://dom.spec.whatwg.org/#domimplementation
|
||||
|
@ -82,17 +82,9 @@ impl DOMImplementationMethods for DOMImplementation {
|
|||
let namespace = namespace_from_domstring(maybe_namespace.to_owned());
|
||||
|
||||
let content_type = match namespace {
|
||||
ns!(html) => Mime(
|
||||
TopLevel::Application,
|
||||
SubLevel::Ext("xhtml+xml".to_string()),
|
||||
vec![],
|
||||
),
|
||||
ns!(svg) => Mime(
|
||||
TopLevel::Image,
|
||||
SubLevel::Ext("svg+xml".to_string()),
|
||||
vec![],
|
||||
),
|
||||
_ => Mime(TopLevel::Application, SubLevel::Xml, vec![]),
|
||||
ns!(html) => "application/xhtml+xml".parse().unwrap(),
|
||||
ns!(svg) => mime::IMAGE_SVG,
|
||||
_ => "application/xml".parse().unwrap(),
|
||||
};
|
||||
|
||||
// Step 1.
|
||||
|
|
|
@ -17,13 +17,14 @@ use dom::messageevent::MessageEvent;
|
|||
use dom_struct::dom_struct;
|
||||
use euclid::Length;
|
||||
use fetch::FetchCanceller;
|
||||
use hyper::header::{Accept, qitem};
|
||||
use headers_ext::ContentType;
|
||||
use http::header::{self, HeaderName, HeaderValue};
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use js::conversions::ToJSValConvertible;
|
||||
use js::jsapi::JSAutoCompartment;
|
||||
use js::jsval::UndefinedValue;
|
||||
use mime::{Mime, TopLevel, SubLevel};
|
||||
use mime::{self, Mime};
|
||||
use net_traits::{CoreResourceMsg, FetchChannels, FetchMetadata};
|
||||
use net_traits::{FetchResponseMsg, FetchResponseListener, NetworkError};
|
||||
use net_traits::request::{CacheMode, CorsSettings, CredentialsMode};
|
||||
|
@ -39,7 +40,6 @@ use task_source::{TaskSource, TaskSourceName};
|
|||
use timers::OneshotTimerCallback;
|
||||
use utf8;
|
||||
|
||||
header! { (LastEventId, "Last-Event-ID") => [String] }
|
||||
|
||||
const DEFAULT_RECONNECTION_TIME: u64 = 5000;
|
||||
|
||||
|
@ -338,13 +338,14 @@ impl FetchResponseListener for EventSourceContext {
|
|||
};
|
||||
match meta.content_type {
|
||||
None => self.fail_the_connection(),
|
||||
Some(ct) => match ct.into_inner().0 {
|
||||
Mime(TopLevel::Text, SubLevel::EventStream, _) => {
|
||||
Some(ct) => {
|
||||
if <ContentType as Into<Mime>>::into(ct.into_inner()) == mime::TEXT_EVENT_STREAM {
|
||||
self.origin = meta.final_url.origin().ascii_serialization();
|
||||
self.announce_the_connection();
|
||||
},
|
||||
_ => self.fail_the_connection(),
|
||||
},
|
||||
} else {
|
||||
self.fail_the_connection()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_) => {
|
||||
|
@ -501,9 +502,8 @@ impl EventSource {
|
|||
..RequestInit::default()
|
||||
};
|
||||
// Step 10
|
||||
request
|
||||
.headers
|
||||
.set(Accept(vec![qitem(mime!(Text / EventStream))]));
|
||||
// TODO(eijebong): Replace once typed headers allow it
|
||||
request.headers.insert(header::ACCEPT, HeaderValue::from_static("text/event-stream"));
|
||||
// Step 11
|
||||
request.cache_mode = CacheMode::NoStore;
|
||||
// Step 12
|
||||
|
@ -613,9 +613,9 @@ impl EventSourceTimeoutCallback {
|
|||
let mut request = event_source.request();
|
||||
// Step 5.3
|
||||
if !event_source.last_event_id.borrow().is_empty() {
|
||||
request.headers.set(LastEventId(String::from(
|
||||
event_source.last_event_id.borrow().clone(),
|
||||
)));
|
||||
//TODO(eijebong): Change this once typed header support custom values
|
||||
request.headers.insert(HeaderName::from_static("last-event-id"),
|
||||
HeaderValue::from_str(&String::from(event_source.last_event_id.borrow().clone())).unwrap());
|
||||
}
|
||||
// Step 5.4
|
||||
global
|
||||
|
|
|
@ -22,13 +22,13 @@ use dom::globalscope::GlobalScope;
|
|||
use dom::progressevent::ProgressEvent;
|
||||
use dom_struct::dom_struct;
|
||||
use encoding_rs::{Encoding, UTF_8};
|
||||
use hyper::mime::{Attr, Mime};
|
||||
use js::jsapi::Heap;
|
||||
use js::jsapi::JSAutoCompartment;
|
||||
use js::jsapi::JSContext;
|
||||
use js::jsapi::JSObject;
|
||||
use js::jsval::{self, JSVal};
|
||||
use js::typedarray::{ArrayBuffer, CreateWith};
|
||||
use mime::{self, Mime};
|
||||
use servo_atoms::Atom;
|
||||
use std::cell::Cell;
|
||||
use std::ptr;
|
||||
|
@ -115,11 +115,10 @@ impl FileReaderSharedFunctionality {
|
|||
// Step 4 & 5
|
||||
encoding = encoding.or_else(|| {
|
||||
let resultmime = blob_type.parse::<Mime>().ok();
|
||||
resultmime.and_then(|Mime(_, _, ref parameters)| {
|
||||
parameters
|
||||
.iter()
|
||||
.find(|&&(ref k, _)| &Attr::Charset == k)
|
||||
.and_then(|&(_, ref v)| Encoding::for_label(v.as_str().as_bytes()))
|
||||
resultmime.and_then(|mime| {
|
||||
mime.params()
|
||||
.find(|(ref k, _)| &mime::CHARSET == k)
|
||||
.and_then(|(_, ref v)| Encoding::for_label(v.as_ref().as_bytes()))
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
@ -11,11 +11,11 @@ use dom::bindings::root::DomRoot;
|
|||
use dom::bindings::str::{ByteString, is_token};
|
||||
use dom::globalscope::GlobalScope;
|
||||
use dom_struct::dom_struct;
|
||||
use hyper::header::Headers as HyperHeaders;
|
||||
use mime::{Mime, TopLevel, SubLevel};
|
||||
use http::header::{self, HeaderMap as HyperHeaders, HeaderName, HeaderValue};
|
||||
use mime::{self, Mime};
|
||||
use std::cell::Cell;
|
||||
use std::result::Result;
|
||||
use std::str;
|
||||
use std::str::{self, FromStr};
|
||||
|
||||
#[dom_struct]
|
||||
pub struct Headers {
|
||||
|
@ -87,14 +87,14 @@ impl HeadersMethods for Headers {
|
|||
}
|
||||
// Step 7
|
||||
let mut combined_value: Vec<u8> = vec![];
|
||||
if let Some(v) = self.header_list.borrow().get_raw(&valid_name) {
|
||||
combined_value = v[0].clone();
|
||||
if let Some(v) = self.header_list.borrow().get(HeaderName::from_str(&valid_name).unwrap()) {
|
||||
combined_value = v.as_bytes().to_vec();
|
||||
combined_value.push(b',');
|
||||
}
|
||||
combined_value.extend(valid_value.iter().cloned());
|
||||
self.header_list
|
||||
.borrow_mut()
|
||||
.set_raw(valid_name, vec![combined_value]);
|
||||
.insert(HeaderName::from_str(&valid_name).unwrap(), HeaderValue::from_bytes(&combined_value).unwrap());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -121,19 +121,17 @@ impl HeadersMethods for Headers {
|
|||
return Ok(());
|
||||
}
|
||||
// Step 6
|
||||
self.header_list.borrow_mut().remove_raw(&valid_name);
|
||||
self.header_list.borrow_mut().remove(&valid_name);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#dom-headers-get
|
||||
fn Get(&self, name: ByteString) -> Fallible<Option<ByteString>> {
|
||||
// Step 1
|
||||
let valid_name = &validate_name(name)?;
|
||||
Ok(self
|
||||
.header_list
|
||||
.borrow()
|
||||
.get_raw(&valid_name)
|
||||
.map(|v| ByteString::new(v[0].clone())))
|
||||
let valid_name = validate_name(name)?;
|
||||
Ok(self.header_list.borrow().get(HeaderName::from_str(&valid_name).unwrap()).map(|v| {
|
||||
ByteString::new(v.as_bytes().to_vec())
|
||||
}))
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#dom-headers-has
|
||||
|
@ -141,7 +139,7 @@ impl HeadersMethods for Headers {
|
|||
// Step 1
|
||||
let valid_name = validate_name(name)?;
|
||||
// Step 2
|
||||
Ok(self.header_list.borrow_mut().get_raw(&valid_name).is_some())
|
||||
Ok(self.header_list.borrow_mut().get(&valid_name).is_some())
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#dom-headers-set
|
||||
|
@ -173,7 +171,7 @@ impl HeadersMethods for Headers {
|
|||
// https://fetch.spec.whatwg.org/#concept-header-list-set
|
||||
self.header_list
|
||||
.borrow_mut()
|
||||
.set_raw(valid_name, vec![valid_value]);
|
||||
.insert(HeaderName::from_str(&valid_name).unwrap(), HeaderValue::from_bytes(&valid_value).unwrap());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -184,10 +182,10 @@ impl Headers {
|
|||
match filler {
|
||||
// Step 1
|
||||
Some(HeadersInit::Headers(h)) => {
|
||||
for header in h.header_list.borrow().iter() {
|
||||
for (name, value) in h.header_list.borrow().iter() {
|
||||
self.Append(
|
||||
ByteString::new(Vec::from(header.name())),
|
||||
ByteString::new(Vec::from(header.value_string().into_bytes())),
|
||||
ByteString::new(Vec::from(name.as_str())),
|
||||
ByteString::new(Vec::from(value.to_str().unwrap().as_bytes()))
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
|
@ -248,26 +246,21 @@ impl Headers {
|
|||
}
|
||||
|
||||
pub fn get_headers_list(&self) -> HyperHeaders {
|
||||
let mut headers = HyperHeaders::new();
|
||||
headers.extend(self.header_list.borrow_mut().iter());
|
||||
headers
|
||||
self.header_list.borrow_mut().clone()
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-header-extract-mime-type
|
||||
pub fn extract_mime_type(&self) -> Vec<u8> {
|
||||
self.header_list
|
||||
.borrow()
|
||||
.get_raw("content-type")
|
||||
.map_or(vec![], |v| v[0].clone())
|
||||
self.header_list.borrow().get(header::CONTENT_TYPE).map_or(vec![], |v| v.as_bytes().to_owned())
|
||||
}
|
||||
|
||||
pub fn sort_header_list(&self) -> Vec<(String, String)> {
|
||||
let borrowed_header_list = self.header_list.borrow();
|
||||
let headers_iter = borrowed_header_list.iter();
|
||||
let mut header_vec = vec![];
|
||||
for header in headers_iter {
|
||||
let name = header.name().to_string();
|
||||
let value = header.value_string();
|
||||
for (name, value) in headers_iter {
|
||||
let name = name.as_str().to_owned();
|
||||
let value = value.to_str().unwrap().to_owned();
|
||||
let name_value = (name, value);
|
||||
header_vec.push(name_value);
|
||||
}
|
||||
|
@ -306,12 +299,14 @@ fn is_cors_safelisted_request_content_type(value: &[u8]) -> bool {
|
|||
let value_mime_result: Result<Mime, _> = value_string.parse();
|
||||
match value_mime_result {
|
||||
Err(_) => false,
|
||||
Ok(value_mime) => match value_mime {
|
||||
Mime(TopLevel::Application, SubLevel::WwwFormUrlEncoded, _) |
|
||||
Mime(TopLevel::Multipart, SubLevel::FormData, _) |
|
||||
Mime(TopLevel::Text, SubLevel::Plain, _) => true,
|
||||
_ => false,
|
||||
},
|
||||
Ok(value_mime) => {
|
||||
match (value_mime.type_(), value_mime.subtype()) {
|
||||
(mime::APPLICATION, mime::WWW_FORM_URLENCODED) |
|
||||
(mime::MULTIPART, mime::FORM_DATA) |
|
||||
(mime::TEXT, mime::PLAIN) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,9 +44,12 @@ use dom::virtualmethods::VirtualMethods;
|
|||
use dom::window::Window;
|
||||
use dom_struct::dom_struct;
|
||||
use encoding_rs::{Encoding, UTF_8};
|
||||
use headers_core::HeaderMapExt;
|
||||
use headers_ext::ContentType;
|
||||
use html5ever::{LocalName, Prefix};
|
||||
use hyper::header::{Charset, ContentDisposition, ContentType, DispositionParam, DispositionType};
|
||||
use hyper::method::Method;
|
||||
use hyper::Method;
|
||||
use mime::{self, Mime};
|
||||
use net_traits::http_percent_encode;
|
||||
use script_thread::MainThreadScriptMsg;
|
||||
use script_traits::LoadData;
|
||||
use servo_rand::random;
|
||||
|
@ -379,23 +382,15 @@ impl HTMLFormElement {
|
|||
// https://html.spec.whatwg.org/multipage/#submit-dialog
|
||||
},
|
||||
// https://html.spec.whatwg.org/multipage/#submit-mutate-action
|
||||
("http", FormMethod::FormGet) |
|
||||
("https", FormMethod::FormGet) |
|
||||
("data", FormMethod::FormGet) => {
|
||||
load_data.headers.set(ContentType::form_url_encoded());
|
||||
("http", FormMethod::FormGet) | ("https", FormMethod::FormGet) | ("data", FormMethod::FormGet) => {
|
||||
load_data.headers.typed_insert(ContentType::from(mime::APPLICATION_WWW_FORM_URLENCODED));
|
||||
self.mutate_action_url(&mut form_data, load_data, encoding, &target_window);
|
||||
},
|
||||
// https://html.spec.whatwg.org/multipage/#submit-body
|
||||
("http", FormMethod::FormPost) | ("https", FormMethod::FormPost) => {
|
||||
load_data.method = Method::Post;
|
||||
self.submit_entity_body(
|
||||
&mut form_data,
|
||||
load_data,
|
||||
enctype,
|
||||
encoding,
|
||||
&target_window,
|
||||
);
|
||||
},
|
||||
load_data.method = Method::POST;
|
||||
self.submit_entity_body(&mut form_data, load_data, enctype, encoding, &target_window);
|
||||
}
|
||||
// https://html.spec.whatwg.org/multipage/#submit-get-action
|
||||
("file", _) |
|
||||
("about", _) |
|
||||
|
@ -450,7 +445,7 @@ impl HTMLFormElement {
|
|||
let bytes = match enctype {
|
||||
FormEncType::UrlEncoded => {
|
||||
let charset = encoding.name();
|
||||
load_data.headers.set(ContentType::form_url_encoded());
|
||||
load_data.headers.typed_insert(ContentType::from(mime::APPLICATION_WWW_FORM_URLENCODED));
|
||||
|
||||
self.set_encoding_override(load_data.url.as_mut_url().query_pairs_mut())
|
||||
.clear()
|
||||
|
@ -463,12 +458,12 @@ impl HTMLFormElement {
|
|||
load_data.url.query().unwrap_or("").to_string().into_bytes()
|
||||
},
|
||||
FormEncType::FormDataEncoded => {
|
||||
let mime = mime!(Multipart / FormData; Boundary =(&boundary));
|
||||
load_data.headers.set(ContentType(mime));
|
||||
let mime: Mime = format!("multipart/form-data; boundary={}", boundary).parse().unwrap();
|
||||
load_data.headers.typed_insert(ContentType::from(mime));
|
||||
encode_multipart_form_data(form_data, boundary, encoding)
|
||||
},
|
||||
FormEncType::TextPlainEncoded => {
|
||||
load_data.headers.set(ContentType(mime!(Text / Plain)));
|
||||
load_data.headers.typed_insert(ContentType::from(mime::TEXT_PLAIN));
|
||||
self.encode_plaintext(form_data).into_bytes()
|
||||
},
|
||||
};
|
||||
|
@ -1231,40 +1226,30 @@ pub fn encode_multipart_form_data(
|
|||
// what spec says (that it should start with a '\r\n').
|
||||
let mut boundary_bytes = format!("--{}\r\n", boundary).into_bytes();
|
||||
result.append(&mut boundary_bytes);
|
||||
let mut content_disposition = ContentDisposition {
|
||||
disposition: DispositionType::Ext("form-data".to_owned()),
|
||||
parameters: vec![DispositionParam::Ext(
|
||||
"name".to_owned(),
|
||||
String::from(entry.name.clone()),
|
||||
)],
|
||||
};
|
||||
|
||||
// TODO(eijebong): Everthing related to content-disposition it to redo once typed headers
|
||||
// are capable of it.
|
||||
match entry.value {
|
||||
FormDatumValue::String(ref s) => {
|
||||
let content_disposition = format!("form-data; name=\"{}\"", entry.name);
|
||||
let mut bytes =
|
||||
format!("Content-Disposition: {}\r\n\r\n{}", content_disposition, s)
|
||||
.into_bytes();
|
||||
result.append(&mut bytes);
|
||||
},
|
||||
FormDatumValue::File(ref f) => {
|
||||
content_disposition
|
||||
.parameters
|
||||
.push(DispositionParam::Filename(
|
||||
Charset::Ext(String::from(charset.clone())),
|
||||
None,
|
||||
f.name().clone().into(),
|
||||
));
|
||||
let extra = if charset.to_lowercase() == "utf-8" {
|
||||
format!("filename=\"{}\"", String::from_utf8(f.name().as_bytes().into()).unwrap())
|
||||
} else {
|
||||
format!("filename*=\"{}\"''{}", charset, http_percent_encode(f.name().as_bytes()))
|
||||
};
|
||||
|
||||
let content_disposition = format!("form-data; name=\"{}\"; {}", entry.name, extra);
|
||||
// https://tools.ietf.org/html/rfc7578#section-4.4
|
||||
let content_type = ContentType(
|
||||
f.upcast::<Blob>()
|
||||
.Type()
|
||||
.parse()
|
||||
.unwrap_or(mime!(Text / Plain)),
|
||||
);
|
||||
let mut type_bytes = format!(
|
||||
"Content-Disposition: {}\r\ncontent-type: {}\r\n\r\n",
|
||||
content_disposition, content_type
|
||||
).into_bytes();
|
||||
let content_type: Mime = f.upcast::<Blob>().Type().parse().unwrap_or(mime::TEXT_PLAIN);
|
||||
let mut type_bytes = format!("Content-Disposition: {}\r\ncontent-type: {}\r\n\r\n",
|
||||
content_disposition,
|
||||
content_type).into_bytes();
|
||||
result.append(&mut type_bytes);
|
||||
|
||||
let mut bytes = f.upcast::<Blob>().get_bytes().unwrap_or(vec![]);
|
||||
|
|
|
@ -44,7 +44,7 @@ use html5ever::{LocalName, Prefix};
|
|||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use microtask::{Microtask, MicrotaskRunnable};
|
||||
use mime::{Mime, TopLevel, SubLevel};
|
||||
use mime::{self, Mime};
|
||||
use net_traits::{FetchResponseListener, FetchMetadata, NetworkError, FetchResponseMsg};
|
||||
use net_traits::image::base::{Image, ImageMetadata};
|
||||
use net_traits::image_cache::{CanRequestImages, ImageCache, ImageOrMetadataAvailable};
|
||||
|
@ -180,13 +180,9 @@ impl FetchResponseListener for ImageContext {
|
|||
// Step 14.5 of https://html.spec.whatwg.org/multipage/#img-environment-changes
|
||||
if let Some(metadata) = metadata.as_ref() {
|
||||
if let Some(ref content_type) = metadata.content_type {
|
||||
match content_type.clone().into_inner().0 {
|
||||
Mime(TopLevel::Multipart, SubLevel::Ext(s), _) => {
|
||||
if s == "x-mixed-replace" {
|
||||
self.aborted.set(true);
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
let mime: Mime = content_type.clone().into_inner().into();
|
||||
if mime.type_() == mime::MULTIPART && mime.subtype().as_str() == "x-mixed-replace" {
|
||||
self.aborted.set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -570,11 +566,12 @@ impl HTMLImageElement {
|
|||
// TODO Handle unsupported mime type
|
||||
let mime = x.value().parse::<Mime>();
|
||||
match mime {
|
||||
Ok(m) => match m {
|
||||
Mime(TopLevel::Image, _, _) => (),
|
||||
_ => continue,
|
||||
},
|
||||
_ => continue,
|
||||
Ok(m) =>
|
||||
match m.type_() {
|
||||
mime::IMAGE => (),
|
||||
_ => continue
|
||||
},
|
||||
_ => continue
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,12 +34,14 @@ use dom::promise::Promise;
|
|||
use dom::virtualmethods::VirtualMethods;
|
||||
use dom_struct::dom_struct;
|
||||
use fetch::FetchCanceller;
|
||||
use headers_core::HeaderMapExt;
|
||||
use headers_ext::ContentLength;
|
||||
use html5ever::{LocalName, Prefix};
|
||||
use hyper::header::{ByteRangeSpec, ContentLength, Headers, Range as HyperRange};
|
||||
use http::header::{self, HeaderMap, HeaderValue};
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use microtask::{Microtask, MicrotaskRunnable};
|
||||
use mime::{Mime, SubLevel, TopLevel};
|
||||
use mime::{self, Mime};
|
||||
use net_traits::{CoreResourceMsg, FetchChannels, FetchResponseListener, FetchMetadata, Metadata};
|
||||
use net_traits::NetworkError;
|
||||
use net_traits::request::{CredentialsMode, Destination, RequestInit};
|
||||
|
@ -686,10 +688,9 @@ impl HTMLMediaElement {
|
|||
HTMLMediaElementTypeId::HTMLAudioElement => Destination::Audio,
|
||||
HTMLMediaElementTypeId::HTMLVideoElement => Destination::Video,
|
||||
};
|
||||
let mut headers = Headers::new();
|
||||
headers.set(HyperRange::Bytes(vec![ByteRangeSpec::AllFrom(
|
||||
offset.unwrap_or(0),
|
||||
)]));
|
||||
let mut headers = HeaderMap::new();
|
||||
// FIXME(eijebong): Use typed headers once we have a constructor for the range header
|
||||
headers.insert(header::RANGE, HeaderValue::from_str(&format!("bytes={}-", offset.unwrap_or(0))).unwrap());
|
||||
let request = RequestInit {
|
||||
url: self.resource_url.borrow().as_ref().unwrap().clone(),
|
||||
headers,
|
||||
|
@ -1271,7 +1272,10 @@ impl HTMLMediaElementMethods for HTMLMediaElement {
|
|||
// https://html.spec.whatwg.org/multipage/#dom-navigator-canplaytype
|
||||
fn CanPlayType(&self, type_: DOMString) -> CanPlayTypeResult {
|
||||
match type_.parse::<Mime>() {
|
||||
Ok(Mime(TopLevel::Application, SubLevel::OctetStream, _)) | Err(_) => {
|
||||
Ok(ref mime) if (mime.type_() == mime::APPLICATION && mime.subtype() == mime::OCTET_STREAM) => {
|
||||
CanPlayTypeResult::_empty
|
||||
},
|
||||
Err(_) => {
|
||||
CanPlayTypeResult::_empty
|
||||
},
|
||||
_ => CanPlayTypeResult::Maybe,
|
||||
|
@ -1464,8 +1468,8 @@ impl FetchResponseListener for HTMLMediaElementContext {
|
|||
|
||||
if let Some(metadata) = self.metadata.as_ref() {
|
||||
if let Some(headers) = metadata.headers.as_ref() {
|
||||
if let Some(content_length) = headers.get::<ContentLength>() {
|
||||
if let Err(e) = self.elem.root().player.set_input_size(**content_length) {
|
||||
if let Some(content_length) = headers.typed_get::<ContentLength>() {
|
||||
if let Err(e) = self.elem.root().player.set_input_size(content_length.0) {
|
||||
eprintln!("Could not set player input size {:?}", e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ use dom::headers::{Guard, Headers};
|
|||
use dom::promise::Promise;
|
||||
use dom::xmlhttprequest::Extractable;
|
||||
use dom_struct::dom_struct;
|
||||
use hyper::method::Method as HttpMethod;
|
||||
use http::Method as HttpMethod;
|
||||
use http::method::InvalidMethod;
|
||||
use net_traits::ReferrerPolicy as MsgReferrerPolicy;
|
||||
use net_traits::request::{Origin, Window};
|
||||
use net_traits::request::CacheMode as NetTraitsRequestCache;
|
||||
|
@ -38,6 +39,7 @@ use net_traits::request::RequestMode as NetTraitsRequestMode;
|
|||
use servo_url::ServoUrl;
|
||||
use std::cell::{Cell, Ref};
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct Request {
|
||||
|
@ -283,7 +285,7 @@ impl Request {
|
|||
}
|
||||
// Step 25.2
|
||||
let method = match init_method.as_str() {
|
||||
Some(s) => normalize_method(s),
|
||||
Some(s) => normalize_method(s).map_err(|e| Error::Type(format!("Method is not valid: {:?}", e)))?,
|
||||
None => return Err(Error::Type("Method is not a valid UTF8".to_string())),
|
||||
};
|
||||
// Step 25.3
|
||||
|
@ -373,16 +375,10 @@ impl Request {
|
|||
let req = r.request.borrow();
|
||||
let req_method = &req.method;
|
||||
match *req_method {
|
||||
HttpMethod::Get => {
|
||||
return Err(Error::Type(
|
||||
"Init's body is non-null, and request method is GET".to_string(),
|
||||
))
|
||||
},
|
||||
HttpMethod::Head => {
|
||||
return Err(Error::Type(
|
||||
"Init's body is non-null, and request method is HEAD".to_string(),
|
||||
))
|
||||
},
|
||||
HttpMethod::GET => return Err(Error::Type(
|
||||
"Init's body is non-null, and request method is GET".to_string())),
|
||||
HttpMethod::HEAD => return Err(Error::Type(
|
||||
"Init's body is non-null, and request method is HEAD".to_string())),
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
@ -473,17 +469,18 @@ fn net_request_from_global(global: &GlobalScope, url: ServoUrl) -> NetTraitsRequ
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-method-normalize
|
||||
fn normalize_method(m: &str) -> HttpMethod {
|
||||
fn normalize_method(m: &str) -> Result<HttpMethod, InvalidMethod> {
|
||||
match_ignore_ascii_case! { m,
|
||||
"delete" => return HttpMethod::Delete,
|
||||
"get" => return HttpMethod::Get,
|
||||
"head" => return HttpMethod::Head,
|
||||
"options" => return HttpMethod::Options,
|
||||
"post" => return HttpMethod::Post,
|
||||
"put" => return HttpMethod::Put,
|
||||
"delete" => return Ok(HttpMethod::DELETE),
|
||||
"get" => return Ok(HttpMethod::GET),
|
||||
"head" => return Ok(HttpMethod::HEAD),
|
||||
"options" => return Ok(HttpMethod::OPTIONS),
|
||||
"post" => return Ok(HttpMethod::POST),
|
||||
"put" => return Ok(HttpMethod::PUT),
|
||||
_ => (),
|
||||
}
|
||||
HttpMethod::Extension(m.to_string())
|
||||
debug!("Method: {:?}", m);
|
||||
HttpMethod::from_str(m)
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-method
|
||||
|
@ -503,7 +500,9 @@ fn is_forbidden_method(m: &ByteString) -> bool {
|
|||
|
||||
// https://fetch.spec.whatwg.org/#cors-safelisted-method
|
||||
fn is_cors_safelisted_method(m: &HttpMethod) -> bool {
|
||||
m == &HttpMethod::Get || m == &HttpMethod::Head || m == &HttpMethod::Post
|
||||
m == &HttpMethod::GET ||
|
||||
m == &HttpMethod::HEAD ||
|
||||
m == &HttpMethod::POST
|
||||
}
|
||||
|
||||
// https://url.spec.whatwg.org/#include-credentials
|
||||
|
|
|
@ -18,8 +18,8 @@ use dom::headers::{is_vchar, is_obs_text};
|
|||
use dom::promise::Promise;
|
||||
use dom::xmlhttprequest::Extractable;
|
||||
use dom_struct::dom_struct;
|
||||
use hyper::header::Headers as HyperHeaders;
|
||||
use hyper::status::StatusCode;
|
||||
use http::header::HeaderMap as HyperHeaders;
|
||||
use hyper::StatusCode;
|
||||
use hyper_serde::Serde;
|
||||
use net_traits::response::{ResponseBody as NetTraitsResponseBody};
|
||||
use servo_url::ServoUrl;
|
||||
|
@ -55,7 +55,7 @@ impl Response {
|
|||
headers_reflector: Default::default(),
|
||||
mime_type: DomRefCell::new("".to_string().into_bytes()),
|
||||
body_used: Cell::new(false),
|
||||
status: DomRefCell::new(Some(StatusCode::Ok)),
|
||||
status: DomRefCell::new(Some(StatusCode::OK)),
|
||||
raw_status: DomRefCell::new(Some((200, b"OK".to_vec()))),
|
||||
response_type: DomRefCell::new(DOMResponseType::Default),
|
||||
url: DomRefCell::new(None),
|
||||
|
@ -99,7 +99,7 @@ impl Response {
|
|||
let r = Response::new(global);
|
||||
|
||||
// Step 4
|
||||
*r.status.borrow_mut() = Some(StatusCode::from_u16(init.status));
|
||||
*r.status.borrow_mut() = Some(StatusCode::from_u16(init.status).unwrap());
|
||||
|
||||
// Step 5
|
||||
*r.raw_status.borrow_mut() = Some((init.status, init.statusText.clone().into()));
|
||||
|
@ -189,7 +189,7 @@ impl Response {
|
|||
let r = Response::new(global);
|
||||
|
||||
// Step 5
|
||||
*r.status.borrow_mut() = Some(StatusCode::from_u16(status));
|
||||
*r.status.borrow_mut() = Some(StatusCode::from_u16(status).unwrap());
|
||||
*r.raw_status.borrow_mut() = Some((status, b"".to_vec()));
|
||||
|
||||
// Step 6
|
||||
|
@ -300,7 +300,7 @@ impl ResponseMethods for Response {
|
|||
fn Ok(&self) -> bool {
|
||||
match *self.status.borrow() {
|
||||
Some(s) => {
|
||||
let status_num = s.to_u16();
|
||||
let status_num = s.as_u16();
|
||||
return status_num >= 200 && status_num <= 299;
|
||||
},
|
||||
None => false,
|
||||
|
|
|
@ -35,9 +35,8 @@ use html5ever::{Attribute, ExpandedName, LocalName, QualName};
|
|||
use html5ever::buffer_queue::BufferQueue;
|
||||
use html5ever::tendril::{StrTendril, ByteTendril, IncompleteUtf8};
|
||||
use html5ever::tree_builder::{NodeOrText, TreeSink, NextParserState, QuirksMode, ElementFlags};
|
||||
use hyper::header::ContentType;
|
||||
use hyper::mime::{Mime, SubLevel, TopLevel};
|
||||
use hyper_serde::Serde;
|
||||
use mime::{self, Mime};
|
||||
use msg::constellation_msg::PipelineId;
|
||||
use net_traits::{FetchMetadata, FetchResponseListener, Metadata, NetworkError};
|
||||
use network_listener::PreInvoke;
|
||||
|
@ -697,10 +696,11 @@ impl FetchResponseListener for ParserContext {
|
|||
},
|
||||
Err(_) => None,
|
||||
};
|
||||
let content_type = metadata
|
||||
let content_type: Option<Mime> = metadata
|
||||
.clone()
|
||||
.and_then(|meta| meta.content_type)
|
||||
.map(Serde::into_inner);
|
||||
.map(Serde::into_inner)
|
||||
.map(Into::into);
|
||||
let parser = match ScriptThread::page_headers_available(&self.id, metadata) {
|
||||
Some(parser) => parser,
|
||||
None => return,
|
||||
|
@ -712,7 +712,7 @@ impl FetchResponseListener for ParserContext {
|
|||
self.parser = Some(Trusted::new(&*parser));
|
||||
|
||||
match content_type {
|
||||
Some(ContentType(Mime(TopLevel::Image, _, _))) => {
|
||||
Some(ref mime) if mime.type_() == mime::IMAGE => {
|
||||
self.is_synthesized_document = true;
|
||||
let page = "<html><body></body></html>".into();
|
||||
parser.push_string_input_chunk(page);
|
||||
|
@ -725,14 +725,14 @@ impl FetchResponseListener for ParserContext {
|
|||
doc_body.AppendChild(&DomRoot::upcast::<Node>(img)).expect("Appending failed");
|
||||
|
||||
},
|
||||
Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => {
|
||||
Some(ref mime) if mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN => {
|
||||
// https://html.spec.whatwg.org/multipage/#read-text
|
||||
let page = "<pre>\n".into();
|
||||
parser.push_string_input_chunk(page);
|
||||
parser.parse_sync();
|
||||
parser.tokenizer.borrow_mut().set_plaintext_state();
|
||||
},
|
||||
Some(ContentType(Mime(TopLevel::Text, SubLevel::Html, _))) => {
|
||||
Some(ref mime) if mime.type_() == mime::TEXT && mime.subtype() == mime::HTML => {
|
||||
// Handle text/html
|
||||
if let Some(reason) = ssl_error {
|
||||
self.is_synthesized_document = true;
|
||||
|
@ -749,15 +749,18 @@ impl FetchResponseListener for ParserContext {
|
|||
parser.parse_sync();
|
||||
}
|
||||
},
|
||||
Some(ContentType(Mime(TopLevel::Text, SubLevel::Xml, _))) | // Handle text/xml, application/xml
|
||||
Some(ContentType(Mime(TopLevel::Application, SubLevel::Xml, _))) => {},
|
||||
Some(ContentType(Mime(TopLevel::Application, SubLevel::Ext(ref sub), _)))
|
||||
if sub.as_str() == "xhtml+xml".to_owned() => {}, // Handle xhtml (application/xhtml+xml)
|
||||
Some(ContentType(Mime(toplevel, sublevel, _))) => {
|
||||
// Handle text/xml, application/xml
|
||||
Some(ref mime) if (mime.type_() == mime::TEXT && mime.subtype() == mime::XML) ||
|
||||
(mime.type_() == mime::APPLICATION && mime.subtype() == mime::XML) => {},
|
||||
Some(ref mime) if mime.type_() == mime::APPLICATION &&
|
||||
mime.subtype().as_str() == "xhtml" &&
|
||||
mime.suffix() == Some(mime::XML)
|
||||
=> {}, // Handle xhtml (application/xhtml+xml)
|
||||
Some(ref mime) => {
|
||||
// Show warning page for unknown mime types.
|
||||
let page = format!("<html><body><p>Unknown content type ({}/{}).</p></body></html>",
|
||||
toplevel.as_str(),
|
||||
sublevel.as_str());
|
||||
mime.type_().as_str(),
|
||||
mime.subtype().as_str());
|
||||
self.is_synthesized_document = true;
|
||||
parser.push_string_input_chunk(page);
|
||||
parser.parse_sync();
|
||||
|
|
|
@ -39,12 +39,12 @@ use dom_struct::dom_struct;
|
|||
use encoding_rs::{Encoding, UTF_8};
|
||||
use euclid::Length;
|
||||
use fetch::FetchCanceller;
|
||||
use headers_core::HeaderMapExt;
|
||||
use headers_ext::{ContentLength, ContentType};
|
||||
use html5ever::serialize;
|
||||
use html5ever::serialize::SerializeOpts;
|
||||
use hyper::header::{ContentLength, ContentType, ContentEncoding};
|
||||
use hyper::header::Headers;
|
||||
use hyper::method::Method;
|
||||
use hyper::mime::{self, Attr as MimeAttr, Mime, Value as MimeValue};
|
||||
use http::header::{self, HeaderMap, HeaderName, HeaderValue};
|
||||
use hyper::Method;
|
||||
use hyper_serde::Serde;
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
|
@ -53,6 +53,7 @@ use js::jsapi::JS_ClearPendingException;
|
|||
use js::jsval::{JSVal, NullValue, UndefinedValue};
|
||||
use js::rust::wrappers::JS_ParseJSON;
|
||||
use js::typedarray::{ArrayBuffer, CreateWith};
|
||||
use mime::{self, Mime, Name};
|
||||
use net_traits::{FetchChannels, FetchMetadata, FilteredMetadata};
|
||||
use net_traits::{FetchResponseListener, NetworkError, ReferrerPolicy};
|
||||
use net_traits::CoreResourceMsg::Fetch;
|
||||
|
@ -68,7 +69,7 @@ use std::default::Default;
|
|||
use std::ptr;
|
||||
use std::ptr::NonNull;
|
||||
use std::slice;
|
||||
use std::str;
|
||||
use std::str::{self, FromStr};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use task_source::TaskSourceName;
|
||||
use task_source::networking::NetworkingTaskSource;
|
||||
|
@ -100,7 +101,7 @@ struct XHRContext {
|
|||
#[derive(Clone)]
|
||||
pub enum XHRProgress {
|
||||
/// Notify that headers have been received
|
||||
HeadersReceived(GenerationId, Option<Headers>, Option<(u16, Vec<u8>)>),
|
||||
HeadersReceived(GenerationId, Option<HeaderMap>, Option<(u16, Vec<u8>)>),
|
||||
/// Partial progress (after receiving headers), containing portion of the response
|
||||
Loading(GenerationId, ByteString),
|
||||
/// Loading is done
|
||||
|
@ -138,7 +139,7 @@ pub struct XMLHttpRequest {
|
|||
#[ignore_malloc_size_of = "Defined in rust-mozjs"]
|
||||
response_json: Heap<JSVal>,
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
response_headers: DomRefCell<Headers>,
|
||||
response_headers: DomRefCell<HeaderMap>,
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
override_mime_type: DomRefCell<Option<Mime>>,
|
||||
override_charset: DomRefCell<Option<&'static Encoding>>,
|
||||
|
@ -148,7 +149,7 @@ pub struct XMLHttpRequest {
|
|||
request_method: DomRefCell<Method>,
|
||||
request_url: DomRefCell<Option<ServoUrl>>,
|
||||
#[ignore_malloc_size_of = "Defined in hyper"]
|
||||
request_headers: DomRefCell<Headers>,
|
||||
request_headers: DomRefCell<HeaderMap>,
|
||||
request_body_len: Cell<usize>,
|
||||
sync: Cell<bool>,
|
||||
upload_complete: Cell<bool>,
|
||||
|
@ -188,13 +189,13 @@ impl XMLHttpRequest {
|
|||
response_blob: Default::default(),
|
||||
response_arraybuffer: Heap::default(),
|
||||
response_json: Heap::default(),
|
||||
response_headers: DomRefCell::new(Headers::new()),
|
||||
response_headers: DomRefCell::new(HeaderMap::new()),
|
||||
override_mime_type: DomRefCell::new(None),
|
||||
override_charset: DomRefCell::new(None),
|
||||
|
||||
request_method: DomRefCell::new(Method::Get),
|
||||
request_method: DomRefCell::new(Method::GET),
|
||||
request_url: DomRefCell::new(None),
|
||||
request_headers: DomRefCell::new(Headers::new()),
|
||||
request_headers: DomRefCell::new(HeaderMap::new()),
|
||||
request_body_len: Cell::new(0),
|
||||
sync: Cell::new(false),
|
||||
upload_complete: Cell::new(false),
|
||||
|
@ -347,8 +348,8 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
|
||||
match maybe_method {
|
||||
// Step 4
|
||||
Some(Method::Connect) | Some(Method::Trace) => Err(Error::Security),
|
||||
Some(Method::Extension(ref t)) if &**t == "TRACK" => Err(Error::Security),
|
||||
Some(Method::CONNECT) | Some(Method::TRACE) => Err(Error::Security),
|
||||
Some(ref t) if t.as_str() == "TRACK" => Err(Error::Security),
|
||||
Some(parsed_method) => {
|
||||
// Step 3
|
||||
if !is_token(&method) {
|
||||
|
@ -395,7 +396,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
*self.request_method.borrow_mut() = parsed_method;
|
||||
*self.request_url.borrow_mut() = Some(parsed_url);
|
||||
self.sync.set(!async);
|
||||
*self.request_headers.borrow_mut() = Headers::new();
|
||||
*self.request_headers.borrow_mut() = HeaderMap::new();
|
||||
self.send_flag.set(false);
|
||||
*self.status_text.borrow_mut() = ByteString::new(vec![]);
|
||||
self.status.set(0);
|
||||
|
@ -450,19 +451,17 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
let mut headers = self.request_headers.borrow_mut();
|
||||
|
||||
// Step 6
|
||||
let value = match headers.get_raw(name_str) {
|
||||
let value = match headers.get(name_str).map(HeaderValue::as_bytes) {
|
||||
Some(raw) => {
|
||||
debug!("SetRequestHeader: old value = {:?}", raw[0]);
|
||||
let mut buf = raw[0].clone();
|
||||
let mut buf = raw.to_vec();
|
||||
buf.extend_from_slice(b", ");
|
||||
buf.extend_from_slice(value);
|
||||
debug!("SetRequestHeader: new value = {:?}", buf);
|
||||
buf
|
||||
},
|
||||
None => value.into(),
|
||||
};
|
||||
|
||||
headers.set_raw(name_str.to_owned(), vec![value]);
|
||||
headers.insert(HeaderName::from_str(name_str).unwrap(), HeaderValue::from_bytes(&value).unwrap());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -532,8 +531,8 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
|
||||
// Step 3
|
||||
let data = match *self.request_method.borrow() {
|
||||
Method::Get | Method::Head => None,
|
||||
_ => data,
|
||||
Method::GET | Method::HEAD => None,
|
||||
_ => data
|
||||
};
|
||||
// Step 4 (first half)
|
||||
let extracted_or_serialized = match data {
|
||||
|
@ -638,30 +637,46 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
// XHR spec differs from http, and says UTF-8 should be in capitals,
|
||||
// instead of "utf-8", which is what Hyper defaults to. So not
|
||||
// using content types provided by Hyper.
|
||||
{
|
||||
Some(MimeValue::Ext("UTF-8".to_string()))
|
||||
},
|
||||
Some("UTF-8"),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let mut content_type_set = false;
|
||||
if let Some(ref ct) = *content_type {
|
||||
if !request.headers.has::<ContentType>() {
|
||||
request
|
||||
.headers
|
||||
.set_raw("content-type", vec![ct.bytes().collect()]);
|
||||
if !request.headers.contains_key(header::CONTENT_TYPE) {
|
||||
request.headers.insert(header::CONTENT_TYPE, HeaderValue::from_str(ct).unwrap());
|
||||
content_type_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !content_type_set {
|
||||
let ct = request.headers.get_mut::<ContentType>();
|
||||
let ct = request.headers.typed_get::<ContentType>();
|
||||
if let Some(ct) = ct {
|
||||
if let Some(encoding) = encoding {
|
||||
for param in &mut (ct.0).2 {
|
||||
if param.0 == MimeAttr::Charset {
|
||||
if !param.0.as_str().eq_ignore_ascii_case(encoding.as_str()) {
|
||||
*param = (MimeAttr::Charset, encoding.clone());
|
||||
let mime: Mime = ct.into();
|
||||
for param in mime.params() {
|
||||
if param.0 == mime::CHARSET {
|
||||
if !param.1.as_ref().eq_ignore_ascii_case(encoding) {
|
||||
let new_params: Vec<(Name, Name)> =
|
||||
mime.params()
|
||||
.filter(|p| p.0 != mime::CHARSET)
|
||||
.map(|p| (p.0, p.1))
|
||||
.collect();
|
||||
|
||||
let new_mime =
|
||||
format!("{}/{}; charset={}{}{}",
|
||||
mime.type_().as_ref(),
|
||||
mime.subtype().as_ref(),
|
||||
encoding,
|
||||
if new_params.is_empty() { "" } else { "; " },
|
||||
new_params
|
||||
.iter()
|
||||
.map(|p| format!("{}={}", p.0, p.1))
|
||||
.collect::<Vec<String>>()
|
||||
.join("; ")
|
||||
);
|
||||
let new_mime: Mime = new_mime.parse().unwrap();
|
||||
request.headers.typed_insert(ContentType::from(new_mime))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -672,8 +687,6 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
_ => (),
|
||||
}
|
||||
|
||||
debug!("request.headers = {:?}", request.headers);
|
||||
|
||||
self.fetch_time.set(time::now().to_timespec().sec);
|
||||
|
||||
let rv = self.fetch(request, &self.global());
|
||||
|
@ -728,15 +741,48 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
|
||||
// https://xhr.spec.whatwg.org/#the-getresponseheader()-method
|
||||
fn GetResponseHeader(&self, name: ByteString) -> Option<ByteString> {
|
||||
self.filter_response_headers()
|
||||
.iter()
|
||||
.find(|h| name.eq_ignore_case(&h.name().parse().unwrap()))
|
||||
.map(|h| ByteString::new(h.value_string().into_bytes()))
|
||||
let headers = self.filter_response_headers();
|
||||
let headers = headers.get_all(HeaderName::from_str(&name.as_str()?.to_lowercase()).ok()?);
|
||||
let mut first = true;
|
||||
let s = headers.iter()
|
||||
.fold(Vec::new(), |mut vec, value| {
|
||||
if !first {
|
||||
vec.extend(", ".as_bytes());
|
||||
}
|
||||
first = false;
|
||||
vec.extend(value.as_bytes());
|
||||
vec
|
||||
});
|
||||
|
||||
// There was no header with that name so we never got to change that value
|
||||
if first {
|
||||
None
|
||||
} else {
|
||||
Some(ByteString::new(s))
|
||||
}
|
||||
}
|
||||
|
||||
// https://xhr.spec.whatwg.org/#the-getallresponseheaders()-method
|
||||
fn GetAllResponseHeaders(&self) -> ByteString {
|
||||
ByteString::new(self.filter_response_headers().to_string().into_bytes())
|
||||
let headers = self.filter_response_headers();
|
||||
let keys = headers.keys();
|
||||
let v = keys.fold(Vec::new(), |mut vec, k| {
|
||||
let values = headers.get_all(k);
|
||||
vec.extend(k.as_str().as_bytes());
|
||||
vec.extend(": ".as_bytes());
|
||||
let mut first = true;
|
||||
for value in values {
|
||||
if !first {
|
||||
vec.extend(", ".as_bytes());
|
||||
first = false;
|
||||
}
|
||||
vec.extend(value.as_bytes());
|
||||
}
|
||||
vec.extend("\r\n".as_bytes());
|
||||
vec
|
||||
});
|
||||
|
||||
ByteString::new(v)
|
||||
}
|
||||
|
||||
// https://xhr.spec.whatwg.org/#the-overridemimetype()-method
|
||||
|
@ -751,12 +797,20 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
|
|||
// Step 2
|
||||
let override_mime = mime.parse::<Mime>().map_err(|_| Error::Syntax)?;
|
||||
// Step 3
|
||||
let mime_no_params = Mime(override_mime.clone().0, override_mime.clone().1, vec![]);
|
||||
let mime_str = override_mime.as_ref();
|
||||
let mime_parts: Vec<&str> = mime_str.split(";").collect();
|
||||
let mime_no_params = if mime_parts.len() > 1 {
|
||||
mime_parts[0].parse().unwrap()
|
||||
} else {
|
||||
override_mime.clone()
|
||||
};
|
||||
|
||||
*self.override_mime_type.borrow_mut() = Some(mime_no_params);
|
||||
// Step 4
|
||||
let value = override_mime.get_param(mime::Attr::Charset);
|
||||
*self.override_charset.borrow_mut() =
|
||||
value.and_then(|value| Encoding::for_label(value.as_bytes()));
|
||||
let value = override_mime.get_param(mime::CHARSET);
|
||||
*self.override_charset.borrow_mut() = value.and_then(|value| {
|
||||
Encoding::for_label(value.as_ref().as_bytes())
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1077,20 +1131,17 @@ impl XMLHttpRequest {
|
|||
|
||||
fn dispatch_progress_event(&self, upload: bool, type_: Atom, loaded: u64, total: Option<u64>) {
|
||||
let (total_length, length_computable) =
|
||||
if self.response_headers.borrow().has::<ContentEncoding>() {
|
||||
if self.response_headers.borrow().contains_key(header::CONTENT_ENCODING) {
|
||||
(0, false)
|
||||
} else {
|
||||
(total.unwrap_or(0), total.is_some())
|
||||
};
|
||||
let progressevent = ProgressEvent::new(
|
||||
&self.global(),
|
||||
type_,
|
||||
EventBubbles::DoesNotBubble,
|
||||
EventCancelable::NotCancelable,
|
||||
length_computable,
|
||||
loaded,
|
||||
total_length,
|
||||
);
|
||||
let progressevent = ProgressEvent::new(&self.global(),
|
||||
type_,
|
||||
EventBubbles::DoesNotBubble,
|
||||
EventCancelable::NotCancelable,
|
||||
length_computable, loaded,
|
||||
total_length);
|
||||
let target = if upload {
|
||||
self.upload.upcast()
|
||||
} else {
|
||||
|
@ -1108,13 +1159,10 @@ impl XMLHttpRequest {
|
|||
|
||||
fn dispatch_response_progress_event(&self, type_: Atom) {
|
||||
let len = self.response.borrow().len() as u64;
|
||||
let total = self
|
||||
.response_headers
|
||||
.borrow()
|
||||
.get::<ContentLength>()
|
||||
.map(|x| **x as u64);
|
||||
let total = self.response_headers.borrow().typed_get::<ContentLength>().map(|v| v.0);
|
||||
self.dispatch_progress_event(false, type_, len, total);
|
||||
}
|
||||
|
||||
fn set_timeout(&self, duration_ms: u32) {
|
||||
// Sets up the object to timeout in a given number of milliseconds
|
||||
// This will cancel all previous timeouts
|
||||
|
@ -1154,11 +1202,7 @@ impl XMLHttpRequest {
|
|||
return response;
|
||||
}
|
||||
// Step 2
|
||||
let mime = self
|
||||
.final_mime_type()
|
||||
.as_ref()
|
||||
.map(Mime::to_string)
|
||||
.unwrap_or("".to_owned());
|
||||
let mime = self.final_mime_type().as_ref().map(|m| m.to_string()).unwrap_or("".to_owned());
|
||||
|
||||
// Step 3, 4
|
||||
let bytes = self.response.borrow().to_vec();
|
||||
|
@ -1200,7 +1244,7 @@ impl XMLHttpRequest {
|
|||
let charset = self.final_charset().unwrap_or(UTF_8);
|
||||
let temp_doc: DomRoot<Document>;
|
||||
match mime_type {
|
||||
Some(Mime(mime::TopLevel::Text, mime::SubLevel::Html, _)) => {
|
||||
Some(ref mime) if mime.type_() == mime::TEXT && mime.subtype() == mime::HTML => {
|
||||
// Step 5
|
||||
if self.response_type.get() == XMLHttpRequestResponseType::_empty {
|
||||
return None;
|
||||
|
@ -1210,17 +1254,15 @@ impl XMLHttpRequest {
|
|||
}
|
||||
},
|
||||
// Step 7
|
||||
Some(Mime(mime::TopLevel::Text, mime::SubLevel::Xml, _)) |
|
||||
Some(Mime(mime::TopLevel::Application, mime::SubLevel::Xml, _)) |
|
||||
Some(ref mime) if (mime.type_() == mime::TEXT && mime.subtype() == mime::XML) ||
|
||||
(mime.type_() == mime::APPLICATION && mime.subtype() == mime::XML) => {
|
||||
temp_doc = self.handle_xml();
|
||||
},
|
||||
None => {
|
||||
temp_doc = self.handle_xml();
|
||||
},
|
||||
Some(Mime(_, mime::SubLevel::Ext(sub), _)) => {
|
||||
if sub.ends_with("+xml") {
|
||||
temp_doc = self.handle_xml();
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
Some(ref mime) if mime.suffix() == Some(mime::XML) => {
|
||||
temp_doc = self.handle_xml();
|
||||
},
|
||||
// Step 4
|
||||
_ => {
|
||||
|
@ -1336,34 +1378,13 @@ impl XMLHttpRequest {
|
|||
)
|
||||
}
|
||||
|
||||
fn filter_response_headers(&self) -> Headers {
|
||||
fn filter_response_headers(&self) -> HeaderMap {
|
||||
// https://fetch.spec.whatwg.org/#concept-response-header-list
|
||||
use hyper::error::Result;
|
||||
use hyper::header::{Header, HeaderFormat};
|
||||
use hyper::header::SetCookie;
|
||||
use std::fmt;
|
||||
|
||||
// a dummy header so we can use headers.remove::<SetCookie2>()
|
||||
#[derive(Clone, Debug, MallocSizeOf)]
|
||||
struct SetCookie2;
|
||||
impl Header for SetCookie2 {
|
||||
fn header_name() -> &'static str {
|
||||
"set-cookie2"
|
||||
}
|
||||
|
||||
fn parse_header(_: &[Vec<u8>]) -> Result<SetCookie2> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
impl HeaderFormat for SetCookie2 {
|
||||
fn fmt_header(&self, _f: &mut fmt::Formatter) -> fmt::Result {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
use http::header::{self, HeaderName};
|
||||
|
||||
let mut headers = self.response_headers.borrow().clone();
|
||||
headers.remove::<SetCookie>();
|
||||
headers.remove::<SetCookie2>();
|
||||
headers.remove(header::SET_COOKIE);
|
||||
headers.remove(HeaderName::from_static("set-cookie2"));
|
||||
// XXXManishearth additional CORS filtering goes here
|
||||
headers
|
||||
}
|
||||
|
@ -1416,12 +1437,15 @@ impl XMLHttpRequest {
|
|||
if self.override_charset.borrow().is_some() {
|
||||
self.override_charset.borrow().clone()
|
||||
} else {
|
||||
match self.response_headers.borrow().get() {
|
||||
Some(&ContentType(ref mime)) => {
|
||||
let value = mime.get_param(mime::Attr::Charset);
|
||||
value.and_then(|value| Encoding::for_label(value.as_bytes()))
|
||||
},
|
||||
None => None,
|
||||
match self.response_headers.borrow().typed_get::<ContentType>() {
|
||||
Some(ct) => {
|
||||
let mime: Mime = ct.into();
|
||||
let value = mime.get_param(mime::CHARSET);
|
||||
value.and_then(|value|{
|
||||
Encoding::for_label(value.as_ref().as_bytes())
|
||||
})
|
||||
}
|
||||
None => { None }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1430,9 +1454,9 @@ impl XMLHttpRequest {
|
|||
if self.override_mime_type.borrow().is_some() {
|
||||
self.override_mime_type.borrow().clone()
|
||||
} else {
|
||||
match self.response_headers.borrow().get() {
|
||||
Some(&ContentType(ref mime)) => Some(mime.clone()),
|
||||
None => None,
|
||||
match self.response_headers.borrow().typed_get::<ContentType>() {
|
||||
Some(ct) => { Some(ct.into()) },
|
||||
None => { None }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,9 +45,11 @@ extern crate euclid;
|
|||
extern crate fnv;
|
||||
extern crate gleam;
|
||||
extern crate half;
|
||||
extern crate headers_core;
|
||||
extern crate headers_ext;
|
||||
#[macro_use]
|
||||
extern crate html5ever;
|
||||
#[macro_use]
|
||||
extern crate http;
|
||||
extern crate hyper;
|
||||
extern crate hyper_serde;
|
||||
extern crate image;
|
||||
|
@ -65,7 +67,6 @@ extern crate malloc_size_of;
|
|||
#[macro_use]
|
||||
extern crate malloc_size_of_derive;
|
||||
extern crate metrics;
|
||||
#[macro_use]
|
||||
extern crate mime;
|
||||
extern crate mime_guess;
|
||||
extern crate mitochondria;
|
||||
|
|
|
@ -65,9 +65,9 @@ use dom::workletglobalscope::WorkletGlobalScopeInit;
|
|||
use embedder_traits::EmbedderMsg;
|
||||
use euclid::{Point2D, Vector2D, Rect};
|
||||
use fetch::FetchCanceller;
|
||||
use hyper::header::{ContentType, HttpDate, Headers, LastModified};
|
||||
use hyper::header::ReferrerPolicy as ReferrerPolicyHeader;
|
||||
use hyper::mime::{Mime, SubLevel, TopLevel};
|
||||
use headers_core::HeaderMapExt;
|
||||
use headers_ext::LastModified;
|
||||
use headers_ext::ReferrerPolicy as ReferrerPolicyHeader;
|
||||
use hyper_serde::Serde;
|
||||
use ipc_channel::ipc::{self, IpcSender};
|
||||
use js::glue::GetWindowProxyClass;
|
||||
|
@ -76,6 +76,7 @@ use js::jsapi::{JSTracer, SetWindowProxyClass};
|
|||
use js::jsval::UndefinedValue;
|
||||
use metrics::{MAX_TASK_NS, PaintTimeMetrics};
|
||||
use microtask::{MicrotaskQueue, Microtask};
|
||||
use mime::{self, Mime};
|
||||
use msg::constellation_msg::{BrowsingContextId, HistoryStateId, PipelineId};
|
||||
use msg::constellation_msg::{PipelineNamespace, TopLevelBrowsingContextId};
|
||||
use net_traits::{FetchMetadata, FetchResponseListener, FetchResponseMsg};
|
||||
|
@ -115,6 +116,7 @@ use std::rc::Rc;
|
|||
use std::result::Result;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::time::SystemTime;
|
||||
use style::thread_state::{self, ThreadState};
|
||||
use task_queue::{QueuedTask, QueuedTaskConversion, TaskQueue};
|
||||
use task_source::TaskSourceName;
|
||||
|
@ -127,7 +129,7 @@ use task_source::performance_timeline::PerformanceTimelineTaskSource;
|
|||
use task_source::remote_event::RemoteEventTaskSource;
|
||||
use task_source::user_interaction::UserInteractionTaskSource;
|
||||
use task_source::websocket::WebsocketTaskSource;
|
||||
use time::{get_time, precise_time_ns, Tm};
|
||||
use time::{at_utc, get_time, precise_time_ns, Timespec};
|
||||
use url::Position;
|
||||
use url::percent_encoding::percent_decode;
|
||||
use webdriver_handlers;
|
||||
|
@ -2611,37 +2613,27 @@ impl ScriptThread {
|
|||
window.init_window_proxy(&window_proxy);
|
||||
|
||||
let last_modified = metadata.headers.as_ref().and_then(|headers| {
|
||||
headers
|
||||
.get()
|
||||
.map(|&LastModified(HttpDate(ref tm))| dom_last_modified(tm))
|
||||
headers.typed_get::<LastModified>()
|
||||
.map(|tm| dom_last_modified(&tm.into()))
|
||||
});
|
||||
|
||||
let content_type = metadata
|
||||
.content_type
|
||||
.as_ref()
|
||||
.map(|&Serde(ContentType(ref mimetype))| mimetype.clone());
|
||||
|
||||
let loader = DocumentLoader::new_with_threads(
|
||||
self.resource_threads.clone(),
|
||||
Some(final_url.clone()),
|
||||
);
|
||||
|
||||
let is_html_document = match metadata.content_type {
|
||||
Some(Serde(ContentType(Mime(
|
||||
TopLevel::Application,
|
||||
SubLevel::Ext(ref sub_level),
|
||||
_,
|
||||
))))
|
||||
if sub_level.ends_with("+xml") =>
|
||||
{
|
||||
IsHTMLDocument::NonHTMLDocument
|
||||
},
|
||||
let content_type: Option<Mime> = metadata.content_type
|
||||
.map(Serde::into_inner)
|
||||
.map(Into::into);
|
||||
|
||||
Some(Serde(ContentType(Mime(TopLevel::Application, SubLevel::Xml, _)))) |
|
||||
Some(Serde(ContentType(Mime(TopLevel::Text, SubLevel::Xml, _)))) => {
|
||||
IsHTMLDocument::NonHTMLDocument
|
||||
},
|
||||
let is_html_document = match content_type {
|
||||
Some(ref mime) if mime.type_() == mime::APPLICATION &&
|
||||
mime.suffix() == Some(mime::XML) => IsHTMLDocument::NonHTMLDocument,
|
||||
|
||||
Some(ref mime) if
|
||||
(mime.type_() == mime::TEXT && mime.subtype() == mime::XML) ||
|
||||
(mime.type_() == mime::APPLICATION && mime.subtype() == mime::XML)
|
||||
=> IsHTMLDocument::NonHTMLDocument,
|
||||
_ => IsHTMLDocument::HTMLDocument,
|
||||
};
|
||||
|
||||
|
@ -2650,28 +2642,25 @@ impl ScriptThread {
|
|||
None => None,
|
||||
};
|
||||
|
||||
let referrer_policy = metadata
|
||||
.headers
|
||||
.as_ref()
|
||||
.map(Serde::deref)
|
||||
.and_then(Headers::get::<ReferrerPolicyHeader>)
|
||||
.map(ReferrerPolicy::from);
|
||||
let referrer_policy = metadata.headers
|
||||
.as_ref()
|
||||
.map(Serde::deref)
|
||||
.and_then(|h| h.typed_get::<ReferrerPolicyHeader>())
|
||||
.map(ReferrerPolicy::from);
|
||||
|
||||
let document = Document::new(
|
||||
&window,
|
||||
HasBrowsingContext::Yes,
|
||||
Some(final_url.clone()),
|
||||
incomplete.origin,
|
||||
is_html_document,
|
||||
content_type,
|
||||
last_modified,
|
||||
incomplete.activity,
|
||||
DocumentSource::FromParser,
|
||||
loader,
|
||||
referrer,
|
||||
referrer_policy,
|
||||
incomplete.canceller,
|
||||
);
|
||||
let document = Document::new(&window,
|
||||
HasBrowsingContext::Yes,
|
||||
Some(final_url.clone()),
|
||||
incomplete.origin,
|
||||
is_html_document,
|
||||
content_type,
|
||||
last_modified,
|
||||
incomplete.activity,
|
||||
DocumentSource::FromParser,
|
||||
loader,
|
||||
referrer,
|
||||
referrer_policy,
|
||||
incomplete.canceller);
|
||||
document.set_ready_state(DocumentReadyState::Loading);
|
||||
|
||||
self.documents
|
||||
|
@ -3112,7 +3101,7 @@ impl ScriptThread {
|
|||
let mut context = ParserContext::new(id, url.clone());
|
||||
|
||||
let mut meta = Metadata::default(url);
|
||||
meta.set_content_type(Some(&mime!(Text / Html)));
|
||||
meta.set_content_type(Some(&mime::TEXT_HTML));
|
||||
|
||||
// If this page load is the result of a javascript scheme url, map
|
||||
// the evaluation result into a response.
|
||||
|
@ -3221,7 +3210,10 @@ impl Drop for ScriptThread {
|
|||
}
|
||||
}
|
||||
|
||||
fn dom_last_modified(tm: &Tm) -> String {
|
||||
fn dom_last_modified(tm: &SystemTime) -> String {
|
||||
let tm = tm.duration_since(SystemTime::UNIX_EPOCH).unwrap();
|
||||
let tm = Timespec::new(tm.as_secs() as i64, 0);
|
||||
let tm = at_utc(tm);
|
||||
tm.to_local()
|
||||
.strftime("%m/%d/%Y %H:%M:%S")
|
||||
.unwrap()
|
||||
|
|
|
@ -14,11 +14,9 @@ use dom::htmlelement::HTMLElement;
|
|||
use dom::htmllinkelement::{RequestGenerationId, HTMLLinkElement};
|
||||
use dom::node::{document_from_node, window_from_node};
|
||||
use encoding_rs::UTF_8;
|
||||
use hyper::header::ContentType;
|
||||
use hyper::mime::{Mime, TopLevel, SubLevel};
|
||||
use hyper_serde::Serde;
|
||||
use ipc_channel::ipc;
|
||||
use ipc_channel::router::ROUTER;
|
||||
use mime::{self, Mime};
|
||||
use net_traits::{FetchResponseListener, FetchMetadata, FilteredMetadata, Metadata, NetworkError, ReferrerPolicy};
|
||||
use net_traits::request::{CorsSettings, CredentialsMode, Destination, RequestInit, RequestMode};
|
||||
use network_listener::{NetworkListener, PreInvoke};
|
||||
|
@ -117,18 +115,12 @@ impl FetchResponseListener for StylesheetContext {
|
|||
Some(meta) => meta,
|
||||
None => return,
|
||||
};
|
||||
let is_css =
|
||||
metadata
|
||||
.content_type
|
||||
.map_or(false, |Serde(ContentType(Mime(top, sub, _)))| {
|
||||
top == TopLevel::Text && sub == SubLevel::Css
|
||||
});
|
||||
let is_css = metadata.content_type.map_or(false, |ct| {
|
||||
let mime: Mime = ct.into_inner().into();
|
||||
mime.type_() == mime::TEXT && mime.subtype() == mime::CSS
|
||||
});
|
||||
|
||||
let data = if is_css {
|
||||
mem::replace(&mut self.data, vec![])
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
let data = if is_css { mem::replace(&mut self.data, vec![]) } else { vec![] };
|
||||
|
||||
// TODO: Get the actual value. http://dev.w3.org/csswg/css-syntax/#environment-encoding
|
||||
let environment_encoding = UTF_8;
|
||||
|
|
|
@ -299,7 +299,11 @@ pub fn handle_add_cookie(
|
|||
},
|
||||
};
|
||||
let url = document.url();
|
||||
let method = if cookie.http_only() { HTTP } else { NonHTTP };
|
||||
let method = if cookie.http_only().unwrap_or(false) {
|
||||
HTTP
|
||||
} else {
|
||||
NonHTTP
|
||||
};
|
||||
|
||||
let domain = cookie.domain().map(ToOwned::to_owned);
|
||||
reply
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue