net: Make most of the resource task messages serializable.

This commit is contained in:
Patrick Walton 2015-07-09 16:18:38 -07:00
parent 7e77285745
commit 9c9d7dc93b
15 changed files with 373 additions and 105 deletions

View file

@ -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
}
};

View file

@ -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();
}
}

View file

@ -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();
}
}
});

View file

@ -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(()))));
}

View file

@ -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();

View file

@ -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
}
};