diff options
-rw-r--r-- | components/layout/layout_task.rs | 2 | ||||
-rw-r--r-- | components/net/about_loader.rs | 18 | ||||
-rw-r--r-- | components/net/data_loader.rs | 20 | ||||
-rw-r--r-- | components/net/file_loader.rs | 12 | ||||
-rw-r--r-- | components/net/http_loader.rs | 45 | ||||
-rw-r--r-- | components/net/image_cache_task.rs | 4 | ||||
-rw-r--r-- | components/net/resource_task.rs | 15 | ||||
-rw-r--r-- | components/net_traits/lib.rs | 295 | ||||
-rw-r--r-- | components/script/cors.rs | 4 | ||||
-rw-r--r-- | components/script/dom/dedicatedworkerglobalscope.rs | 4 | ||||
-rw-r--r-- | components/script/dom/document.rs | 10 | ||||
-rw-r--r-- | components/script/dom/htmlscriptelement.rs | 2 | ||||
-rw-r--r-- | components/script/dom/servohtmlparser.rs | 2 | ||||
-rw-r--r-- | components/script/dom/xmlhttprequest.rs | 25 | ||||
-rw-r--r-- | components/script/script_task.rs | 20 |
15 files changed, 373 insertions, 105 deletions
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 001f8f42d2a..12a2b549c38 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -718,7 +718,7 @@ impl LayoutTask { // TODO we don't really even need to load this if mq does not match let (metadata, iter) = load_bytes_iter(pending); let protocol_encoding_label = metadata.charset.as_ref().map(|s| &**s); - let final_url = metadata.final_url; + let final_url = metadata.final_url.0; let sheet = Stylesheet::from_bytes_iter(iter, final_url, diff --git a/components/net/about_loader.rs b/components/net/about_loader.rs index 213988904c2..d20a3e4ef63 100644 --- a/components/net/about_loader.rs +++ b/components/net/about_loader.rs @@ -2,7 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use net_traits::{LoadData, Metadata, LoadConsumer}; +use net_traits::{LoadData, Metadata, LoadConsumer, SerializableContentType, SerializableRawStatus}; +use net_traits::{SerializableStringResult, SerializableUrl}; use net_traits::ProgressMsg::Done; use mime_classifier::MIMEClassifier; use resource_task::start_sending; @@ -22,12 +23,14 @@ pub fn factory(mut load_data: LoadData, start_chan: LoadConsumer, classifier: Ar "blank" => { let chan = start_sending(start_chan, Metadata { final_url: load_data.url, - content_type: Some(ContentType(Mime(TopLevel::Text, SubLevel::Html, vec![]))), + content_type: Some(SerializableContentType(ContentType(Mime(TopLevel::Text, + SubLevel::Html, + vec![])))), charset: Some("utf-8".to_string()), headers: None, - status: Some(RawStatus(200, "OK".into())), + status: Some(SerializableRawStatus(RawStatus(200, "OK".into()))), }); - chan.send(Done(Ok(()))).unwrap(); + chan.send(Done(SerializableStringResult(Ok(())))).unwrap(); return } "crash" => panic!("Loading the about:crash URL."), @@ -35,11 +38,12 @@ pub fn factory(mut load_data: LoadData, start_chan: LoadConsumer, classifier: Ar let mut path = resources_dir_path(); path.push("failure.html"); assert!(path.exists()); - load_data.url = Url::from_file_path(&*path).unwrap(); + load_data.url = SerializableUrl(Url::from_file_path(&*path).unwrap()); } _ => { - start_sending(start_chan, Metadata::default(load_data.url)) - .send(Done(Err("Unknown about: URL.".to_string()))).unwrap(); + start_sending(start_chan, Metadata::default(load_data.url.0)) + .send(Done(SerializableStringResult(Err("Unknown about: URL.".to_string())))) + .unwrap(); return } }; diff --git a/components/net/data_loader.rs b/components/net/data_loader.rs index 36daf044e61..f1f99d6efe2 100644 --- a/components/net/data_loader.rs +++ b/components/net/data_loader.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use net_traits::{LoadData, Metadata, LoadConsumer}; +use net_traits::{LoadData, Metadata, LoadConsumer, SerializableStringResult}; use net_traits::ProgressMsg::{Payload, Done}; use mime_classifier::MIMEClassifier; use resource_task::start_sending; @@ -26,23 +26,24 @@ pub fn load(load_data: LoadData, start_chan: LoadConsumer) { let url = load_data.url; assert!(&*url.scheme == "data"); - let mut metadata = Metadata::default(url.clone()); + let mut metadata = Metadata::default((*url).clone()); // Split out content type and data. let mut scheme_data = match url.scheme_data { - SchemeData::NonRelative(scheme_data) => scheme_data, + SchemeData::NonRelative(ref scheme_data) => (*scheme_data).clone(), _ => panic!("Expected a non-relative scheme URL.") }; match url.query { - Some(query) => { + Some(ref query) => { scheme_data.push_str("?"); - scheme_data.push_str(&query); + scheme_data.push_str(query); }, None => () } let parts: Vec<&str> = scheme_data.splitn(2, ',').collect(); if parts.len() != 2 { - start_sending(start_chan, metadata).send(Done(Err("invalid data uri".to_string()))).unwrap(); + start_sending(start_chan, metadata).send(Done(SerializableStringResult(Err( + "invalid data uri".to_string())))).unwrap(); return; } @@ -69,15 +70,16 @@ pub fn load(load_data: LoadData, start_chan: LoadConsumer) { let bytes = bytes.into_iter().filter(|&b| b != ' ' as u8).collect::<Vec<u8>>(); match bytes.from_base64() { Err(..) => { - progress_chan.send(Done(Err("non-base64 data uri".to_string()))).unwrap(); + progress_chan.send(Done(SerializableStringResult(Err( + "non-base64 data uri".to_string())))).unwrap(); } Ok(data) => { progress_chan.send(Payload(data)).unwrap(); - progress_chan.send(Done(Ok(()))).unwrap(); + progress_chan.send(Done(SerializableStringResult(Ok(())))).unwrap(); } } } else { progress_chan.send(Payload(bytes)).unwrap(); - progress_chan.send(Done(Ok(()))).unwrap(); + progress_chan.send(Done(SerializableStringResult(Ok(())))).unwrap(); } } diff --git a/components/net/file_loader.rs b/components/net/file_loader.rs index a81d0e8afdb..08de3298cf3 100644 --- a/components/net/file_loader.rs +++ b/components/net/file_loader.rs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use net_traits::{LoadData, Metadata, LoadConsumer}; +use net_traits::{LoadData, Metadata, LoadConsumer, SerializableStringResult}; use net_traits::ProgressMsg::{Payload, Done}; use mime_classifier::MIMEClassifier; use resource_task::{start_sending, start_sending_sniffed, ProgressSender}; @@ -48,7 +48,7 @@ pub fn factory(load_data: LoadData, senders: LoadConsumer, classifier: Arc<MIMEC let url = load_data.url; assert!(&*url.scheme == "file"); spawn_named("file_loader".to_owned(), move || { - let metadata = Metadata::default(url.clone()); + let metadata = Metadata::default(url.0.clone()); let file_path: Result<PathBuf, ()> = url.to_file_path(); match file_path { Ok(file_path) => { @@ -65,17 +65,19 @@ pub fn factory(load_data: LoadData, senders: LoadConsumer, classifier: Arc<MIMEC Ok(ReadStatus::EOF) | Err(_) => (res.map(|_| ()), start_sending(senders, metadata)), }; - progress_chan.send(Done(res)).unwrap(); + progress_chan.send(Done(SerializableStringResult(res))).unwrap(); } Err(e) => { let progress_chan = start_sending(senders, metadata); - progress_chan.send(Done(Err(e.description().to_string()))).unwrap(); + progress_chan.send(Done(SerializableStringResult(Err(e.description() + .to_string())))) + .unwrap(); } } } Err(_) => { let progress_chan = start_sending(senders, metadata); - progress_chan.send(Done(Err(url.to_string()))).unwrap(); + progress_chan.send(Done(SerializableStringResult(Err(url.to_string())))).unwrap(); } } }); diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 637558a4e7f..cc186787985 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -2,7 +2,9 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use net_traits::{ControlMsg, CookieSource, LoadData, Metadata, LoadConsumer}; +use net_traits::{ControlMsg, CookieSource, LoadData, Metadata, LoadConsumer, SerializableMethod}; +use net_traits::{SerializableHeaders, SerializableRawStatus, SerializableStringResult}; +use net_traits::{SerializableUrl}; use net_traits::ProgressMsg::{Payload, Done}; use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent}; use mime_classifier::MIMEClassifier; @@ -51,7 +53,7 @@ fn send_error(url: Url, err: String, start_chan: LoadConsumer) { metadata.status = None; match start_sending_opt(start_chan, metadata) { - Ok(p) => p.send(Done(Err(err))).unwrap(), + Ok(p) => p.send(Done(SerializableStringResult(Err(err)))).unwrap(), _ => {} }; } @@ -94,7 +96,7 @@ fn load(mut load_data: LoadData, // repository DOES exist, please update this constant to use it. let max_redirects = 50; let mut iters = 0; - let mut url = load_data.url.clone(); + let mut url = load_data.url.0.clone(); let mut redirected_to = HashSet::new(); // If the URL is a view-source scheme then the scheme data contains the @@ -153,7 +155,10 @@ reason: \"certificate verify failed\" }]))"; Request::with_connector(load_data.method.clone(), url.clone(), &HttpsConnector::new(Openssl { context: Arc::new(context) })) }; - let mut req = match req { + + let mut req = match Request::with_connector(load_data.method.0.clone(), + url.clone(), + &mut connector) { Ok(req) => req, Err(HttpError::Io(ref io_error)) if ( io_error.kind() == io::ErrorKind::Other && @@ -182,11 +187,11 @@ reason: \"certificate verify failed\" }]))"; // https://bugzilla.mozilla.org/show_bug.cgi?id=216828 . // Only preserve ones which have been explicitly marked as such. if iters == 1 { - let mut combined_headers = load_data.headers.clone(); + let mut combined_headers = (*load_data.headers).clone(); combined_headers.extend(load_data.preserved_headers.iter()); *req.headers_mut() = combined_headers; } else { - *req.headers_mut() = load_data.preserved_headers.clone(); + *req.headers_mut() = (*load_data.preserved_headers).clone(); } req.headers_mut().set(host); @@ -202,7 +207,9 @@ reason: \"certificate verify failed\" }]))"; } let (tx, rx) = channel(); - cookies_chan.send(ControlMsg::GetCookiesForUrl(url.clone(), tx, CookieSource::HTTP)).unwrap(); + cookies_chan.send(ControlMsg::GetCookiesForUrl(SerializableUrl(url.clone()), + tx, + CookieSource::HTTP)).unwrap(); if let Some(cookie_list) = rx.recv().unwrap() { let mut v = Vec::new(); v.push(cookie_list.into_bytes()); @@ -213,7 +220,7 @@ reason: \"certificate verify failed\" }]))"; req.headers_mut().set_raw("Accept-Encoding".to_owned(), vec![b"gzip, deflate".to_vec()]); } if log_enabled!(log::LogLevel::Info) { - info!("{}", load_data.method); + info!("{}", load_data.method.0); for header in req.headers().iter() { info!(" - {}", header); } @@ -241,7 +248,7 @@ reason: \"certificate verify failed\" }]))"; writer }, _ => { - match load_data.method { + match *load_data.method { Method::Get | Method::Head => (), _ => req.headers_mut().set(ContentLength(0)) } @@ -259,9 +266,9 @@ reason: \"certificate verify failed\" }]))"; // TODO: Do this only if load_data has some pipeline_id, and send the pipeline_id in the message let request_id = uuid::Uuid::new_v4().to_simple_string(); if let Some(ref chan) = devtools_chan { - let net_event = NetworkEvent::HttpRequest(load_data.url.clone(), - load_data.method.clone(), - load_data.headers.clone(), + let net_event = NetworkEvent::HttpRequest((*load_data.url).clone(), + (*load_data.method).clone(), + (*load_data.headers).clone(), load_data.data.clone()); chan.send(DevtoolsControlMsg::FromChrome( ChromeToDevtoolsControlMsg::NetworkEventMessage(request_id.clone(), @@ -287,7 +294,7 @@ reason: \"certificate verify failed\" }]))"; if let Some(cookies) = response.headers.get_raw("set-cookie") { for cookie in cookies.iter() { if let Ok(cookies) = String::from_utf8(cookie.clone()) { - cookies_chan.send(ControlMsg::SetCookiesForUrl(url.clone(), + cookies_chan.send(ControlMsg::SetCookiesForUrl(SerializableUrl(url.clone()), cookies, CookieSource::HTTP)).unwrap(); } @@ -325,10 +332,10 @@ reason: \"certificate verify failed\" }]))"; // According to https://tools.ietf.org/html/rfc7231#section-6.4.2, // historically UAs have rewritten POST->GET on 301 and 302 responses. - if load_data.method == Method::Post && + if *load_data.method == Method::Post && (response.status == StatusCode::MovedPermanently || response.status == StatusCode::Found) { - load_data.method = Method::Get; + load_data.method = SerializableMethod(Method::Get); } if redirected_to.contains(&url) { @@ -352,8 +359,8 @@ reason: \"certificate verify failed\" }]))"; Some(&ContentType(ref mime)) => Some(mime), None => None }); - metadata.headers = Some(adjusted_headers); - metadata.status = Some(response.status_raw().clone()); + metadata.headers = Some(SerializableHeaders(adjusted_headers)); + metadata.status = Some(SerializableRawStatus(response.status_raw().clone())); let mut encoding_str: Option<String> = None; //FIXME: Implement Content-Encoding Header https://github.com/hyperium/hyper/issues/391 @@ -389,7 +396,7 @@ reason: \"certificate verify failed\" }]))"; send_data(&mut response_decoding, start_chan, metadata, classifier); } Err(err) => { - send_error(metadata.final_url, err.to_string(), start_chan); + send_error((*metadata.final_url).clone(), err.to_string(), start_chan); return; } } @@ -438,5 +445,5 @@ fn send_data<R: Read>(reader: &mut R, }; } - let _ = progress_chan.send(Done(Ok(()))); + let _ = progress_chan.send(Done(SerializableStringResult(Ok(())))); } diff --git a/components/net/image_cache_task.rs b/components/net/image_cache_task.rs index e6088051c29..865e8c6e37b 100644 --- a/components/net/image_cache_task.rs +++ b/components/net/image_cache_task.rs @@ -248,10 +248,10 @@ impl ImageCache { pending_load.bytes.push_all(&data); } ResponseAction::ResponseComplete(result) => { - match result { + match *result { Ok(()) => { let pending_load = self.pending_loads.get_mut(&msg.url).unwrap(); - pending_load.result = Some(result); + pending_load.result = Some((*result).clone()); let bytes = mem::replace(&mut pending_load.bytes, vec!()); let url = msg.url.clone(); diff --git a/components/net/resource_task.rs b/components/net/resource_task.rs index 1e857102e33..d206e252c93 100644 --- a/components/net/resource_task.rs +++ b/components/net/resource_task.rs @@ -13,7 +13,8 @@ use cookie; use mime_classifier::MIMEClassifier; use net_traits::{ControlMsg, LoadData, LoadResponse, LoadConsumer}; -use net_traits::{Metadata, ProgressMsg, ResourceTask, AsyncResponseTarget, ResponseAction, CookieSource}; +use net_traits::{Metadata, ProgressMsg, ResourceTask, AsyncResponseTarget, ResponseAction}; +use net_traits::{CookieSource, SerializableContentType, SerializableStringResult}; use net_traits::ProgressMsg::Done; use util::opts; use util::task::spawn_named; @@ -124,14 +125,17 @@ pub fn start_sending_sniffed_opt(start_chan: LoadConsumer, mut metadata: Metadat } } - let supplied_type = metadata.content_type.map(|ContentType(Mime(toplevel, sublevel, _))| { + let supplied_type = + metadata.content_type.map(|SerializableContentType(ContentType(Mime(toplevel, + sublevel, + _)))| { (format!("{}", toplevel), format!("{}", sublevel)) }); metadata.content_type = classifier.classify(nosniff, check_for_apache_bug, &supplied_type, &partial_body).map(|(toplevel, sublevel)| { let mime_tp: TopLevel = toplevel.parse().unwrap(); let mime_sb: SubLevel = sublevel.parse().unwrap(); - ContentType(Mime(mime_tp, mime_sb, vec!())) + SerializableContentType(ContentType(Mime(mime_tp, mime_sb, vec!()))) }); } @@ -321,8 +325,9 @@ impl ResourceManager { "about" => from_factory(about_loader::factory), _ => { debug!("resource_task: no loader for scheme {}", load_data.url.scheme); - start_sending(consumer, Metadata::default(load_data.url)) - .send(ProgressMsg::Done(Err("no loader for scheme".to_string()))).unwrap(); + start_sending(consumer, Metadata::default((*load_data.url).clone())) + .send(ProgressMsg::Done(SerializableStringResult(Err( + "no loader for scheme".to_string())))).unwrap(); return } }; diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 0028c61dcce..8e243195cf6 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -10,8 +10,6 @@ #![feature(vec_push_all)] #![plugin(serde_macros)] -#![plugin(serde_macros)] - extern crate euclid; extern crate hyper; extern crate ipc_channel; @@ -24,13 +22,19 @@ extern crate url; extern crate util; extern crate msg; -use hyper::header::{ContentType, Headers}; +use hyper::header::{ContentType, Header, Headers, HeadersItems}; use hyper::http::RawStatus; use hyper::method::Method; use hyper::mime::{Mime, Attr}; use msg::constellation_msg::{PipelineId}; +use serde::de; +use serde::ser; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; use url::Url; +use std::borrow::Cow; +use std::ops::{Deref, DerefMut}; +use std::str::FromStr; use std::sync::mpsc::{channel, Receiver, Sender}; use std::thread; @@ -46,14 +50,14 @@ pub mod image { pub mod base; } -#[derive(Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct LoadData { - pub url: Url, - pub method: Method, + pub url: SerializableUrl, + pub method: SerializableMethod, /// Headers that will apply to the initial request only - pub headers: Headers, + pub headers: SerializableHeaders, /// Headers that will apply to the initial request and any redirects - pub preserved_headers: Headers, + pub preserved_headers: SerializableHeaders, pub data: Option<Vec<u8>>, pub cors: Option<ResourceCORSData>, pub pipeline_id: Option<PipelineId>, @@ -62,10 +66,10 @@ pub struct LoadData { impl LoadData { pub fn new(url: Url, id: Option<PipelineId>) -> LoadData { LoadData { - url: url, - method: Method::Get, - headers: Headers::new(), - preserved_headers: Headers::new(), + url: SerializableUrl(url), + method: SerializableMethod(Method::Get), + headers: SerializableHeaders(Headers::new()), + preserved_headers: SerializableHeaders(Headers::new()), data: None, cors: None, pipeline_id: id, @@ -87,13 +91,14 @@ pub trait AsyncResponseListener { /// Data for passing between threads/processes to indicate a particular action to /// take on a provided network listener. +#[derive(Deserialize, Serialize)] pub enum ResponseAction { /// Invoke headers_available HeadersAvailable(Metadata), /// Invoke data_available DataAvailable(Vec<u8>), /// Invoke response_complete - ResponseComplete(Result<(), String>) + ResponseComplete(SerializableStringResult) } impl ResponseAction { @@ -102,7 +107,7 @@ impl ResponseAction { match self { ResponseAction::HeadersAvailable(m) => listener.headers_available(m), ResponseAction::DataAvailable(d) => listener.data_available(d), - ResponseAction::ResponseComplete(r) => listener.response_complete(r), + ResponseAction::ResponseComplete(r) => listener.response_complete(r.0), } } } @@ -132,9 +137,9 @@ pub enum ControlMsg { /// Request the data associated with a particular URL Load(LoadData, LoadConsumer), /// Store a set of cookies for a given originating URL - SetCookiesForUrl(Url, String, CookieSource), + SetCookiesForUrl(SerializableUrl, String, CookieSource), /// Retrieve the stored cookies for a given URL - GetCookiesForUrl(Url, Sender<Option<String>>, CookieSource), + GetCookiesForUrl(SerializableUrl, Sender<Option<String>>, CookieSource), /// Store a domain's STS information SetHSTSEntryForHost(String, IncludeSubdomains, Option<u64>), Exit @@ -210,43 +215,43 @@ pub struct LoadResponse { pub progress_port: Receiver<ProgressMsg>, } -#[derive(Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct ResourceCORSData { /// CORS Preflight flag pub preflight: bool, /// Origin of CORS Request - pub origin: Url + pub origin: SerializableUrl, } /// Metadata about a loaded resource, such as is obtained from HTTP headers. -#[derive(Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct Metadata { /// Final URL after redirects. - pub final_url: Url, + pub final_url: SerializableUrl, /// MIME type / subtype. - pub content_type: Option<(ContentType)>, + pub content_type: Option<(SerializableContentType)>, /// Character set. pub charset: Option<String>, /// Headers - pub headers: Option<Headers>, + pub headers: Option<SerializableHeaders>, /// HTTP Status - pub status: Option<RawStatus>, + pub status: Option<SerializableRawStatus>, } impl Metadata { /// Metadata with defaults for everything optional. pub fn default(url: Url) -> Self { Metadata { - final_url: url, + final_url: SerializableUrl(url), content_type: None, charset: None, headers: None, // https://fetch.spec.whatwg.org/#concept-response-status-message - status: Some(RawStatus(200, "OK".into())), + status: Some(SerializableRawStatus(RawStatus(200, "OK".into()))), } } @@ -255,7 +260,7 @@ impl Metadata { match content_type { None => (), Some(mime) => { - self.content_type = Some(ContentType(mime.clone())); + self.content_type = Some(SerializableContentType(ContentType(mime.clone()))); let &Mime(_, _, ref parameters) = mime; for &(ref k, ref v) in parameters.iter() { if &Attr::Charset == k { @@ -268,7 +273,7 @@ impl Metadata { } /// The creator of a given cookie -#[derive(PartialEq, Copy, Clone)] +#[derive(PartialEq, Copy, Clone, Deserialize, Serialize)] pub enum CookieSource { /// An HTTP API HTTP, @@ -277,12 +282,12 @@ pub enum CookieSource { } /// Messages sent in response to a `Load` message -#[derive(PartialEq,Debug)] +#[derive(PartialEq, Debug, Deserialize, Serialize)] pub enum ProgressMsg { /// Binary data - there may be multiple of these Payload(Vec<u8>), /// Indicates loading is complete, either successfully or not - Done(Result<(), String>) + Done(SerializableStringResult) } /// Convenience function for synchronously loading a whole resource. @@ -296,8 +301,10 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url) loop { match response.progress_port.recv().unwrap() { ProgressMsg::Payload(data) => buf.push_all(&data), - ProgressMsg::Done(Ok(())) => return Ok((response.metadata, buf)), - ProgressMsg::Done(Err(e)) => return Err(e) + ProgressMsg::Done(SerializableStringResult(Ok(()))) => { + return Ok((response.metadata, buf)) + } + ProgressMsg::Done(SerializableStringResult(Err(e))) => return Err(e) } } } @@ -321,8 +328,8 @@ impl Iterator for ProgressMsgPortIterator { fn next(&mut self) -> Option<Vec<u8>> { match self.progress_port.recv().unwrap() { ProgressMsg::Payload(data) => Some(data), - ProgressMsg::Done(Ok(())) => None, - ProgressMsg::Done(Err(e)) => { + ProgressMsg::Done(SerializableStringResult(Ok(()))) => None, + ProgressMsg::Done(SerializableStringResult(Err(e))) => { error!("error receiving bytes: {}", e); None } @@ -330,4 +337,226 @@ impl Iterator for ProgressMsgPortIterator { } } +#[derive(Clone)] +pub struct SerializableMethod(pub Method); + +impl Deref for SerializableMethod { + type Target = Method; + + fn deref(&self) -> &Method { + &self.0 + } +} + +impl Serialize for SerializableMethod { + fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { + format!("{}", self.0).serialize(serializer) + } +} + +impl Deserialize for SerializableMethod { + fn deserialize<D>(deserializer: &mut D) -> Result<SerializableMethod, D::Error> + where D: Deserializer { + let string_representation: String = try!(Deserialize::deserialize(deserializer)); + Ok(SerializableMethod(FromStr::from_str(&string_representation[..]).unwrap())) + } +} + +#[derive(Clone)] +pub struct SerializableHeaders(pub Headers); + +impl Deref for SerializableHeaders { + type Target = Headers; + + fn deref(&self) -> &Headers { + &self.0 + } +} + +impl DerefMut for SerializableHeaders { + fn deref_mut(&mut self) -> &mut Headers { + &mut self.0 + } +} + +impl Serialize for SerializableHeaders { + fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { + struct HeadersVisitor<'a> { + iter: HeadersItems<'a>, + len: usize, + } + + impl<'a> ser::MapVisitor for HeadersVisitor<'a> { + fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error> + where S: Serializer { + match self.iter.next() { + Some(header_item) => { + try!(serializer.visit_map_elt(header_item.name(), + header_item.value_string())); + Ok(Some(())) + } + None => Ok(None), + } + } + + fn len(&self) -> Option<usize> { + Some(self.len) + } + } + + serializer.visit_map(HeadersVisitor { + iter: self.iter(), + len: self.len(), + }) + } +} + +impl Deserialize for SerializableHeaders { + fn deserialize<D>(deserializer: &mut D) -> Result<SerializableHeaders, D::Error> + where D: Deserializer { + struct HeadersVisitor; + + impl de::Visitor for HeadersVisitor { + type Value = SerializableHeaders; + + fn visit_map<V>(&mut self, mut visitor: V) -> Result<SerializableHeaders, V::Error> + where V: de::MapVisitor { + let mut result = Headers::new(); + while let Some((key, value)) = try!(visitor.visit()) { + let (key, value): (String, String) = (key, value); + result.set_raw(key, vec![value.into_bytes()]); + } + try!(visitor.end()); + Ok(SerializableHeaders(result)) + } + } + + let result = SerializableHeaders(Headers::new()); + try!(deserializer.visit_map(HeadersVisitor)); + Ok(result) + } +} + +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct SerializableUrl(pub Url); + +impl Deref for SerializableUrl { + type Target = Url; + + fn deref(&self) -> &Url { + &self.0 + } +} + +impl DerefMut for SerializableUrl { + fn deref_mut(&mut self) -> &mut Url { + &mut self.0 + } +} + +impl Serialize for SerializableUrl { + fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { + format!("{}", self.0).serialize(serializer) + } +} + +impl Deserialize for SerializableUrl { + fn deserialize<D>(deserializer: &mut D) -> Result<SerializableUrl, D::Error> + where D: Deserializer { + let string_representation: String = try!(Deserialize::deserialize(deserializer)); + Ok(SerializableUrl(FromStr::from_str(&string_representation[..]).unwrap())) + } +} + +#[derive(Clone, PartialEq)] +pub struct SerializableContentType(pub ContentType); + +impl Deref for SerializableContentType { + type Target = ContentType; + + fn deref(&self) -> &ContentType { + &self.0 + } +} + +impl Serialize for SerializableContentType { + fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { + format!("{}", self.0).serialize(serializer) + } +} + +impl Deserialize for SerializableContentType { + fn deserialize<D>(deserializer: &mut D) -> Result<SerializableContentType, D::Error> + where D: Deserializer { + let string_representation: String = try!(Deserialize::deserialize(deserializer)); + Ok(SerializableContentType(Header::parse_header( + &[string_representation.into_bytes()]).unwrap())) + } +} + +#[derive(Clone, PartialEq)] +pub struct SerializableRawStatus(pub RawStatus); + +impl Deref for SerializableRawStatus { + type Target = RawStatus; + + fn deref(&self) -> &RawStatus { + &self.0 + } +} + +impl Serialize for SerializableRawStatus { + fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { + ((self.0).0, (self.0).1.clone().into_owned()).serialize(serializer) + } +} + +impl Deserialize for SerializableRawStatus { + fn deserialize<D>(deserializer: &mut D) -> Result<SerializableRawStatus, D::Error> + where D: Deserializer { + let representation: (u16, String) = try!(Deserialize::deserialize(deserializer)); + Ok(SerializableRawStatus(RawStatus(representation.0, Cow::Owned(representation.1)))) + } +} + +#[derive(Clone, PartialEq, Debug)] +pub struct SerializableStringResult(pub Result<(),String>); + +#[derive(Deserialize, Serialize)] +enum SerializableStringResultInternal { + Ok(()), + Err(String), +} + +impl Deref for SerializableStringResult { + type Target = Result<(),String>; + + fn deref(&self) -> &Result<(),String> { + &self.0 + } +} + +impl Serialize for SerializableStringResult { + fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { + let result = match **self { + Ok(ref value) => SerializableStringResultInternal::Ok(*value), + Err(ref value) => SerializableStringResultInternal::Err((*value).clone()), + }; + result.serialize(serializer) + } +} + +impl Deserialize for SerializableStringResult { + fn deserialize<D>(deserializer: &mut D) -> Result<SerializableStringResult, D::Error> + where D: Deserializer { + let result: SerializableStringResultInternal = + try!(Deserialize::deserialize(deserializer)); + match result { + SerializableStringResultInternal::Ok(value) => Ok(SerializableStringResult(Ok(value))), + SerializableStringResultInternal::Err(value) => { + Ok(SerializableStringResult(Err(value))) + } + } + } +} diff --git a/components/script/cors.rs b/components/script/cors.rs index c5a99fac63d..1e274a5b9fd 100644 --- a/components/script/cors.rs +++ b/components/script/cors.rs @@ -12,6 +12,7 @@ use network_listener::{NetworkListener, PreInvoke}; use script_task::ScriptChan; use net_traits::{AsyncResponseTarget, AsyncResponseListener, ResponseAction, Metadata}; +use net_traits::{SerializableStringResult}; use std::ascii::AsciiExt; use std::borrow::ToOwned; @@ -144,7 +145,8 @@ impl CORSRequest { let mut context = listener.context.lock(); let context = context.as_mut().unwrap(); *context.response.borrow_mut() = Some(response); - listener.invoke_with_listener(ResponseAction::ResponseComplete(Ok(()))); + listener.invoke_with_listener(ResponseAction::ResponseComplete( + SerializableStringResult(Ok(())))); }); } diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 63a5a82a46c..02f75d3832b 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -181,8 +181,8 @@ impl DedicatedWorkerGlobalScope { let serialized_url = url.serialize(); let parent_sender_for_reporter = parent_sender.clone(); let global = DedicatedWorkerGlobalScope::new( - url, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(), resource_task, - constellation_chan, parent_sender, own_sender, receiver); + url.0, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(), + resource_task, constellation_chan, parent_sender, own_sender, receiver); // FIXME(njn): workers currently don't have a unique ID suitable for using in reporter // registration (#6631), so we instead use a random number and cross our fingers. let reporter_name = format!("worker-reporter-{}", random::<u64>()); diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 9df842dddfc..2e5a479f4e6 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -74,7 +74,7 @@ use msg::constellation_msg::{ConstellationChan, FocusType, Key, KeyState, KeyMod use msg::constellation_msg::{SUPER, ALT, SHIFT, CONTROL}; use net_traits::CookieSource::NonHTTP; use net_traits::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl}; -use net_traits::{Metadata, PendingAsyncLoad, AsyncResponseTarget}; +use net_traits::{Metadata, PendingAsyncLoad, AsyncResponseTarget, SerializableUrl}; use script_task::Runnable; use script_traits::{MouseButton, UntrustedNodeAddress}; use util::opts; @@ -1721,7 +1721,9 @@ impl<'a> DocumentMethods for &'a Document { } let window = self.window.root(); let (tx, rx) = channel(); - let _ = window.r().resource_task().send(GetCookiesForUrl(url, tx, NonHTTP)); + let _ = window.r().resource_task().send(GetCookiesForUrl(SerializableUrl(url), + tx, + NonHTTP)); let cookies = rx.recv().unwrap(); Ok(cookies.unwrap_or("".to_owned())) } @@ -1734,7 +1736,9 @@ impl<'a> DocumentMethods for &'a Document { return Err(Security); } let window = self.window.root(); - let _ = window.r().resource_task().send(SetCookiesForUrl(url, cookie, NonHTTP)); + let _ = window.r().resource_task().send(SetCookiesForUrl(SerializableUrl(url), + cookie, + NonHTTP)); Ok(()) } diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 3329e0f0af9..56ea651ef7d 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -392,7 +392,7 @@ impl<'a> HTMLScriptElementHelpers for &'a HTMLScriptElement { // encoding as the fallback encoding. (UTF_8.decode(&*bytes, DecoderTrap::Replace).unwrap(), true, - metadata.final_url) + metadata.final_url.0) }, // Step 2.b.1.c. diff --git a/components/script/dom/servohtmlparser.rs b/components/script/dom/servohtmlparser.rs index a81fe125973..6e12320b682 100644 --- a/components/script/dom/servohtmlparser.rs +++ b/components/script/dom/servohtmlparser.rs @@ -84,7 +84,7 @@ impl ParserContext { impl AsyncResponseListener for ParserContext { fn headers_available(&self, metadata: Metadata) { - let content_type = metadata.content_type.clone(); + let content_type = metadata.content_type.clone().map(|content_type| content_type.0); let parser = ScriptTask::page_fetch_complete(self.id.clone(), self.subpage.clone(), metadata); diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 9ec68cb0fd2..7cb33d1b023 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -46,7 +46,8 @@ use js::jsval::{JSVal, NullValue, UndefinedValue}; use net_traits::ControlMsg::Load; use net_traits::{ResourceTask, ResourceCORSData, LoadData, LoadConsumer}; -use net_traits::{AsyncResponseListener, Metadata}; +use net_traits::{AsyncResponseListener, Metadata, SerializableHeaders, SerializableMethod}; +use net_traits::{SerializableUrl}; use cors::{allow_cross_origin_request, CORSRequest, RequestMode, AsyncCORSResponseListener}; use cors::CORSResponse; use util::str::DOMString; @@ -216,7 +217,7 @@ impl XMLHttpRequest { let mut load_data = self.load_data.borrow_mut().take().unwrap(); load_data.cors = Some(ResourceCORSData { preflight: self.req.preflight_flag, - origin: self.req.origin.clone() + origin: SerializableUrl(self.req.origin.clone()) }); XMLHttpRequest::initiate_async_xhr(self.xhr.clone(), self.script_chan.clone(), @@ -539,14 +540,15 @@ impl<'a> XMLHttpRequestMethods for &'a XMLHttpRequest { None => () } - load_data.preserved_headers = (*self.request_headers.borrow()).clone(); + load_data.preserved_headers = + SerializableHeaders((*self.request_headers.borrow()).clone()); if !load_data.preserved_headers.has::<Accept>() { let mime = Mime(mime::TopLevel::Star, mime::SubLevel::Star, vec![]); load_data.preserved_headers.set(Accept(vec![qitem(mime)])); } - load_data.method = (*self.request_method.borrow()).clone(); + load_data.method = SerializableMethod((*self.request_method.borrow()).clone()); // CORS stuff let global = self.global.root(); @@ -556,10 +558,13 @@ impl<'a> XMLHttpRequestMethods for &'a XMLHttpRequest { } else { RequestMode::CORS }; - let mut combined_headers = load_data.headers.clone(); + let mut combined_headers = (*load_data.headers).clone(); combined_headers.extend(load_data.preserved_headers.iter()); - let cors_request = CORSRequest::maybe_new(referer_url.clone(), load_data.url.clone(), mode, - load_data.method.clone(), combined_headers); + let cors_request = CORSRequest::maybe_new(referer_url.clone(), + (*load_data.url).clone(), + mode, + (*load_data.method).clone(), + combined_headers); match cors_request { Ok(None) => { let mut buf = String::new(); @@ -780,8 +785,10 @@ impl<'a> PrivateXMLHttpRequestHelpers for &'a XMLHttpRequest { _ => {} }; // XXXManishearth Clear cache entries in case of a network error - self.process_partial_response(XHRProgress::HeadersReceived(gen_id, - metadata.headers, metadata.status)); + self.process_partial_response(XHRProgress::HeadersReceived( + gen_id, + metadata.headers.map(|headers| headers.0), + metadata.status.map(|status| status.0))); Ok(()) } diff --git a/components/script/script_task.rs b/components/script/script_task.rs index 7deed84430d..192c922991a 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -67,8 +67,10 @@ use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, W use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType}; use msg::constellation_msg::Msg as ConstellationMsg; use msg::webdriver_msg::WebDriverScriptCommand; -use net_traits::{ResourceTask, LoadConsumer, ControlMsg, Metadata}; use net_traits::LoadData as NetLoadData; +use net_traits::{ResourceTask, LoadConsumer, ControlMsg, Metadata}; +use net_traits::{SerializableContentType, SerializableHeaders, SerializableMethod}; +use net_traits::{SerializableUrl}; use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageCacheResult}; use net_traits::storage_task::StorageTask; use profile_traits::mem::{self, Report, Reporter, ReporterRequest, ReportKind, ReportsChan}; @@ -1309,7 +1311,7 @@ impl ScriptTask { /// The entry point to document loading. Defines bindings, sets up the window and document /// objects, parses HTML and CSS, and kicks off initial layout. fn load(&self, metadata: Metadata, incomplete: InProgressLoad) -> Root<ServoHTMLParser> { - let final_url = metadata.final_url.clone(); + let final_url = (*metadata.final_url).clone(); debug!("ScriptTask: loading {} on page {:?}", incomplete.url.serialize(), incomplete.pipeline_id); // We should either be initializing a root page or loading a child page of an @@ -1415,7 +1417,11 @@ impl ScriptTask { }); let content_type = match metadata.content_type { - Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => Some("text/plain".to_owned()), + Some(SerializableContentType(ContentType(Mime(TopLevel::Text, + SubLevel::Plain, + _)))) => { + Some("text/plain".to_owned()) + } _ => None }; @@ -1690,10 +1696,10 @@ impl ScriptTask { } resource_task.send(ControlMsg::Load(NetLoadData { - url: load_data.url, - method: load_data.method, - headers: Headers::new(), - preserved_headers: load_data.headers, + url: SerializableUrl(load_data.url), + method: SerializableMethod(load_data.method), + headers: SerializableHeaders(Headers::new()), + preserved_headers: SerializableHeaders(load_data.headers), data: load_data.data, cors: None, pipeline_id: Some(id), |