mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
script: Make the resource task communication use IPC channels.
This commit is contained in:
parent
44d13f7fd4
commit
2aa5174246
35 changed files with 234 additions and 458 deletions
|
@ -66,10 +66,13 @@ git = "https://github.com/pcwalton/ipc-channel"
|
||||||
git = "https://github.com/ecoal95/rust-offscreen-rendering-context"
|
git = "https://github.com/ecoal95/rust-offscreen-rendering-context"
|
||||||
features = ["texture_surface"]
|
features = ["texture_surface"]
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
num = "0.1.24"
|
num = "0.1.24"
|
||||||
url = "0.2.36"
|
|
||||||
time = "0.1.17"
|
time = "0.1.17"
|
||||||
libc = "0.1"
|
libc = "0.1"
|
||||||
gleam = "0.1"
|
gleam = "0.1"
|
||||||
|
@ -80,3 +83,4 @@ core-graphics = "0.1"
|
||||||
|
|
||||||
[target.x86_64-apple-darwin.dependencies.core-text]
|
[target.x86_64-apple-darwin.dependencies.core-text]
|
||||||
git = "https://github.com/servo/core-text-rs"
|
git = "https://github.com/servo/core-text-rs"
|
||||||
|
|
||||||
|
|
|
@ -47,10 +47,13 @@ path = "../script_traits"
|
||||||
[dependencies.ipc-channel]
|
[dependencies.ipc-channel]
|
||||||
git = "https://github.com/pcwalton/ipc-channel"
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
url = "0.2.36"
|
|
||||||
time = "0.1.12"
|
time = "0.1.12"
|
||||||
bitflags = "0.3"
|
bitflags = "0.3"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
|
|
|
@ -62,11 +62,14 @@ features = [ "serde-serialization" ]
|
||||||
[dependencies.ipc-channel]
|
[dependencies.ipc-channel]
|
||||||
git = "https://github.com/pcwalton/ipc-channel"
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
encoding = "0.2"
|
encoding = "0.2"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
url = "0.2.36"
|
|
||||||
bitflags = "0.3"
|
bitflags = "0.3"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
libc = "0.1"
|
libc = "0.1"
|
||||||
|
|
|
@ -718,7 +718,7 @@ impl LayoutTask {
|
||||||
// TODO we don't really even need to load this if mq does not match
|
// TODO we don't really even need to load this if mq does not match
|
||||||
let (metadata, iter) = load_bytes_iter(pending);
|
let (metadata, iter) = load_bytes_iter(pending);
|
||||||
let protocol_encoding_label = metadata.charset.as_ref().map(|s| &**s);
|
let protocol_encoding_label = metadata.charset.as_ref().map(|s| &**s);
|
||||||
let final_url = metadata.final_url.0;
|
let final_url = metadata.final_url;
|
||||||
|
|
||||||
let sheet = Stylesheet::from_bytes_iter(iter,
|
let sheet = Stylesheet::from_bytes_iter(iter,
|
||||||
final_url,
|
final_url,
|
||||||
|
|
|
@ -28,8 +28,11 @@ path = "../util"
|
||||||
[dependencies.ipc-channel]
|
[dependencies.ipc-channel]
|
||||||
git = "https://github.com/pcwalton/ipc-channel"
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
url = "0.2.36"
|
|
||||||
euclid = "0.1"
|
euclid = "0.1"
|
||||||
serde = "0.4"
|
serde = "0.4"
|
||||||
serde_macros = "0.4"
|
serde_macros = "0.4"
|
||||||
|
|
|
@ -27,9 +27,12 @@ features = [ "serde-serialization" ]
|
||||||
[dependencies.ipc-channel]
|
[dependencies.ipc-channel]
|
||||||
git = "https://github.com/pcwalton/ipc-channel"
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
url = "0.2.36"
|
|
||||||
time = "0.1.17"
|
time = "0.1.17"
|
||||||
openssl="0.6.1"
|
openssl="0.6.1"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
|
@ -39,3 +42,4 @@ regex_macros = "0.1.8"
|
||||||
flate2 = "0.2.0"
|
flate2 = "0.2.0"
|
||||||
uuid = "0.1.16"
|
uuid = "0.1.16"
|
||||||
euclid = "0.1"
|
euclid = "0.1"
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use net_traits::{LoadData, Metadata, LoadConsumer, SerializableContentType, SerializableRawStatus};
|
use net_traits::{LoadData, Metadata, LoadConsumer};
|
||||||
use net_traits::{SerializableStringResult, SerializableUrl};
|
|
||||||
use net_traits::ProgressMsg::Done;
|
use net_traits::ProgressMsg::Done;
|
||||||
use mime_classifier::MIMEClassifier;
|
use mime_classifier::MIMEClassifier;
|
||||||
use resource_task::start_sending;
|
use resource_task::start_sending;
|
||||||
|
@ -23,14 +22,12 @@ pub fn factory(mut load_data: LoadData, start_chan: LoadConsumer, classifier: Ar
|
||||||
"blank" => {
|
"blank" => {
|
||||||
let chan = start_sending(start_chan, Metadata {
|
let chan = start_sending(start_chan, Metadata {
|
||||||
final_url: load_data.url,
|
final_url: load_data.url,
|
||||||
content_type: Some(SerializableContentType(ContentType(Mime(TopLevel::Text,
|
content_type: Some(ContentType(Mime(TopLevel::Text, SubLevel::Html, vec![]))),
|
||||||
SubLevel::Html,
|
|
||||||
vec![])))),
|
|
||||||
charset: Some("utf-8".to_string()),
|
charset: Some("utf-8".to_string()),
|
||||||
headers: None,
|
headers: None,
|
||||||
status: Some(SerializableRawStatus(RawStatus(200, "OK".into()))),
|
status: Some(RawStatus(200, "OK".into())),
|
||||||
});
|
});
|
||||||
chan.send(Done(SerializableStringResult(Ok(())))).unwrap();
|
chan.send(Done(Ok(()))).unwrap();
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
"crash" => panic!("Loading the about:crash URL."),
|
"crash" => panic!("Loading the about:crash URL."),
|
||||||
|
@ -38,11 +35,11 @@ pub fn factory(mut load_data: LoadData, start_chan: LoadConsumer, classifier: Ar
|
||||||
let mut path = resources_dir_path();
|
let mut path = resources_dir_path();
|
||||||
path.push("failure.html");
|
path.push("failure.html");
|
||||||
assert!(path.exists());
|
assert!(path.exists());
|
||||||
load_data.url = SerializableUrl(Url::from_file_path(&*path).unwrap());
|
load_data.url = Url::from_file_path(&*path).unwrap();
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
start_sending(start_chan, Metadata::default(load_data.url.0))
|
start_sending(start_chan, Metadata::default(load_data.url))
|
||||||
.send(Done(SerializableStringResult(Err("Unknown about: URL.".to_string()))))
|
.send(Done(Err("Unknown about: URL.".to_string())))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use net_traits::{LoadData, Metadata, LoadConsumer, SerializableStringResult};
|
use net_traits::{LoadData, Metadata, LoadConsumer};
|
||||||
use net_traits::ProgressMsg::{Payload, Done};
|
use net_traits::ProgressMsg::{Payload, Done};
|
||||||
use mime_classifier::MIMEClassifier;
|
use mime_classifier::MIMEClassifier;
|
||||||
use resource_task::start_sending;
|
use resource_task::start_sending;
|
||||||
|
@ -26,11 +26,11 @@ pub fn load(load_data: LoadData, start_chan: LoadConsumer) {
|
||||||
let url = load_data.url;
|
let url = load_data.url;
|
||||||
assert!(&*url.scheme == "data");
|
assert!(&*url.scheme == "data");
|
||||||
|
|
||||||
let mut metadata = Metadata::default((*url).clone());
|
let mut metadata = Metadata::default(url.clone());
|
||||||
|
|
||||||
// Split out content type and data.
|
// Split out content type and data.
|
||||||
let mut scheme_data = match url.scheme_data {
|
let mut scheme_data = match url.scheme_data {
|
||||||
SchemeData::NonRelative(ref scheme_data) => (*scheme_data).clone(),
|
SchemeData::NonRelative(scheme_data) => scheme_data,
|
||||||
_ => panic!("Expected a non-relative scheme URL.")
|
_ => panic!("Expected a non-relative scheme URL.")
|
||||||
};
|
};
|
||||||
match url.query {
|
match url.query {
|
||||||
|
@ -42,8 +42,8 @@ pub fn load(load_data: LoadData, start_chan: LoadConsumer) {
|
||||||
}
|
}
|
||||||
let parts: Vec<&str> = scheme_data.splitn(2, ',').collect();
|
let parts: Vec<&str> = scheme_data.splitn(2, ',').collect();
|
||||||
if parts.len() != 2 {
|
if parts.len() != 2 {
|
||||||
start_sending(start_chan, metadata).send(Done(SerializableStringResult(Err(
|
start_sending(start_chan,
|
||||||
"invalid data uri".to_string())))).unwrap();
|
metadata).send(Done(Err("invalid data uri".to_string()))).unwrap();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,16 +70,15 @@ pub fn load(load_data: LoadData, start_chan: LoadConsumer) {
|
||||||
let bytes = bytes.into_iter().filter(|&b| b != ' ' as u8).collect::<Vec<u8>>();
|
let bytes = bytes.into_iter().filter(|&b| b != ' ' as u8).collect::<Vec<u8>>();
|
||||||
match bytes.from_base64() {
|
match bytes.from_base64() {
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
progress_chan.send(Done(SerializableStringResult(Err(
|
progress_chan.send(Done(Err("non-base64 data uri".to_string()))).unwrap();
|
||||||
"non-base64 data uri".to_string())))).unwrap();
|
|
||||||
}
|
}
|
||||||
Ok(data) => {
|
Ok(data) => {
|
||||||
progress_chan.send(Payload(data)).unwrap();
|
progress_chan.send(Payload(data)).unwrap();
|
||||||
progress_chan.send(Done(SerializableStringResult(Ok(())))).unwrap();
|
progress_chan.send(Done(Ok(()))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
progress_chan.send(Payload(bytes)).unwrap();
|
progress_chan.send(Payload(bytes)).unwrap();
|
||||||
progress_chan.send(Done(SerializableStringResult(Ok(())))).unwrap();
|
progress_chan.send(Done(Ok(()))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use net_traits::{LoadData, Metadata, LoadConsumer, SerializableStringResult};
|
use net_traits::{LoadData, Metadata, LoadConsumer};
|
||||||
use net_traits::ProgressMsg::{Payload, Done};
|
use net_traits::ProgressMsg::{Payload, Done};
|
||||||
use mime_classifier::MIMEClassifier;
|
use mime_classifier::MIMEClassifier;
|
||||||
use resource_task::{start_sending, start_sending_sniffed, ProgressSender};
|
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;
|
let url = load_data.url;
|
||||||
assert!(&*url.scheme == "file");
|
assert!(&*url.scheme == "file");
|
||||||
spawn_named("file_loader".to_owned(), move || {
|
spawn_named("file_loader".to_owned(), move || {
|
||||||
let metadata = Metadata::default(url.0.clone());
|
let metadata = Metadata::default(url.clone());
|
||||||
let file_path: Result<PathBuf, ()> = url.to_file_path();
|
let file_path: Result<PathBuf, ()> = url.to_file_path();
|
||||||
match file_path {
|
match file_path {
|
||||||
Ok(file_path) => {
|
Ok(file_path) => {
|
||||||
|
@ -65,19 +65,17 @@ pub fn factory(load_data: LoadData, senders: LoadConsumer, classifier: Arc<MIMEC
|
||||||
Ok(ReadStatus::EOF) | Err(_) =>
|
Ok(ReadStatus::EOF) | Err(_) =>
|
||||||
(res.map(|_| ()), start_sending(senders, metadata)),
|
(res.map(|_| ()), start_sending(senders, metadata)),
|
||||||
};
|
};
|
||||||
progress_chan.send(Done(SerializableStringResult(res))).unwrap();
|
progress_chan.send(Done(res)).unwrap();
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let progress_chan = start_sending(senders, metadata);
|
let progress_chan = start_sending(senders, metadata);
|
||||||
progress_chan.send(Done(SerializableStringResult(Err(e.description()
|
progress_chan.send(Done(Err(e.description().to_string()))).unwrap();
|
||||||
.to_string()))))
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let progress_chan = start_sending(senders, metadata);
|
let progress_chan = start_sending(senders, metadata);
|
||||||
progress_chan.send(Done(SerializableStringResult(Err(url.to_string())))).unwrap();
|
progress_chan.send(Done(Err(url.to_string()))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,15 +2,14 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use net_traits::{ControlMsg, CookieSource, LoadData, Metadata, LoadConsumer, SerializableMethod};
|
use net_traits::{ControlMsg, CookieSource, LoadData, Metadata, LoadConsumer};
|
||||||
use net_traits::{SerializableHeaders, SerializableRawStatus, SerializableStringResult};
|
|
||||||
use net_traits::{SerializableUrl};
|
|
||||||
use net_traits::ProgressMsg::{Payload, Done};
|
use net_traits::ProgressMsg::{Payload, Done};
|
||||||
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent};
|
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent};
|
||||||
use mime_classifier::MIMEClassifier;
|
use mime_classifier::MIMEClassifier;
|
||||||
use resource_task::{start_sending_opt, start_sending_sniffed_opt};
|
use resource_task::{start_sending_opt, start_sending_sniffed_opt};
|
||||||
use hsts::{HSTSList, secure_url};
|
use hsts::{HSTSList, secure_url};
|
||||||
|
|
||||||
|
use ipc_channel::ipc::{self, IpcSender};
|
||||||
use log;
|
use log;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use file_loader;
|
use file_loader;
|
||||||
|
@ -38,7 +37,7 @@ use uuid;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::boxed::FnBox;
|
use std::boxed::FnBox;
|
||||||
|
|
||||||
pub fn factory(cookies_chan: Sender<ControlMsg>,
|
pub fn factory(cookies_chan: IpcSender<ControlMsg>,
|
||||||
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||||
hsts_list: Arc<Mutex<HSTSList>>)
|
hsts_list: Arc<Mutex<HSTSList>>)
|
||||||
-> Box<FnBox(LoadData, LoadConsumer, Arc<MIMEClassifier>) + Send> {
|
-> Box<FnBox(LoadData, LoadConsumer, Arc<MIMEClassifier>) + Send> {
|
||||||
|
@ -53,7 +52,7 @@ fn send_error(url: Url, err: String, start_chan: LoadConsumer) {
|
||||||
metadata.status = None;
|
metadata.status = None;
|
||||||
|
|
||||||
match start_sending_opt(start_chan, metadata) {
|
match start_sending_opt(start_chan, metadata) {
|
||||||
Ok(p) => p.send(Done(SerializableStringResult(Err(err)))).unwrap(),
|
Ok(p) => p.send(Done(Err(err))).unwrap(),
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -88,7 +87,7 @@ fn request_must_be_secured(hsts_list: &HSTSList, url: &Url) -> bool {
|
||||||
fn load(mut load_data: LoadData,
|
fn load(mut load_data: LoadData,
|
||||||
start_chan: LoadConsumer,
|
start_chan: LoadConsumer,
|
||||||
classifier: Arc<MIMEClassifier>,
|
classifier: Arc<MIMEClassifier>,
|
||||||
cookies_chan: Sender<ControlMsg>,
|
cookies_chan: IpcSender<ControlMsg>,
|
||||||
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||||
hsts_list: Arc<Mutex<HSTSList>>) {
|
hsts_list: Arc<Mutex<HSTSList>>) {
|
||||||
// FIXME: At the time of writing this FIXME, servo didn't have any central
|
// FIXME: At the time of writing this FIXME, servo didn't have any central
|
||||||
|
@ -96,7 +95,7 @@ fn load(mut load_data: LoadData,
|
||||||
// repository DOES exist, please update this constant to use it.
|
// repository DOES exist, please update this constant to use it.
|
||||||
let max_redirects = 50;
|
let max_redirects = 50;
|
||||||
let mut iters = 0;
|
let mut iters = 0;
|
||||||
let mut url = load_data.url.0.clone();
|
let mut url = load_data.url.clone();
|
||||||
let mut redirected_to = HashSet::new();
|
let mut redirected_to = HashSet::new();
|
||||||
|
|
||||||
// If the URL is a view-source scheme then the scheme data contains the
|
// If the URL is a view-source scheme then the scheme data contains the
|
||||||
|
@ -156,9 +155,7 @@ reason: \"certificate verify failed\" }]))";
|
||||||
&HttpsConnector::new(Openssl { context: Arc::new(context) }))
|
&HttpsConnector::new(Openssl { context: Arc::new(context) }))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut req = match Request::with_connector(load_data.method.0.clone(),
|
let mut req = match req {
|
||||||
url.clone(),
|
|
||||||
&mut connector) {
|
|
||||||
Ok(req) => req,
|
Ok(req) => req,
|
||||||
Err(HttpError::Io(ref io_error)) if (
|
Err(HttpError::Io(ref io_error)) if (
|
||||||
io_error.kind() == io::ErrorKind::Other &&
|
io_error.kind() == io::ErrorKind::Other &&
|
||||||
|
@ -187,11 +184,11 @@ reason: \"certificate verify failed\" }]))";
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=216828 .
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=216828 .
|
||||||
// Only preserve ones which have been explicitly marked as such.
|
// Only preserve ones which have been explicitly marked as such.
|
||||||
if iters == 1 {
|
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());
|
combined_headers.extend(load_data.preserved_headers.iter());
|
||||||
*req.headers_mut() = combined_headers;
|
*req.headers_mut() = combined_headers;
|
||||||
} else {
|
} else {
|
||||||
*req.headers_mut() = (*load_data.preserved_headers).clone();
|
*req.headers_mut() = load_data.preserved_headers.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
req.headers_mut().set(host);
|
req.headers_mut().set(host);
|
||||||
|
@ -206,8 +203,8 @@ reason: \"certificate verify failed\" }]))";
|
||||||
req.headers_mut().set(accept);
|
req.headers_mut().set(accept);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = ipc::channel().unwrap();
|
||||||
cookies_chan.send(ControlMsg::GetCookiesForUrl(SerializableUrl(url.clone()),
|
cookies_chan.send(ControlMsg::GetCookiesForUrl(url.clone(),
|
||||||
tx,
|
tx,
|
||||||
CookieSource::HTTP)).unwrap();
|
CookieSource::HTTP)).unwrap();
|
||||||
if let Some(cookie_list) = rx.recv().unwrap() {
|
if let Some(cookie_list) = rx.recv().unwrap() {
|
||||||
|
@ -220,7 +217,7 @@ reason: \"certificate verify failed\" }]))";
|
||||||
req.headers_mut().set_raw("Accept-Encoding".to_owned(), vec![b"gzip, deflate".to_vec()]);
|
req.headers_mut().set_raw("Accept-Encoding".to_owned(), vec![b"gzip, deflate".to_vec()]);
|
||||||
}
|
}
|
||||||
if log_enabled!(log::LogLevel::Info) {
|
if log_enabled!(log::LogLevel::Info) {
|
||||||
info!("{}", load_data.method.0);
|
info!("{}", load_data.method);
|
||||||
for header in req.headers().iter() {
|
for header in req.headers().iter() {
|
||||||
info!(" - {}", header);
|
info!(" - {}", header);
|
||||||
}
|
}
|
||||||
|
@ -248,7 +245,7 @@ reason: \"certificate verify failed\" }]))";
|
||||||
writer
|
writer
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
match *load_data.method {
|
match load_data.method {
|
||||||
Method::Get | Method::Head => (),
|
Method::Get | Method::Head => (),
|
||||||
_ => req.headers_mut().set(ContentLength(0))
|
_ => req.headers_mut().set(ContentLength(0))
|
||||||
}
|
}
|
||||||
|
@ -266,9 +263,9 @@ reason: \"certificate verify failed\" }]))";
|
||||||
// TODO: Do this only if load_data has some pipeline_id, and send the pipeline_id in the message
|
// 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();
|
let request_id = uuid::Uuid::new_v4().to_simple_string();
|
||||||
if let Some(ref chan) = devtools_chan {
|
if let Some(ref chan) = devtools_chan {
|
||||||
let net_event = NetworkEvent::HttpRequest((*load_data.url).clone(),
|
let net_event = NetworkEvent::HttpRequest(load_data.url.clone(),
|
||||||
(*load_data.method).clone(),
|
load_data.method.clone(),
|
||||||
(*load_data.headers).clone(),
|
load_data.headers.clone(),
|
||||||
load_data.data.clone());
|
load_data.data.clone());
|
||||||
chan.send(DevtoolsControlMsg::FromChrome(
|
chan.send(DevtoolsControlMsg::FromChrome(
|
||||||
ChromeToDevtoolsControlMsg::NetworkEventMessage(request_id.clone(),
|
ChromeToDevtoolsControlMsg::NetworkEventMessage(request_id.clone(),
|
||||||
|
@ -294,7 +291,7 @@ reason: \"certificate verify failed\" }]))";
|
||||||
if let Some(cookies) = response.headers.get_raw("set-cookie") {
|
if let Some(cookies) = response.headers.get_raw("set-cookie") {
|
||||||
for cookie in cookies.iter() {
|
for cookie in cookies.iter() {
|
||||||
if let Ok(cookies) = String::from_utf8(cookie.clone()) {
|
if let Ok(cookies) = String::from_utf8(cookie.clone()) {
|
||||||
cookies_chan.send(ControlMsg::SetCookiesForUrl(SerializableUrl(url.clone()),
|
cookies_chan.send(ControlMsg::SetCookiesForUrl(url.clone(),
|
||||||
cookies,
|
cookies,
|
||||||
CookieSource::HTTP)).unwrap();
|
CookieSource::HTTP)).unwrap();
|
||||||
}
|
}
|
||||||
|
@ -332,10 +329,10 @@ reason: \"certificate verify failed\" }]))";
|
||||||
|
|
||||||
// According to https://tools.ietf.org/html/rfc7231#section-6.4.2,
|
// According to https://tools.ietf.org/html/rfc7231#section-6.4.2,
|
||||||
// historically UAs have rewritten POST->GET on 301 and 302 responses.
|
// 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::MovedPermanently ||
|
||||||
response.status == StatusCode::Found) {
|
response.status == StatusCode::Found) {
|
||||||
load_data.method = SerializableMethod(Method::Get);
|
load_data.method = Method::Get;
|
||||||
}
|
}
|
||||||
|
|
||||||
if redirected_to.contains(&url) {
|
if redirected_to.contains(&url) {
|
||||||
|
@ -359,8 +356,8 @@ reason: \"certificate verify failed\" }]))";
|
||||||
Some(&ContentType(ref mime)) => Some(mime),
|
Some(&ContentType(ref mime)) => Some(mime),
|
||||||
None => None
|
None => None
|
||||||
});
|
});
|
||||||
metadata.headers = Some(SerializableHeaders(adjusted_headers));
|
metadata.headers = Some(adjusted_headers);
|
||||||
metadata.status = Some(SerializableRawStatus(response.status_raw().clone()));
|
metadata.status = Some(response.status_raw().clone());
|
||||||
|
|
||||||
let mut encoding_str: Option<String> = None;
|
let mut encoding_str: Option<String> = None;
|
||||||
//FIXME: Implement Content-Encoding Header https://github.com/hyperium/hyper/issues/391
|
//FIXME: Implement Content-Encoding Header https://github.com/hyperium/hyper/issues/391
|
||||||
|
@ -396,7 +393,7 @@ reason: \"certificate verify failed\" }]))";
|
||||||
send_data(&mut response_decoding, start_chan, metadata, classifier);
|
send_data(&mut response_decoding, start_chan, metadata, classifier);
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
send_error((*metadata.final_url).clone(), err.to_string(), start_chan);
|
send_error(metadata.final_url, err.to_string(), start_chan);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,5 +442,5 @@ fn send_data<R: Read>(reader: &mut R,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = progress_chan.send(Done(SerializableStringResult(Ok(()))));
|
let _ = progress_chan.send(Done(Ok(())));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::mpsc::{channel, Sender, Receiver, Select};
|
use std::sync::mpsc::{channel, Sender, Receiver, Select};
|
||||||
use std::thread;
|
|
||||||
use util::resource_files::resources_dir_path;
|
use util::resource_files::resources_dir_path;
|
||||||
use util::task::spawn_named;
|
use util::task::spawn_named;
|
||||||
use util::taskpool::TaskPool;
|
use util::taskpool::TaskPool;
|
||||||
|
@ -98,23 +97,6 @@ struct ResourceLoadInfo {
|
||||||
url: Url,
|
url: Url,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ResourceListener {
|
|
||||||
url: Url,
|
|
||||||
sender: Sender<ResourceLoadInfo>,
|
|
||||||
receiver: Receiver<ResponseAction>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ResourceListener {
|
|
||||||
fn run(&self) {
|
|
||||||
while let Ok(action) = self.receiver.recv() {
|
|
||||||
self.sender.send(ResourceLoadInfo {
|
|
||||||
action: action,
|
|
||||||
url: self.url.clone(),
|
|
||||||
}).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Implementation of the image cache
|
/// Implementation of the image cache
|
||||||
struct ImageCache {
|
struct ImageCache {
|
||||||
// Receive commands from clients
|
// Receive commands from clients
|
||||||
|
@ -252,10 +234,10 @@ impl ImageCache {
|
||||||
pending_load.bytes.push_all(&data);
|
pending_load.bytes.push_all(&data);
|
||||||
}
|
}
|
||||||
ResponseAction::ResponseComplete(result) => {
|
ResponseAction::ResponseComplete(result) => {
|
||||||
match *result {
|
match result {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let pending_load = self.pending_loads.get_mut(&msg.url).unwrap();
|
let pending_load = self.pending_loads.get_mut(&msg.url).unwrap();
|
||||||
pending_load.result = Some((*result).clone());
|
pending_load.result = Some(result);
|
||||||
|
|
||||||
let bytes = mem::replace(&mut pending_load.bytes, vec!());
|
let bytes = mem::replace(&mut pending_load.bytes, vec!());
|
||||||
let url = msg.url.clone();
|
let url = msg.url.clone();
|
||||||
|
@ -334,17 +316,20 @@ impl ImageCache {
|
||||||
e.insert(pending_load);
|
e.insert(pending_load);
|
||||||
|
|
||||||
let load_data = LoadData::new(url.clone(), None);
|
let load_data = LoadData::new(url.clone(), None);
|
||||||
let (action_sender, action_receiver) = channel();
|
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||||
let listener = box ResourceListener {
|
let response_target = AsyncResponseTarget {
|
||||||
url: url,
|
sender: action_sender,
|
||||||
sender: self.progress_sender.clone(),
|
|
||||||
receiver: action_receiver,
|
|
||||||
};
|
};
|
||||||
let msg = ControlMsg::Load(load_data,
|
let msg = ControlMsg::Load(load_data,
|
||||||
LoadConsumer::Listener(AsyncResponseTarget {
|
LoadConsumer::Listener(response_target));
|
||||||
sender: action_sender,
|
let progress_sender = self.progress_sender.clone();
|
||||||
}));
|
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
|
||||||
thread::spawn(move || listener.run());
|
let action: ResponseAction = message.to().unwrap();
|
||||||
|
progress_sender.send(ResourceLoadInfo {
|
||||||
|
action: action,
|
||||||
|
url: url.clone(),
|
||||||
|
}).unwrap();
|
||||||
|
});
|
||||||
self.resource_task.send(msg).unwrap();
|
self.resource_task.send(msg).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,8 @@ use cookie_storage::CookieStorage;
|
||||||
use cookie;
|
use cookie;
|
||||||
use mime_classifier::MIMEClassifier;
|
use mime_classifier::MIMEClassifier;
|
||||||
|
|
||||||
use net_traits::{ControlMsg, LoadData, LoadResponse, LoadConsumer};
|
use net_traits::{ControlMsg, LoadData, LoadResponse, LoadConsumer, CookieSource};
|
||||||
use net_traits::{Metadata, ProgressMsg, ResourceTask, AsyncResponseTarget, ResponseAction};
|
use net_traits::{Metadata, ProgressMsg, ResourceTask, AsyncResponseTarget, ResponseAction};
|
||||||
use net_traits::{CookieSource, SerializableContentType, SerializableStringResult};
|
|
||||||
use net_traits::ProgressMsg::Done;
|
use net_traits::ProgressMsg::Done;
|
||||||
use util::opts;
|
use util::opts;
|
||||||
use util::task::spawn_named;
|
use util::task::spawn_named;
|
||||||
|
@ -25,6 +24,7 @@ use hsts::{HSTSList, HSTSEntry, preload_hsts_domains};
|
||||||
use devtools_traits::{DevtoolsControlMsg};
|
use devtools_traits::{DevtoolsControlMsg};
|
||||||
use hyper::header::{ContentType, Header, SetCookie, UserAgent};
|
use hyper::header::{ContentType, Header, SetCookie, UserAgent};
|
||||||
use hyper::mime::{Mime, TopLevel, SubLevel};
|
use hyper::mime::{Mime, TopLevel, SubLevel};
|
||||||
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
|
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
@ -35,7 +35,7 @@ use std::fs::File;
|
||||||
use std::io::{BufReader, Read};
|
use std::io::{BufReader, Read};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
use std::sync::mpsc::{channel, Sender};
|
||||||
|
|
||||||
static mut HOST_TABLE: Option<*mut HashMap<String, String>> = None;
|
static mut HOST_TABLE: Option<*mut HashMap<String, String>> = None;
|
||||||
pub static IPV4_REGEX: Regex = regex!(
|
pub static IPV4_REGEX: Regex = regex!(
|
||||||
|
@ -68,7 +68,7 @@ pub fn global_init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ProgressSender {
|
pub enum ProgressSender {
|
||||||
Channel(Sender<ProgressMsg>),
|
Channel(IpcSender<ProgressMsg>),
|
||||||
Listener(AsyncResponseTarget),
|
Listener(AsyncResponseTarget),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,16 +126,14 @@ pub fn start_sending_sniffed_opt(start_chan: LoadConsumer, mut metadata: Metadat
|
||||||
}
|
}
|
||||||
|
|
||||||
let supplied_type =
|
let supplied_type =
|
||||||
metadata.content_type.map(|SerializableContentType(ContentType(Mime(toplevel,
|
metadata.content_type.map(|ContentType(Mime(toplevel, sublevel, _))| {
|
||||||
sublevel,
|
|
||||||
_)))| {
|
|
||||||
(format!("{}", toplevel), format!("{}", sublevel))
|
(format!("{}", toplevel), format!("{}", sublevel))
|
||||||
});
|
});
|
||||||
metadata.content_type = classifier.classify(nosniff, check_for_apache_bug, &supplied_type,
|
metadata.content_type = classifier.classify(nosniff, check_for_apache_bug, &supplied_type,
|
||||||
&partial_body).map(|(toplevel, sublevel)| {
|
&partial_body).map(|(toplevel, sublevel)| {
|
||||||
let mime_tp: TopLevel = toplevel.parse().unwrap();
|
let mime_tp: TopLevel = toplevel.parse().unwrap();
|
||||||
let mime_sb: SubLevel = sublevel.parse().unwrap();
|
let mime_sb: SubLevel = sublevel.parse().unwrap();
|
||||||
SerializableContentType(ContentType(Mime(mime_tp, mime_sb, vec!())))
|
ContentType(Mime(mime_tp, mime_sb, vec!()))
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -147,7 +145,7 @@ pub fn start_sending_sniffed_opt(start_chan: LoadConsumer, mut metadata: Metadat
|
||||||
pub fn start_sending_opt(start_chan: LoadConsumer, metadata: Metadata) -> Result<ProgressSender, ()> {
|
pub fn start_sending_opt(start_chan: LoadConsumer, metadata: Metadata) -> Result<ProgressSender, ()> {
|
||||||
match start_chan {
|
match start_chan {
|
||||||
LoadConsumer::Channel(start_chan) => {
|
LoadConsumer::Channel(start_chan) => {
|
||||||
let (progress_chan, progress_port) = channel();
|
let (progress_chan, progress_port) = ipc::channel().unwrap();
|
||||||
let result = start_chan.send(LoadResponse {
|
let result = start_chan.send(LoadResponse {
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
progress_port: progress_port,
|
progress_port: progress_port,
|
||||||
|
@ -172,7 +170,7 @@ pub fn new_resource_task(user_agent: Option<String>,
|
||||||
None => HSTSList::new()
|
None => HSTSList::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
let (setup_chan, setup_port) = channel();
|
let (setup_chan, setup_port) = ipc::channel().unwrap();
|
||||||
let setup_chan_clone = setup_chan.clone();
|
let setup_chan_clone = setup_chan.clone();
|
||||||
spawn_named("ResourceManager".to_owned(), move || {
|
spawn_named("ResourceManager".to_owned(), move || {
|
||||||
let resource_manager = ResourceManager::new(
|
let resource_manager = ResourceManager::new(
|
||||||
|
@ -222,7 +220,7 @@ pub fn replace_hosts(mut load_data: LoadData, host_table: *mut HashMap<String, S
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ResourceChannelManager {
|
struct ResourceChannelManager {
|
||||||
from_client: Receiver<ControlMsg>,
|
from_client: IpcReceiver<ControlMsg>,
|
||||||
resource_manager: ResourceManager
|
resource_manager: ResourceManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,19 +250,18 @@ impl ResourceChannelManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ResourceManager {
|
struct ResourceManager {
|
||||||
user_agent: Option<String>,
|
user_agent: Option<String>,
|
||||||
cookie_storage: CookieStorage,
|
cookie_storage: CookieStorage,
|
||||||
// TODO: Can this be de-coupled?
|
resource_task: IpcSender<ControlMsg>,
|
||||||
resource_task: Sender<ControlMsg>,
|
|
||||||
mime_classifier: Arc<MIMEClassifier>,
|
mime_classifier: Arc<MIMEClassifier>,
|
||||||
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
devtools_chan: Option<Sender<DevtoolsControlMsg>>,
|
||||||
hsts_list: Arc<Mutex<HSTSList>>
|
hsts_list: Arc<Mutex<HSTSList>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResourceManager {
|
impl ResourceManager {
|
||||||
pub fn new(user_agent: Option<String>,
|
fn new(user_agent: Option<String>,
|
||||||
resource_task: Sender<ControlMsg>,
|
resource_task: IpcSender<ControlMsg>,
|
||||||
hsts_list: HSTSList,
|
hsts_list: HSTSList,
|
||||||
devtools_channel: Option<Sender<DevtoolsControlMsg>>) -> ResourceManager {
|
devtools_channel: Option<Sender<DevtoolsControlMsg>>) -> ResourceManager {
|
||||||
ResourceManager {
|
ResourceManager {
|
||||||
|
@ -278,7 +275,6 @@ impl ResourceManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl ResourceManager {
|
impl ResourceManager {
|
||||||
fn set_cookies_for_url(&mut self, request: Url, cookie_list: String, source: CookieSource) {
|
fn set_cookies_for_url(&mut self, request: Url, cookie_list: String, source: CookieSource) {
|
||||||
let header = Header::parse_header(&[cookie_list.into_bytes()]);
|
let header = Header::parse_header(&[cookie_list.into_bytes()]);
|
||||||
|
@ -325,9 +321,8 @@ impl ResourceManager {
|
||||||
"about" => from_factory(about_loader::factory),
|
"about" => from_factory(about_loader::factory),
|
||||||
_ => {
|
_ => {
|
||||||
debug!("resource_task: no loader for scheme {}", load_data.url.scheme);
|
debug!("resource_task: no loader for scheme {}", load_data.url.scheme);
|
||||||
start_sending(consumer, Metadata::default((*load_data.url).clone()))
|
start_sending(consumer, Metadata::default(load_data.url))
|
||||||
.send(ProgressMsg::Done(SerializableStringResult(Err(
|
.send(ProgressMsg::Done(Err("no loader for scheme".to_string()))).unwrap();
|
||||||
"no loader for scheme".to_string())))).unwrap();
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,6 +31,10 @@ features = [ "serde_serialization" ]
|
||||||
[dependencies.ipc-channel]
|
[dependencies.ipc-channel]
|
||||||
git = "https://github.com/pcwalton/ipc-channel"
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
euclid = "0.1"
|
euclid = "0.1"
|
||||||
|
|
|
@ -22,20 +22,15 @@ extern crate url;
|
||||||
extern crate util;
|
extern crate util;
|
||||||
extern crate msg;
|
extern crate msg;
|
||||||
|
|
||||||
use hyper::header::{ContentType, Header, Headers, HeadersItems};
|
use hyper::header::{ContentType, Headers};
|
||||||
use hyper::http::RawStatus;
|
use hyper::http::RawStatus;
|
||||||
use hyper::method::Method;
|
use hyper::method::Method;
|
||||||
use hyper::mime::{Mime, Attr};
|
use hyper::mime::{Mime, Attr};
|
||||||
|
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
|
||||||
use msg::constellation_msg::{PipelineId};
|
use msg::constellation_msg::{PipelineId};
|
||||||
use serde::de;
|
use serde::{Deserializer, Serializer};
|
||||||
use serde::ser;
|
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
|
||||||
use url::Url;
|
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;
|
use std::thread;
|
||||||
|
|
||||||
pub mod image_cache_task;
|
pub mod image_cache_task;
|
||||||
|
@ -52,12 +47,12 @@ pub mod image {
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct LoadData {
|
pub struct LoadData {
|
||||||
pub url: SerializableUrl,
|
pub url: Url,
|
||||||
pub method: SerializableMethod,
|
pub method: Method,
|
||||||
/// Headers that will apply to the initial request only
|
/// Headers that will apply to the initial request only
|
||||||
pub headers: SerializableHeaders,
|
pub headers: Headers,
|
||||||
/// Headers that will apply to the initial request and any redirects
|
/// Headers that will apply to the initial request and any redirects
|
||||||
pub preserved_headers: SerializableHeaders,
|
pub preserved_headers: Headers,
|
||||||
pub data: Option<Vec<u8>>,
|
pub data: Option<Vec<u8>>,
|
||||||
pub cors: Option<ResourceCORSData>,
|
pub cors: Option<ResourceCORSData>,
|
||||||
pub pipeline_id: Option<PipelineId>,
|
pub pipeline_id: Option<PipelineId>,
|
||||||
|
@ -66,10 +61,10 @@ pub struct LoadData {
|
||||||
impl LoadData {
|
impl LoadData {
|
||||||
pub fn new(url: Url, id: Option<PipelineId>) -> LoadData {
|
pub fn new(url: Url, id: Option<PipelineId>) -> LoadData {
|
||||||
LoadData {
|
LoadData {
|
||||||
url: SerializableUrl(url),
|
url: url,
|
||||||
method: SerializableMethod(Method::Get),
|
method: Method::Get,
|
||||||
headers: SerializableHeaders(Headers::new()),
|
headers: Headers::new(),
|
||||||
preserved_headers: SerializableHeaders(Headers::new()),
|
preserved_headers: Headers::new(),
|
||||||
data: None,
|
data: None,
|
||||||
cors: None,
|
cors: None,
|
||||||
pipeline_id: id,
|
pipeline_id: id,
|
||||||
|
@ -98,7 +93,7 @@ pub enum ResponseAction {
|
||||||
/// Invoke data_available
|
/// Invoke data_available
|
||||||
DataAvailable(Vec<u8>),
|
DataAvailable(Vec<u8>),
|
||||||
/// Invoke response_complete
|
/// Invoke response_complete
|
||||||
ResponseComplete(SerializableStringResult)
|
ResponseComplete(Result<(), String>)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResponseAction {
|
impl ResponseAction {
|
||||||
|
@ -107,15 +102,16 @@ impl ResponseAction {
|
||||||
match self {
|
match self {
|
||||||
ResponseAction::HeadersAvailable(m) => listener.headers_available(m),
|
ResponseAction::HeadersAvailable(m) => listener.headers_available(m),
|
||||||
ResponseAction::DataAvailable(d) => listener.data_available(d),
|
ResponseAction::DataAvailable(d) => listener.data_available(d),
|
||||||
ResponseAction::ResponseComplete(r) => listener.response_complete(r.0),
|
ResponseAction::ResponseComplete(r) => listener.response_complete(r),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A target for async networking events. Commonly used to dispatch a runnable event to another
|
/// A target for async networking events. Commonly used to dispatch a runnable event to another
|
||||||
/// thread storing the wrapped closure for later execution.
|
/// thread storing the wrapped closure for later execution.
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct AsyncResponseTarget {
|
pub struct AsyncResponseTarget {
|
||||||
pub sender: Sender<ResponseAction>,
|
pub sender: IpcSender<ResponseAction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncResponseTarget {
|
impl AsyncResponseTarget {
|
||||||
|
@ -125,27 +121,29 @@ impl AsyncResponseTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper for a network load that can either be channel or event-based.
|
/// A wrapper for a network load that can either be channel or event-based.
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum LoadConsumer {
|
pub enum LoadConsumer {
|
||||||
Channel(Sender<LoadResponse>),
|
Channel(IpcSender<LoadResponse>),
|
||||||
Listener(AsyncResponseTarget),
|
Listener(AsyncResponseTarget),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handle to a resource task
|
/// Handle to a resource task
|
||||||
pub type ResourceTask = Sender<ControlMsg>;
|
pub type ResourceTask = IpcSender<ControlMsg>;
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone)]
|
#[derive(PartialEq, Copy, Clone, Deserialize, Serialize)]
|
||||||
pub enum IncludeSubdomains {
|
pub enum IncludeSubdomains {
|
||||||
Included,
|
Included,
|
||||||
NotIncluded
|
NotIncluded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum ControlMsg {
|
pub enum ControlMsg {
|
||||||
/// Request the data associated with a particular URL
|
/// Request the data associated with a particular URL
|
||||||
Load(LoadData, LoadConsumer),
|
Load(LoadData, LoadConsumer),
|
||||||
/// Store a set of cookies for a given originating URL
|
/// Store a set of cookies for a given originating URL
|
||||||
SetCookiesForUrl(SerializableUrl, String, CookieSource),
|
SetCookiesForUrl(Url, String, CookieSource),
|
||||||
/// Retrieve the stored cookies for a given URL
|
/// Retrieve the stored cookies for a given URL
|
||||||
GetCookiesForUrl(SerializableUrl, Sender<Option<String>>, CookieSource),
|
GetCookiesForUrl(Url, IpcSender<Option<String>>, CookieSource),
|
||||||
/// Store a domain's STS information
|
/// Store a domain's STS information
|
||||||
SetHSTSEntryForHost(String, IncludeSubdomains, Option<u64>),
|
SetHSTSEntryForHost(String, IncludeSubdomains, Option<u64>),
|
||||||
Exit
|
Exit
|
||||||
|
@ -191,10 +189,10 @@ impl PendingAsyncLoad {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initiate the network request associated with this pending load.
|
/// Initiate the network request associated with this pending load.
|
||||||
pub fn load(mut self) -> Receiver<LoadResponse> {
|
pub fn load(mut self) -> IpcReceiver<LoadResponse> {
|
||||||
self.guard.neuter();
|
self.guard.neuter();
|
||||||
let load_data = LoadData::new(self.url, self.pipeline);
|
let load_data = LoadData::new(self.url, self.pipeline);
|
||||||
let (sender, receiver) = channel();
|
let (sender, receiver) = ipc::channel().unwrap();
|
||||||
let consumer = LoadConsumer::Channel(sender);
|
let consumer = LoadConsumer::Channel(sender);
|
||||||
self.resource_task.send(ControlMsg::Load(load_data, consumer)).unwrap();
|
self.resource_task.send(ControlMsg::Load(load_data, consumer)).unwrap();
|
||||||
receiver
|
receiver
|
||||||
|
@ -214,11 +212,12 @@ impl PendingAsyncLoad {
|
||||||
///
|
///
|
||||||
/// Even if loading fails immediately, we send one of these and the
|
/// Even if loading fails immediately, we send one of these and the
|
||||||
/// progress_port will provide the error.
|
/// progress_port will provide the error.
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct LoadResponse {
|
pub struct LoadResponse {
|
||||||
/// Metadata, such as from HTTP headers.
|
/// Metadata, such as from HTTP headers.
|
||||||
pub metadata: Metadata,
|
pub metadata: Metadata,
|
||||||
/// Port for reading data.
|
/// Port for reading data.
|
||||||
pub progress_port: Receiver<ProgressMsg>,
|
pub progress_port: IpcReceiver<ProgressMsg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
|
@ -226,38 +225,38 @@ pub struct ResourceCORSData {
|
||||||
/// CORS Preflight flag
|
/// CORS Preflight flag
|
||||||
pub preflight: bool,
|
pub preflight: bool,
|
||||||
/// Origin of CORS Request
|
/// Origin of CORS Request
|
||||||
pub origin: SerializableUrl,
|
pub origin: Url,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Metadata about a loaded resource, such as is obtained from HTTP headers.
|
/// Metadata about a loaded resource, such as is obtained from HTTP headers.
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct Metadata {
|
pub struct Metadata {
|
||||||
/// Final URL after redirects.
|
/// Final URL after redirects.
|
||||||
pub final_url: SerializableUrl,
|
pub final_url: Url,
|
||||||
|
|
||||||
/// MIME type / subtype.
|
/// MIME type / subtype.
|
||||||
pub content_type: Option<(SerializableContentType)>,
|
pub content_type: Option<(ContentType)>,
|
||||||
|
|
||||||
/// Character set.
|
/// Character set.
|
||||||
pub charset: Option<String>,
|
pub charset: Option<String>,
|
||||||
|
|
||||||
/// Headers
|
/// Headers
|
||||||
pub headers: Option<SerializableHeaders>,
|
pub headers: Option<Headers>,
|
||||||
|
|
||||||
/// HTTP Status
|
/// HTTP Status
|
||||||
pub status: Option<SerializableRawStatus>,
|
pub status: Option<RawStatus>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Metadata {
|
impl Metadata {
|
||||||
/// Metadata with defaults for everything optional.
|
/// Metadata with defaults for everything optional.
|
||||||
pub fn default(url: Url) -> Self {
|
pub fn default(url: Url) -> Self {
|
||||||
Metadata {
|
Metadata {
|
||||||
final_url: SerializableUrl(url),
|
final_url: url,
|
||||||
content_type: None,
|
content_type: None,
|
||||||
charset: None,
|
charset: None,
|
||||||
headers: None,
|
headers: None,
|
||||||
// https://fetch.spec.whatwg.org/#concept-response-status-message
|
// https://fetch.spec.whatwg.org/#concept-response-status-message
|
||||||
status: Some(SerializableRawStatus(RawStatus(200, "OK".into()))),
|
status: Some(RawStatus(200, "OK".into())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,7 +265,7 @@ impl Metadata {
|
||||||
match content_type {
|
match content_type {
|
||||||
None => (),
|
None => (),
|
||||||
Some(mime) => {
|
Some(mime) => {
|
||||||
self.content_type = Some(SerializableContentType(ContentType(mime.clone())));
|
self.content_type = Some(ContentType(mime.clone()));
|
||||||
let &Mime(_, _, ref parameters) = mime;
|
let &Mime(_, _, ref parameters) = mime;
|
||||||
for &(ref k, ref v) in parameters.iter() {
|
for &(ref k, ref v) in parameters.iter() {
|
||||||
if &Attr::Charset == k {
|
if &Attr::Charset == k {
|
||||||
|
@ -293,24 +292,23 @@ pub enum ProgressMsg {
|
||||||
/// Binary data - there may be multiple of these
|
/// Binary data - there may be multiple of these
|
||||||
Payload(Vec<u8>),
|
Payload(Vec<u8>),
|
||||||
/// Indicates loading is complete, either successfully or not
|
/// Indicates loading is complete, either successfully or not
|
||||||
Done(SerializableStringResult)
|
Done(Result<(), String>)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function for synchronously loading a whole resource.
|
/// Convenience function for synchronously loading a whole resource.
|
||||||
pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
||||||
-> Result<(Metadata, Vec<u8>), String> {
|
-> Result<(Metadata, Vec<u8>), String> {
|
||||||
let (start_chan, start_port) = channel();
|
let (start_chan, start_port) = ipc::channel().unwrap();
|
||||||
resource_task.send(ControlMsg::Load(LoadData::new(url, None), LoadConsumer::Channel(start_chan))).unwrap();
|
resource_task.send(ControlMsg::Load(LoadData::new(url, None),
|
||||||
|
LoadConsumer::Channel(start_chan))).unwrap();
|
||||||
let response = start_port.recv().unwrap();
|
let response = start_port.recv().unwrap();
|
||||||
|
|
||||||
let mut buf = vec!();
|
let mut buf = vec!();
|
||||||
loop {
|
loop {
|
||||||
match response.progress_port.recv().unwrap() {
|
match response.progress_port.recv().unwrap() {
|
||||||
ProgressMsg::Payload(data) => buf.push_all(&data),
|
ProgressMsg::Payload(data) => buf.push_all(&data),
|
||||||
ProgressMsg::Done(SerializableStringResult(Ok(()))) => {
|
ProgressMsg::Done(Ok(())) => return Ok((response.metadata, buf)),
|
||||||
return Ok((response.metadata, buf))
|
ProgressMsg::Done(Err(e)) => return Err(e)
|
||||||
}
|
|
||||||
ProgressMsg::Done(SerializableStringResult(Err(e))) => return Err(e)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,13 +317,15 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
||||||
pub fn load_bytes_iter(pending: PendingAsyncLoad) -> (Metadata, ProgressMsgPortIterator) {
|
pub fn load_bytes_iter(pending: PendingAsyncLoad) -> (Metadata, ProgressMsgPortIterator) {
|
||||||
let input_port = pending.load();
|
let input_port = pending.load();
|
||||||
let response = input_port.recv().unwrap();
|
let response = input_port.recv().unwrap();
|
||||||
let iter = ProgressMsgPortIterator { progress_port: response.progress_port };
|
let iter = ProgressMsgPortIterator {
|
||||||
|
progress_port: response.progress_port
|
||||||
|
};
|
||||||
(response.metadata, iter)
|
(response.metadata, iter)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator that reads chunks of bytes from a ProgressMsg port
|
/// Iterator that reads chunks of bytes from a ProgressMsg port
|
||||||
pub struct ProgressMsgPortIterator {
|
pub struct ProgressMsgPortIterator {
|
||||||
progress_port: Receiver<ProgressMsg>
|
progress_port: IpcReceiver<ProgressMsg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for ProgressMsgPortIterator {
|
impl Iterator for ProgressMsgPortIterator {
|
||||||
|
@ -334,8 +334,8 @@ impl Iterator for ProgressMsgPortIterator {
|
||||||
fn next(&mut self) -> Option<Vec<u8>> {
|
fn next(&mut self) -> Option<Vec<u8>> {
|
||||||
match self.progress_port.recv().unwrap() {
|
match self.progress_port.recv().unwrap() {
|
||||||
ProgressMsg::Payload(data) => Some(data),
|
ProgressMsg::Payload(data) => Some(data),
|
||||||
ProgressMsg::Done(SerializableStringResult(Ok(()))) => None,
|
ProgressMsg::Done(Ok(())) => None,
|
||||||
ProgressMsg::Done(SerializableStringResult(Err(e))) => {
|
ProgressMsg::Done(Err(e)) => {
|
||||||
error!("error receiving bytes: {}", e);
|
error!("error receiving bytes: {}", e);
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -343,226 +343,3 @@ 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)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,12 @@ path = "lib.rs"
|
||||||
[dependencies.ipc-channel]
|
[dependencies.ipc-channel]
|
||||||
git = "https://github.com/pcwalton/ipc-channel"
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = "0.4"
|
serde = "0.4"
|
||||||
serde_macros = "0.4"
|
serde_macros = "0.4"
|
||||||
time = "0.1.12"
|
time = "0.1.12"
|
||||||
url = "0.2.36"
|
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ rustc-serialize = "0.3"
|
||||||
libc = "0.1"
|
libc = "0.1"
|
||||||
unicase = "0.1"
|
unicase = "0.1"
|
||||||
num = "0.1.24"
|
num = "0.1.24"
|
||||||
websocket = "0.12"
|
websocket = "0.12.0"
|
||||||
uuid = "0.1.16"
|
uuid = "0.1.16"
|
||||||
smallvec = "0.1"
|
smallvec = "0.1"
|
||||||
html5ever = { version = "0.2.1", features = ["unstable"] }
|
html5ever = { version = "0.2.1", features = ["unstable"] }
|
||||||
|
|
|
@ -11,13 +11,11 @@
|
||||||
|
|
||||||
use network_listener::{NetworkListener, PreInvoke};
|
use network_listener::{NetworkListener, PreInvoke};
|
||||||
use script_task::ScriptChan;
|
use script_task::ScriptChan;
|
||||||
use net_traits::{AsyncResponseTarget, AsyncResponseListener, ResponseAction, Metadata};
|
use net_traits::{AsyncResponseListener, ResponseAction, Metadata};
|
||||||
use net_traits::{SerializableStringResult};
|
|
||||||
|
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::sync::mpsc;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use time;
|
use time;
|
||||||
use time::{now, Timespec};
|
use time::{now, Timespec};
|
||||||
|
@ -133,14 +131,9 @@ impl CORSRequest {
|
||||||
listener: listener,
|
listener: listener,
|
||||||
response: RefCell::new(None),
|
response: RefCell::new(None),
|
||||||
};
|
};
|
||||||
let (action_sender, action_receiver) = mpsc::channel();
|
|
||||||
let listener = NetworkListener {
|
let listener = NetworkListener {
|
||||||
context: Arc::new(Mutex::new(context)),
|
context: Arc::new(Mutex::new(context)),
|
||||||
script_chan: script_chan,
|
script_chan: script_chan,
|
||||||
receiver: action_receiver,
|
|
||||||
};
|
|
||||||
let response_target = AsyncResponseTarget {
|
|
||||||
sender: action_sender,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: this exists only to make preflight check non-blocking
|
// TODO: this exists only to make preflight check non-blocking
|
||||||
|
@ -151,8 +144,7 @@ impl CORSRequest {
|
||||||
let mut context = listener.context.lock();
|
let mut context = listener.context.lock();
|
||||||
let context = context.as_mut().unwrap();
|
let context = context.as_mut().unwrap();
|
||||||
*context.response.borrow_mut() = Some(response);
|
*context.response.borrow_mut() = Some(response);
|
||||||
response_target.invoke_with_listener(ResponseAction::ResponseComplete(
|
listener.notify(ResponseAction::ResponseComplete(Ok(())));
|
||||||
SerializableStringResult(Ok(()))));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ use euclid::size::Size2D;
|
||||||
use html5ever::tree_builder::QuirksMode;
|
use html5ever::tree_builder::QuirksMode;
|
||||||
use hyper::header::Headers;
|
use hyper::header::Headers;
|
||||||
use hyper::method::Method;
|
use hyper::method::Method;
|
||||||
use ipc_channel::ipc::IpcSender;
|
use ipc_channel::ipc::{IpcReceiver, IpcSender};
|
||||||
use js::jsapi::{JSObject, JSTracer, JSGCTraceKind, JS_CallValueTracer, JS_CallObjectTracer, GCTraceKindToAscii, Heap};
|
use js::jsapi::{JSObject, JSTracer, JSGCTraceKind, JS_CallValueTracer, JS_CallObjectTracer, GCTraceKindToAscii, Heap};
|
||||||
use js::jsapi::JS_CallUnbarrieredObjectTracer;
|
use js::jsapi::JS_CallUnbarrieredObjectTracer;
|
||||||
use js::jsval::JSVal;
|
use js::jsval::JSVal;
|
||||||
|
@ -57,6 +57,7 @@ use net_traits::image_cache_task::{ImageCacheChan, ImageCacheTask};
|
||||||
use net_traits::storage_task::StorageType;
|
use net_traits::storage_task::StorageType;
|
||||||
use script_traits::ScriptControlChan;
|
use script_traits::ScriptControlChan;
|
||||||
use script_traits::UntrustedNodeAddress;
|
use script_traits::UntrustedNodeAddress;
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use msg::compositor_msg::ScriptListener;
|
use msg::compositor_msg::ScriptListener;
|
||||||
use msg::constellation_msg::ConstellationChan;
|
use msg::constellation_msg::ConstellationChan;
|
||||||
|
@ -356,9 +357,10 @@ impl JSTraceable for Box<LayoutRPC+'static> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JSTraceable for () {
|
impl<T> JSTraceable for IpcReceiver<T> where T: Deserialize + Serialize {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn trace(&self, _trc: *mut JSTracer) {
|
fn trace(&self, _: *mut JSTracer) {
|
||||||
|
// Do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -181,7 +181,7 @@ impl DedicatedWorkerGlobalScope {
|
||||||
let serialized_url = url.serialize();
|
let serialized_url = url.serialize();
|
||||||
let parent_sender_for_reporter = parent_sender.clone();
|
let parent_sender_for_reporter = parent_sender.clone();
|
||||||
let global = DedicatedWorkerGlobalScope::new(
|
let global = DedicatedWorkerGlobalScope::new(
|
||||||
url.0, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(),
|
url, id, mem_profiler_chan.clone(), devtools_chan, runtime.clone(),
|
||||||
resource_task, constellation_chan, parent_sender, own_sender, receiver);
|
resource_task, constellation_chan, parent_sender, own_sender, receiver);
|
||||||
// FIXME(njn): workers currently don't have a unique ID suitable for using in reporter
|
// 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.
|
// registration (#6631), so we instead use a random number and cross our fingers.
|
||||||
|
|
|
@ -74,7 +74,7 @@ use msg::constellation_msg::{ConstellationChan, FocusType, Key, KeyState, KeyMod
|
||||||
use msg::constellation_msg::{SUPER, ALT, SHIFT, CONTROL};
|
use msg::constellation_msg::{SUPER, ALT, SHIFT, CONTROL};
|
||||||
use net_traits::CookieSource::NonHTTP;
|
use net_traits::CookieSource::NonHTTP;
|
||||||
use net_traits::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl};
|
use net_traits::ControlMsg::{SetCookiesForUrl, GetCookiesForUrl};
|
||||||
use net_traits::{Metadata, PendingAsyncLoad, AsyncResponseTarget, SerializableUrl};
|
use net_traits::{Metadata, PendingAsyncLoad, AsyncResponseTarget};
|
||||||
use script_task::Runnable;
|
use script_task::Runnable;
|
||||||
use script_traits::{MouseButton, UntrustedNodeAddress};
|
use script_traits::{MouseButton, UntrustedNodeAddress};
|
||||||
use util::opts;
|
use util::opts;
|
||||||
|
@ -83,6 +83,7 @@ use layout_interface::{ReflowGoal, ReflowQueryType};
|
||||||
|
|
||||||
use euclid::point::Point2D;
|
use euclid::point::Point2D;
|
||||||
use html5ever::tree_builder::{QuirksMode, NoQuirks, LimitedQuirks, Quirks};
|
use html5ever::tree_builder::{QuirksMode, NoQuirks, LimitedQuirks, Quirks};
|
||||||
|
use ipc_channel::ipc;
|
||||||
use layout_interface::{LayoutChan, Msg};
|
use layout_interface::{LayoutChan, Msg};
|
||||||
use string_cache::{Atom, QualName};
|
use string_cache::{Atom, QualName};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -1720,10 +1721,8 @@ impl<'a> DocumentMethods for &'a Document {
|
||||||
return Err(Security);
|
return Err(Security);
|
||||||
}
|
}
|
||||||
let window = self.window.root();
|
let window = self.window.root();
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = ipc::channel().unwrap();
|
||||||
let _ = window.r().resource_task().send(GetCookiesForUrl(SerializableUrl(url),
|
let _ = window.r().resource_task().send(GetCookiesForUrl(url, tx, NonHTTP));
|
||||||
tx,
|
|
||||||
NonHTTP));
|
|
||||||
let cookies = rx.recv().unwrap();
|
let cookies = rx.recv().unwrap();
|
||||||
Ok(cookies.unwrap_or("".to_owned()))
|
Ok(cookies.unwrap_or("".to_owned()))
|
||||||
}
|
}
|
||||||
|
@ -1736,9 +1735,7 @@ impl<'a> DocumentMethods for &'a Document {
|
||||||
return Err(Security);
|
return Err(Security);
|
||||||
}
|
}
|
||||||
let window = self.window.root();
|
let window = self.window.root();
|
||||||
let _ = window.r().resource_task().send(SetCookiesForUrl(SerializableUrl(url),
|
let _ = window.r().resource_task().send(SetCookiesForUrl(url, cookie, NonHTTP));
|
||||||
cookie,
|
|
||||||
NonHTTP));
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,14 +40,14 @@ use js::jsval::UndefinedValue;
|
||||||
use encoding::all::UTF_8;
|
use encoding::all::UTF_8;
|
||||||
use encoding::label::encoding_from_whatwg_label;
|
use encoding::label::encoding_from_whatwg_label;
|
||||||
use encoding::types::{Encoding, EncodingRef, DecoderTrap};
|
use encoding::types::{Encoding, EncodingRef, DecoderTrap};
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use ipc_channel::router::ROUTER;
|
||||||
use net_traits::{Metadata, AsyncResponseListener, AsyncResponseTarget};
|
use net_traits::{Metadata, AsyncResponseListener, AsyncResponseTarget};
|
||||||
use util::str::{DOMString, HTML_SPACE_CHARACTERS, StaticStringVec};
|
use util::str::{DOMString, HTML_SPACE_CHARACTERS, StaticStringVec};
|
||||||
use html5ever::tree_builder::NextParserState;
|
use html5ever::tree_builder::NextParserState;
|
||||||
use std::cell::{RefCell, Cell};
|
use std::cell::{RefCell, Cell};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::mpsc;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
use url::{Url, UrlParser};
|
use url::{Url, UrlParser};
|
||||||
|
|
||||||
|
@ -332,16 +332,17 @@ impl<'a> HTMLScriptElementHelpers for &'a HTMLScriptElement {
|
||||||
url: url.clone(),
|
url: url.clone(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let (action_sender, action_receiver) = mpsc::channel();
|
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||||
let listener = box NetworkListener {
|
let listener = box NetworkListener {
|
||||||
context: context,
|
context: context,
|
||||||
script_chan: script_chan,
|
script_chan: script_chan,
|
||||||
receiver: action_receiver,
|
|
||||||
};
|
};
|
||||||
let response_target = AsyncResponseTarget {
|
let response_target = AsyncResponseTarget {
|
||||||
sender: action_sender,
|
sender: action_sender,
|
||||||
};
|
};
|
||||||
thread::spawn(move || listener.run());
|
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
|
||||||
|
listener.notify(message.to().unwrap());
|
||||||
|
});
|
||||||
|
|
||||||
doc.r().load_async(LoadType::Script(url), response_target);
|
doc.r().load_async(LoadType::Script(url), response_target);
|
||||||
|
|
||||||
|
@ -400,7 +401,7 @@ impl<'a> HTMLScriptElementHelpers for &'a HTMLScriptElement {
|
||||||
// encoding as the fallback encoding.
|
// encoding as the fallback encoding.
|
||||||
|
|
||||||
(UTF_8.decode(&*bytes, DecoderTrap::Replace).unwrap(), true,
|
(UTF_8.decode(&*bytes, DecoderTrap::Replace).unwrap(), true,
|
||||||
metadata.final_url.0)
|
metadata.final_url)
|
||||||
},
|
},
|
||||||
|
|
||||||
// Step 2.b.1.c.
|
// Step 2.b.1.c.
|
||||||
|
|
|
@ -84,7 +84,7 @@ impl ParserContext {
|
||||||
|
|
||||||
impl AsyncResponseListener for ParserContext {
|
impl AsyncResponseListener for ParserContext {
|
||||||
fn headers_available(&self, metadata: Metadata) {
|
fn headers_available(&self, metadata: Metadata) {
|
||||||
let content_type = metadata.content_type.clone().map(|content_type| content_type.0);
|
let content_type = metadata.content_type.clone();
|
||||||
|
|
||||||
let parser = ScriptTask::page_fetch_complete(self.id.clone(), self.subpage.clone(),
|
let parser = ScriptTask::page_fetch_complete(self.id.clone(), self.subpage.clone(),
|
||||||
metadata);
|
metadata);
|
||||||
|
|
|
@ -46,20 +46,21 @@ use js::jsval::{JSVal, NullValue, UndefinedValue};
|
||||||
|
|
||||||
use net_traits::ControlMsg::Load;
|
use net_traits::ControlMsg::Load;
|
||||||
use net_traits::{ResourceTask, ResourceCORSData, LoadData, LoadConsumer};
|
use net_traits::{ResourceTask, ResourceCORSData, LoadData, LoadConsumer};
|
||||||
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata, SerializableHeaders};
|
use net_traits::{AsyncResponseListener, AsyncResponseTarget, Metadata};
|
||||||
use net_traits::{SerializableMethod, SerializableUrl};
|
|
||||||
use cors::{allow_cross_origin_request, CORSRequest, RequestMode, AsyncCORSResponseListener};
|
use cors::{allow_cross_origin_request, CORSRequest, RequestMode, AsyncCORSResponseListener};
|
||||||
use cors::CORSResponse;
|
use cors::CORSResponse;
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
use util::task::spawn_named;
|
use util::task::spawn_named;
|
||||||
|
|
||||||
|
use ipc_channel::ipc;
|
||||||
|
use ipc_channel::router::ROUTER;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cell::{RefCell, Cell};
|
use std::cell::{RefCell, Cell};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::sync::{Mutex, Arc};
|
use std::sync::{Mutex, Arc};
|
||||||
use std::sync::mpsc::{channel, Sender, TryRecvError};
|
use std::sync::mpsc::{channel, Sender, TryRecvError};
|
||||||
use std::thread::{self, sleep_ms};
|
use std::thread::sleep_ms;
|
||||||
use time;
|
use time;
|
||||||
use url::{Url, UrlParser};
|
use url::{Url, UrlParser};
|
||||||
|
|
||||||
|
@ -217,7 +218,7 @@ impl XMLHttpRequest {
|
||||||
let mut load_data = self.load_data.borrow_mut().take().unwrap();
|
let mut load_data = self.load_data.borrow_mut().take().unwrap();
|
||||||
load_data.cors = Some(ResourceCORSData {
|
load_data.cors = Some(ResourceCORSData {
|
||||||
preflight: self.req.preflight_flag,
|
preflight: self.req.preflight_flag,
|
||||||
origin: SerializableUrl(self.req.origin.clone())
|
origin: self.req.origin.clone()
|
||||||
});
|
});
|
||||||
|
|
||||||
XMLHttpRequest::initiate_async_xhr(self.xhr.clone(), self.script_chan.clone(),
|
XMLHttpRequest::initiate_async_xhr(self.xhr.clone(), self.script_chan.clone(),
|
||||||
|
@ -271,16 +272,17 @@ impl XMLHttpRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (action_sender, action_receiver) = channel();
|
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||||
let listener = box NetworkListener {
|
let listener = box NetworkListener {
|
||||||
context: context,
|
context: context,
|
||||||
script_chan: script_chan,
|
script_chan: script_chan,
|
||||||
receiver: action_receiver,
|
|
||||||
};
|
};
|
||||||
let response_target = AsyncResponseTarget {
|
let response_target = AsyncResponseTarget {
|
||||||
sender: action_sender,
|
sender: action_sender,
|
||||||
};
|
};
|
||||||
thread::spawn(move || listener.run());
|
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
|
||||||
|
listener.notify(message.to().unwrap());
|
||||||
|
});
|
||||||
resource_task.send(Load(load_data, LoadConsumer::Listener(response_target))).unwrap();
|
resource_task.send(Load(load_data, LoadConsumer::Listener(response_target))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,15 +548,14 @@ impl<'a> XMLHttpRequestMethods for &'a XMLHttpRequest {
|
||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
load_data.preserved_headers =
|
load_data.preserved_headers = (*self.request_headers.borrow()).clone();
|
||||||
SerializableHeaders((*self.request_headers.borrow()).clone());
|
|
||||||
|
|
||||||
if !load_data.preserved_headers.has::<Accept>() {
|
if !load_data.preserved_headers.has::<Accept>() {
|
||||||
let mime = Mime(mime::TopLevel::Star, mime::SubLevel::Star, vec![]);
|
let mime = Mime(mime::TopLevel::Star, mime::SubLevel::Star, vec![]);
|
||||||
load_data.preserved_headers.set(Accept(vec![qitem(mime)]));
|
load_data.preserved_headers.set(Accept(vec![qitem(mime)]));
|
||||||
}
|
}
|
||||||
|
|
||||||
load_data.method = SerializableMethod((*self.request_method.borrow()).clone());
|
load_data.method = (*self.request_method.borrow()).clone();
|
||||||
|
|
||||||
// CORS stuff
|
// CORS stuff
|
||||||
let global = self.global.root();
|
let global = self.global.root();
|
||||||
|
@ -564,12 +565,12 @@ impl<'a> XMLHttpRequestMethods for &'a XMLHttpRequest {
|
||||||
} else {
|
} else {
|
||||||
RequestMode::CORS
|
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());
|
combined_headers.extend(load_data.preserved_headers.iter());
|
||||||
let cors_request = CORSRequest::maybe_new(referer_url.clone(),
|
let cors_request = CORSRequest::maybe_new(referer_url.clone(),
|
||||||
(*load_data.url).clone(),
|
load_data.url.clone(),
|
||||||
mode,
|
mode,
|
||||||
(*load_data.method).clone(),
|
load_data.method.clone(),
|
||||||
combined_headers);
|
combined_headers);
|
||||||
match cors_request {
|
match cors_request {
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
|
@ -791,10 +792,9 @@ impl<'a> PrivateXMLHttpRequestHelpers for &'a XMLHttpRequest {
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
// XXXManishearth Clear cache entries in case of a network error
|
// XXXManishearth Clear cache entries in case of a network error
|
||||||
self.process_partial_response(XHRProgress::HeadersReceived(
|
self.process_partial_response(XHRProgress::HeadersReceived(gen_id,
|
||||||
gen_id,
|
metadata.headers,
|
||||||
metadata.headers.map(|headers| headers.0),
|
metadata.status));
|
||||||
metadata.status.map(|status| status.0)));
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
use script_task::{ScriptChan, ScriptMsg, Runnable};
|
use script_task::{ScriptChan, ScriptMsg, Runnable};
|
||||||
use net_traits::{AsyncResponseListener, ResponseAction};
|
use net_traits::{AsyncResponseListener, ResponseAction};
|
||||||
use std::sync::mpsc::Receiver;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
/// An off-thread sink for async network event runnables. All such events are forwarded to
|
/// An off-thread sink for async network event runnables. All such events are forwarded to
|
||||||
|
@ -12,17 +11,14 @@ use std::sync::{Arc, Mutex};
|
||||||
pub struct NetworkListener<T: AsyncResponseListener + PreInvoke + Send + 'static> {
|
pub struct NetworkListener<T: AsyncResponseListener + PreInvoke + Send + 'static> {
|
||||||
pub context: Arc<Mutex<T>>,
|
pub context: Arc<Mutex<T>>,
|
||||||
pub script_chan: Box<ScriptChan+Send>,
|
pub script_chan: Box<ScriptChan+Send>,
|
||||||
pub receiver: Receiver<ResponseAction>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsyncResponseListener + PreInvoke + Send + 'static> NetworkListener<T> {
|
impl<T: AsyncResponseListener + PreInvoke + Send + 'static> NetworkListener<T> {
|
||||||
pub fn run(&self) {
|
pub fn notify(&self, action: ResponseAction) {
|
||||||
while let Ok(action) = self.receiver.recv() {
|
self.script_chan.send(ScriptMsg::RunnableMsg(box ListenerRunnable {
|
||||||
self.script_chan.send(ScriptMsg::RunnableMsg(box ListenerRunnable {
|
context: self.context.clone(),
|
||||||
context: self.context.clone(),
|
action: action,
|
||||||
action: action,
|
})).unwrap();
|
||||||
})).unwrap();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,8 +69,6 @@ use msg::constellation_msg::Msg as ConstellationMsg;
|
||||||
use msg::webdriver_msg::WebDriverScriptCommand;
|
use msg::webdriver_msg::WebDriverScriptCommand;
|
||||||
use net_traits::LoadData as NetLoadData;
|
use net_traits::LoadData as NetLoadData;
|
||||||
use net_traits::{AsyncResponseTarget, ResourceTask, LoadConsumer, ControlMsg, Metadata};
|
use net_traits::{AsyncResponseTarget, 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::image_cache_task::{ImageCacheChan, ImageCacheTask, ImageCacheResult};
|
||||||
use net_traits::storage_task::StorageTask;
|
use net_traits::storage_task::StorageTask;
|
||||||
use profile_traits::mem::{self, Report, Reporter, ReporterRequest, ReportKind, ReportsChan};
|
use profile_traits::mem::{self, Report, Reporter, ReporterRequest, ReportKind, ReportsChan};
|
||||||
|
@ -105,7 +103,6 @@ use std::rc::Rc;
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::sync::mpsc::{channel, Sender, Receiver, Select};
|
use std::sync::mpsc::{channel, Sender, Receiver, Select};
|
||||||
use std::thread;
|
|
||||||
use time::Tm;
|
use time::Tm;
|
||||||
|
|
||||||
use hyper::header::{ContentType, HttpDate};
|
use hyper::header::{ContentType, HttpDate};
|
||||||
|
@ -1312,7 +1309,7 @@ impl ScriptTask {
|
||||||
/// The entry point to document loading. Defines bindings, sets up the window and document
|
/// The entry point to document loading. Defines bindings, sets up the window and document
|
||||||
/// objects, parses HTML and CSS, and kicks off initial layout.
|
/// objects, parses HTML and CSS, and kicks off initial layout.
|
||||||
fn load(&self, metadata: Metadata, incomplete: InProgressLoad) -> Root<ServoHTMLParser> {
|
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);
|
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
|
// We should either be initializing a root page or loading a child page of an
|
||||||
|
@ -1418,9 +1415,7 @@ impl ScriptTask {
|
||||||
});
|
});
|
||||||
|
|
||||||
let content_type = match metadata.content_type {
|
let content_type = match metadata.content_type {
|
||||||
Some(SerializableContentType(ContentType(Mime(TopLevel::Text,
|
Some(ContentType(Mime(TopLevel::Text, SubLevel::Plain, _))) => {
|
||||||
SubLevel::Plain,
|
|
||||||
_)))) => {
|
|
||||||
Some("text/plain".to_owned())
|
Some("text/plain".to_owned())
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None
|
||||||
|
@ -1687,13 +1682,14 @@ impl ScriptTask {
|
||||||
|
|
||||||
let context = Arc::new(Mutex::new(ParserContext::new(id, subpage, script_chan.clone(),
|
let context = Arc::new(Mutex::new(ParserContext::new(id, subpage, script_chan.clone(),
|
||||||
load_data.url.clone())));
|
load_data.url.clone())));
|
||||||
let (action_sender, action_receiver) = channel();
|
let (action_sender, action_receiver) = ipc::channel().unwrap();
|
||||||
let listener = box NetworkListener {
|
let listener = box NetworkListener {
|
||||||
context: context,
|
context: context,
|
||||||
script_chan: script_chan.clone(),
|
script_chan: script_chan.clone(),
|
||||||
receiver: action_receiver,
|
|
||||||
};
|
};
|
||||||
thread::spawn(move || listener.run());
|
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
|
||||||
|
listener.notify(message.to().unwrap());
|
||||||
|
});
|
||||||
let response_target = AsyncResponseTarget {
|
let response_target = AsyncResponseTarget {
|
||||||
sender: action_sender,
|
sender: action_sender,
|
||||||
};
|
};
|
||||||
|
@ -1703,10 +1699,10 @@ impl ScriptTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
resource_task.send(ControlMsg::Load(NetLoadData {
|
resource_task.send(ControlMsg::Load(NetLoadData {
|
||||||
url: SerializableUrl(load_data.url),
|
url: load_data.url,
|
||||||
method: SerializableMethod(load_data.method),
|
method: load_data.method,
|
||||||
headers: SerializableHeaders(Headers::new()),
|
headers: Headers::new(),
|
||||||
preserved_headers: SerializableHeaders(load_data.headers),
|
preserved_headers: load_data.headers,
|
||||||
data: load_data.data,
|
data: load_data.data,
|
||||||
cors: None,
|
cors: None,
|
||||||
pipeline_id: Some(id),
|
pipeline_id: Some(id),
|
||||||
|
|
|
@ -25,8 +25,11 @@ path = "../devtools_traits"
|
||||||
[dependencies.ipc-channel]
|
[dependencies.ipc-channel]
|
||||||
git = "https://github.com/pcwalton/ipc-channel"
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
url = "0.2.36"
|
|
||||||
libc = "0.1"
|
libc = "0.1"
|
||||||
euclid = "0.1"
|
euclid = "0.1"
|
||||||
serde = "0.4"
|
serde = "0.4"
|
||||||
|
|
1
components/servo/Cargo.lock
generated
1
components/servo/Cargo.lock
generated
|
@ -910,6 +910,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cookie 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cookie 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"ipc-channel 0.1.0 (git+https://github.com/pcwalton/ipc-channel)",
|
||||||
"net 0.0.1",
|
"net 0.0.1",
|
||||||
"net_traits 0.0.1",
|
"net_traits 0.0.1",
|
||||||
"time 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
"time 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -100,9 +100,12 @@ optional = true
|
||||||
path = "../../support/android-rs-glue/glue"
|
path = "../../support/android-rs-glue/glue"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
url = "0.2.36"
|
|
||||||
time = "0.1.12"
|
time = "0.1.12"
|
||||||
bitflags = "0.3"
|
bitflags = "0.3"
|
||||||
libc = "0.1"
|
libc = "0.1"
|
||||||
|
|
|
@ -23,13 +23,16 @@ features = ["unstable"]
|
||||||
version = "0.3"
|
version = "0.3"
|
||||||
features = [ "serde-serialization" ]
|
features = [ "serde-serialization" ]
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
encoding = "0.2"
|
encoding = "0.2"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
matches = "0.1"
|
matches = "0.1"
|
||||||
url = "0.2.36"
|
|
||||||
bitflags = "0.3"
|
bitflags = "0.3"
|
||||||
num = "0.1.24"
|
num = "0.1.24"
|
||||||
lazy_static = "0.1.10"
|
lazy_static = "0.1.10"
|
||||||
|
|
|
@ -28,6 +28,10 @@ features = [ "serde-serialization" ]
|
||||||
[dependencies.ipc-channel]
|
[dependencies.ipc-channel]
|
||||||
git = "https://github.com/pcwalton/ipc-channel"
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
bitflags = "0.3"
|
bitflags = "0.3"
|
||||||
|
@ -37,7 +41,6 @@ rustc-serialize = "0.3"
|
||||||
smallvec = "0.1"
|
smallvec = "0.1"
|
||||||
num_cpus = "0.2.2"
|
num_cpus = "0.2.2"
|
||||||
num = "0.1.24"
|
num = "0.1.24"
|
||||||
url = "0.2.36"
|
|
||||||
euclid = "0.1"
|
euclid = "0.1"
|
||||||
serde = "0.4"
|
serde = "0.4"
|
||||||
serde_macros = "0.4"
|
serde_macros = "0.4"
|
||||||
|
|
|
@ -23,8 +23,11 @@ features = [ "serde-serialization" ]
|
||||||
[dependencies.ipc-channel]
|
[dependencies.ipc-channel]
|
||||||
git = "https://github.com/pcwalton/ipc-channel"
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
|
[dependencies.url]
|
||||||
|
version = "0.2"
|
||||||
|
features = [ "serde_serialization" ]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
rustc-serialize = "0.3.4"
|
rustc-serialize = "0.3.4"
|
||||||
url = "0.2.36"
|
|
||||||
uuid = "0.1"
|
uuid = "0.1"
|
||||||
|
|
|
@ -17,6 +17,9 @@ path = "../../../components/net_traits"
|
||||||
[dependencies.util]
|
[dependencies.util]
|
||||||
path = "../../../components/util"
|
path = "../../../components/util"
|
||||||
|
|
||||||
|
[dependencies.ipc-channel]
|
||||||
|
git = "https://github.com/pcwalton/ipc-channel"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cookie = "0.1"
|
cookie = "0.1"
|
||||||
hyper = "0.6"
|
hyper = "0.6"
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
|
||||||
|
use ipc_channel::ipc;
|
||||||
use net_traits::LoadConsumer::Channel;
|
use net_traits::LoadConsumer::Channel;
|
||||||
use net_traits::LoadData;
|
use net_traits::LoadData;
|
||||||
use net_traits::ProgressMsg::{Payload, Done};
|
use net_traits::ProgressMsg::{Payload, Done};
|
||||||
|
@ -19,7 +20,7 @@ fn assert_parse(url: &'static str,
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use net::data_loader::load;
|
use net::data_loader::load;
|
||||||
|
|
||||||
let (start_chan, start_port) = channel();
|
let (start_chan, start_port) = ipc::channel().unwrap();
|
||||||
load(LoadData::new(Url::parse(url).unwrap(), None), Channel(start_chan));
|
load(LoadData::new(Url::parse(url).unwrap(), None), Channel(start_chan));
|
||||||
|
|
||||||
let response = start_port.recv().unwrap();
|
let response = start_port.recv().unwrap();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#![cfg_attr(test, feature(box_raw))]
|
#![cfg_attr(test, feature(box_raw))]
|
||||||
|
|
||||||
|
extern crate ipc_channel;
|
||||||
extern crate net;
|
extern crate net;
|
||||||
extern crate net_traits;
|
extern crate net_traits;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use net::resource_task::new_resource_task;
|
use ipc_channel::ipc;
|
||||||
use net::resource_task::parse_hostsfile;
|
use net::resource_task::{new_resource_task, parse_hostsfile, replace_hosts};
|
||||||
use net::resource_task::replace_hosts;
|
|
||||||
use net_traits::{ControlMsg, LoadData, LoadConsumer};
|
use net_traits::{ControlMsg, LoadData, LoadConsumer};
|
||||||
use net_traits::ProgressMsg;
|
use net_traits::ProgressMsg;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
@ -21,7 +20,7 @@ fn test_exit() {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bad_scheme() {
|
fn test_bad_scheme() {
|
||||||
let resource_task = new_resource_task(None, None);
|
let resource_task = new_resource_task(None, None);
|
||||||
let (start_chan, start) = channel();
|
let (start_chan, start) = ipc::channel().unwrap();
|
||||||
let url = Url::parse("bogus://whatever").unwrap();
|
let url = Url::parse("bogus://whatever").unwrap();
|
||||||
resource_task.send(ControlMsg::Load(LoadData::new(url, None), LoadConsumer::Channel(start_chan))).unwrap();
|
resource_task.send(ControlMsg::Load(LoadData::new(url, None), LoadConsumer::Channel(start_chan))).unwrap();
|
||||||
let response = start.recv().unwrap();
|
let response = start.recv().unwrap();
|
||||||
|
@ -170,7 +169,7 @@ fn test_replace_hosts() {
|
||||||
|
|
||||||
//Start the resource task and make a request to our TCP server
|
//Start the resource task and make a request to our TCP server
|
||||||
let resource_task = new_resource_task(None, None);
|
let resource_task = new_resource_task(None, None);
|
||||||
let (start_chan, _) = channel();
|
let (start_chan, _start_port) = ipc::channel().unwrap();
|
||||||
let url = Url::parse(&format!("http://foo.bar.com:{}", port)).unwrap();
|
let url = Url::parse(&format!("http://foo.bar.com:{}", port)).unwrap();
|
||||||
let msg = ControlMsg::Load(replace_hosts(LoadData::new(url, None), host_table),
|
let msg = ControlMsg::Load(replace_hosts(LoadData::new(url, None), host_table),
|
||||||
LoadConsumer::Channel(start_chan));
|
LoadConsumer::Channel(start_chan));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue