aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2015-07-09 16:18:38 -0700
committerPatrick Walton <pcwalton@mimiga.net>2015-07-31 11:27:49 -0700
commit9c9d7dc93b1d64b1524eb2bdcbdc817319abc8b9 (patch)
treed03336f8dcd684ace3cea05033b49cd4e4bc4b16
parent7e772857458f60a68346ac1a7020ae51d65959a1 (diff)
downloadservo-9c9d7dc93b1d64b1524eb2bdcbdc817319abc8b9.tar.gz
servo-9c9d7dc93b1d64b1524eb2bdcbdc817319abc8b9.zip
net: Make most of the resource task messages serializable.
-rw-r--r--components/layout/layout_task.rs2
-rw-r--r--components/net/about_loader.rs18
-rw-r--r--components/net/data_loader.rs20
-rw-r--r--components/net/file_loader.rs12
-rw-r--r--components/net/http_loader.rs45
-rw-r--r--components/net/image_cache_task.rs4
-rw-r--r--components/net/resource_task.rs15
-rw-r--r--components/net_traits/lib.rs295
-rw-r--r--components/script/cors.rs4
-rw-r--r--components/script/dom/dedicatedworkerglobalscope.rs4
-rw-r--r--components/script/dom/document.rs10
-rw-r--r--components/script/dom/htmlscriptelement.rs2
-rw-r--r--components/script/dom/servohtmlparser.rs2
-rw-r--r--components/script/dom/xmlhttprequest.rs25
-rw-r--r--components/script/script_task.rs20
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),