mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Start switching net/ to use abstractions over channels to allow introducing non-channel communication in the future.
This commit is contained in:
parent
7fddf4aa13
commit
1644436557
13 changed files with 108 additions and 79 deletions
|
@ -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};
|
use net_traits::{LoadData, Metadata,ResponseSenders};
|
||||||
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;
|
||||||
|
@ -18,10 +18,9 @@ use std::borrow::IntoCow;
|
||||||
use std::fs::PathExt;
|
use std::fs::PathExt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub fn factory(mut load_data: LoadData, classifier: Arc<MIMEClassifier>) {
|
pub fn factory(mut load_data: LoadData, start_chan: ResponseSenders, classifier: Arc<MIMEClassifier>) {
|
||||||
match load_data.url.non_relative_scheme_data().unwrap() {
|
match load_data.url.non_relative_scheme_data().unwrap() {
|
||||||
"blank" => {
|
"blank" => {
|
||||||
let start_chan = load_data.consumer;
|
|
||||||
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(ContentType(Mime(TopLevel::Text, SubLevel::Html, vec![]))),
|
content_type: Some(ContentType(Mime(TopLevel::Text, SubLevel::Html, vec![]))),
|
||||||
|
@ -40,11 +39,10 @@ pub fn factory(mut load_data: LoadData, classifier: Arc<MIMEClassifier>) {
|
||||||
load_data.url = Url::from_file_path(&*path).unwrap();
|
load_data.url = Url::from_file_path(&*path).unwrap();
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let start_chan = load_data.consumer;
|
|
||||||
start_sending(start_chan, Metadata::default(load_data.url))
|
start_sending(start_chan, Metadata::default(load_data.url))
|
||||||
.send(Done(Err("Unknown about: URL.".to_string()))).unwrap();
|
.send(Done(Err("Unknown about: URL.".to_string()))).unwrap();
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
file_loader::factory(load_data, classifier)
|
file_loader::factory(load_data, start_chan, classifier)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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};
|
use net_traits::{LoadData, Metadata, ResponseSenders};
|
||||||
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;
|
||||||
|
@ -13,16 +13,15 @@ use hyper::mime::Mime;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use url::{percent_decode, SchemeData};
|
use url::{percent_decode, SchemeData};
|
||||||
|
|
||||||
pub fn factory(load_data: LoadData, _classifier: Arc<MIMEClassifier>) {
|
pub fn factory(load_data: LoadData, senders: ResponseSenders, _classifier: Arc<MIMEClassifier>) {
|
||||||
// NB: we don't spawn a new task.
|
// NB: we don't spawn a new task.
|
||||||
// Hypothesis: data URLs are too small for parallel base64 etc. to be worth it.
|
// Hypothesis: data URLs are too small for parallel base64 etc. to be worth it.
|
||||||
// Should be tested at some point.
|
// Should be tested at some point.
|
||||||
// Left in separate function to allow easy moving to a task, if desired.
|
// Left in separate function to allow easy moving to a task, if desired.
|
||||||
load(load_data)
|
load(load_data, senders)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(load_data: LoadData) {
|
pub fn load(load_data: LoadData, start_chan: ResponseSenders) {
|
||||||
let start_chan = load_data.consumer;
|
|
||||||
let url = load_data.url;
|
let url = load_data.url;
|
||||||
assert!(&*url.scheme == "data");
|
assert!(&*url.scheme == "data");
|
||||||
|
|
||||||
|
|
|
@ -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, ProgressMsg};
|
use net_traits::{LoadData, Metadata, ProgressMsg, ResponseSenders};
|
||||||
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};
|
use resource_task::{start_sending, start_sending_sniffed};
|
||||||
|
@ -44,9 +44,8 @@ fn read_all(reader: &mut File, progress_chan: &Sender<ProgressMsg>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn factory(load_data: LoadData, classifier: Arc<MIMEClassifier>) {
|
pub fn factory(load_data: LoadData, senders: ResponseSenders, classifier: Arc<MIMEClassifier>) {
|
||||||
let url = load_data.url;
|
let url = load_data.url;
|
||||||
let start_chan = load_data.consumer;
|
|
||||||
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.clone());
|
let metadata = Metadata::default(url.clone());
|
||||||
|
@ -58,24 +57,24 @@ pub fn factory(load_data: LoadData, classifier: Arc<MIMEClassifier>) {
|
||||||
let res = read_block(reader);
|
let res = read_block(reader);
|
||||||
let (res, progress_chan) = match res {
|
let (res, progress_chan) = match res {
|
||||||
Ok(ReadStatus::Partial(buf)) => {
|
Ok(ReadStatus::Partial(buf)) => {
|
||||||
let progress_chan = start_sending_sniffed(start_chan, metadata,
|
let progress_chan = start_sending_sniffed(senders, metadata,
|
||||||
classifier, &buf);
|
classifier, &buf);
|
||||||
progress_chan.send(Payload(buf)).unwrap();
|
progress_chan.send(Payload(buf)).unwrap();
|
||||||
(read_all(reader, &progress_chan), progress_chan)
|
(read_all(reader, &progress_chan), progress_chan)
|
||||||
}
|
}
|
||||||
Ok(ReadStatus::EOF) | Err(_) =>
|
Ok(ReadStatus::EOF) | Err(_) =>
|
||||||
(res.map(|_| ()), start_sending(start_chan, metadata)),
|
(res.map(|_| ()), start_sending(senders, metadata)),
|
||||||
};
|
};
|
||||||
progress_chan.send(Done(res)).unwrap();
|
progress_chan.send(Done(res)).unwrap();
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let progress_chan = start_sending(start_chan, metadata);
|
let progress_chan = start_sending(senders, metadata);
|
||||||
progress_chan.send(Done(Err(e.description().to_string()))).unwrap();
|
progress_chan.send(Done(Err(e.description().to_string()))).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let progress_chan = start_sending(start_chan, metadata);
|
let progress_chan = start_sending(senders, metadata);
|
||||||
progress_chan.send(Done(Err(url.to_string()))).unwrap();
|
progress_chan.send(Done(Err(url.to_string()))).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::{ControlMsg, CookieSource, LoadData, LoadResponse, Metadata};
|
use net_traits::{ControlMsg, CookieSource, LoadData, Metadata, ResponseSenders};
|
||||||
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_opt, start_sending_sniffed_opt};
|
use resource_task::{start_sending_opt, start_sending_sniffed_opt};
|
||||||
|
@ -32,13 +32,13 @@ use url::{Url, UrlParser};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
|
||||||
pub fn factory(cookies_chan: Sender<ControlMsg>)
|
pub fn factory(cookies_chan: Sender<ControlMsg>)
|
||||||
-> Box<Invoke<(LoadData, Arc<MIMEClassifier>)> + Send> {
|
-> Box<Invoke<(LoadData, ResponseSenders, Arc<MIMEClassifier>)> + Send> {
|
||||||
box move |(load_data, classifier)| {
|
box move |(load_data, senders, classifier)| {
|
||||||
spawn_named("http_loader".to_owned(), move || load(load_data, classifier, cookies_chan))
|
spawn_named("http_loader".to_owned(), move || load(load_data, senders, classifier, cookies_chan))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_error(url: Url, err: String, start_chan: Sender<LoadResponse>) {
|
fn send_error(url: Url, err: String, start_chan: ResponseSenders) {
|
||||||
let mut metadata: Metadata = Metadata::default(url);
|
let mut metadata: Metadata = Metadata::default(url);
|
||||||
metadata.status = None;
|
metadata.status = None;
|
||||||
|
|
||||||
|
@ -66,13 +66,12 @@ fn read_block<R: Read>(reader: &mut R) -> Result<ReadResult, ()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(mut load_data: LoadData, classifier: Arc<MIMEClassifier>, cookies_chan: Sender<ControlMsg>) {
|
fn load(mut load_data: LoadData, start_chan: ResponseSenders, classifier: Arc<MIMEClassifier>, cookies_chan: Sender<ControlMsg>) {
|
||||||
// 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
|
||||||
// location for configuration. If you're reading this and such a
|
// location for configuration. If you're reading this and such a
|
||||||
// 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 start_chan = load_data.consumer;
|
|
||||||
let mut url = load_data.url.clone();
|
let mut url = load_data.url.clone();
|
||||||
let mut redirected_to = HashSet::new();
|
let mut redirected_to = HashSet::new();
|
||||||
|
|
||||||
|
@ -140,8 +139,8 @@ reason: \"certificate verify failed\" }]";
|
||||||
) => {
|
) => {
|
||||||
let mut image = resources_dir_path();
|
let mut image = resources_dir_path();
|
||||||
image.push("badcert.html");
|
image.push("badcert.html");
|
||||||
let load_data = LoadData::new(Url::from_file_path(&*image).unwrap(), start_chan);
|
let load_data = LoadData::new(Url::from_file_path(&*image).unwrap());
|
||||||
file_loader::factory(load_data, classifier);
|
file_loader::factory(load_data, start_chan, classifier);
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -340,7 +339,7 @@ reason: \"certificate verify failed\" }]";
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_data<R: Read>(reader: &mut R,
|
fn send_data<R: Read>(reader: &mut R,
|
||||||
start_chan: Sender<LoadResponse>,
|
start_chan: ResponseSenders,
|
||||||
metadata: Metadata,
|
metadata: Metadata,
|
||||||
classifier: Arc<MIMEClassifier>) {
|
classifier: Arc<MIMEClassifier>) {
|
||||||
let (progress_chan, mut chunk) = {
|
let (progress_chan, mut chunk) = {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use cookie_storage::CookieStorage;
|
||||||
use cookie;
|
use cookie;
|
||||||
use mime_classifier::MIMEClassifier;
|
use mime_classifier::MIMEClassifier;
|
||||||
|
|
||||||
use net_traits::{ControlMsg, LoadData, LoadResponse};
|
use net_traits::{ControlMsg, LoadData, LoadResponse, ResponseSenders, LoadConsumer};
|
||||||
use net_traits::{Metadata, ProgressMsg, ResourceTask};
|
use net_traits::{Metadata, ProgressMsg, ResourceTask};
|
||||||
use net_traits::ProgressMsg::Done;
|
use net_traits::ProgressMsg::Done;
|
||||||
use util::opts;
|
use util::opts;
|
||||||
|
@ -59,19 +59,19 @@ pub fn global_init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For use by loaders in responding to a Load message.
|
/// For use by loaders in responding to a Load message.
|
||||||
pub fn start_sending(start_chan: Sender<LoadResponse>, metadata: Metadata) -> Sender<ProgressMsg> {
|
pub fn start_sending(start_chan: ResponseSenders, metadata: Metadata) -> Sender<ProgressMsg> {
|
||||||
start_sending_opt(start_chan, metadata).ok().unwrap()
|
start_sending_opt(start_chan, metadata).ok().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For use by loaders in responding to a Load message that allows content sniffing.
|
/// For use by loaders in responding to a Load message that allows content sniffing.
|
||||||
pub fn start_sending_sniffed(start_chan: Sender<LoadResponse>, metadata: Metadata,
|
pub fn start_sending_sniffed(start_chan: ResponseSenders, metadata: Metadata,
|
||||||
classifier: Arc<MIMEClassifier>, partial_body: &Vec<u8>)
|
classifier: Arc<MIMEClassifier>, partial_body: &Vec<u8>)
|
||||||
-> Sender<ProgressMsg> {
|
-> Sender<ProgressMsg> {
|
||||||
start_sending_sniffed_opt(start_chan, metadata, classifier, partial_body).ok().unwrap()
|
start_sending_sniffed_opt(start_chan, metadata, classifier, partial_body).ok().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For use by loaders in responding to a Load message that allows content sniffing.
|
/// For use by loaders in responding to a Load message that allows content sniffing.
|
||||||
pub fn start_sending_sniffed_opt(start_chan: Sender<LoadResponse>, mut metadata: Metadata,
|
pub fn start_sending_sniffed_opt(start_chan: ResponseSenders, mut metadata: Metadata,
|
||||||
classifier: Arc<MIMEClassifier>, partial_body: &Vec<u8>)
|
classifier: Arc<MIMEClassifier>, partial_body: &Vec<u8>)
|
||||||
-> Result<Sender<ProgressMsg>, ()> {
|
-> Result<Sender<ProgressMsg>, ()> {
|
||||||
if opts::get().sniff_mime_types {
|
if opts::get().sniff_mime_types {
|
||||||
|
@ -94,7 +94,9 @@ pub fn start_sending_sniffed_opt(start_chan: Sender<LoadResponse>, mut metadata:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For use by loaders in responding to a Load message.
|
/// For use by loaders in responding to a Load message.
|
||||||
pub fn start_sending_opt(start_chan: Sender<LoadResponse>, metadata: Metadata) -> Result<Sender<ProgressMsg>, ()> {
|
pub fn start_sending_opt(start_chan: ResponseSenders, metadata: Metadata) -> Result<Sender<ProgressMsg>, ()> {
|
||||||
|
match start_chan {
|
||||||
|
ResponseSenders::Channel(start_chan) => {
|
||||||
let (progress_chan, progress_port) = channel();
|
let (progress_chan, progress_port) = channel();
|
||||||
let result = start_chan.send(LoadResponse {
|
let result = start_chan.send(LoadResponse {
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
|
@ -104,6 +106,9 @@ pub fn start_sending_opt(start_chan: Sender<LoadResponse>, metadata: Metadata) -
|
||||||
Ok(_) => Ok(progress_chan),
|
Ok(_) => Ok(progress_chan),
|
||||||
Err(_) => Err(())
|
Err(_) => Err(())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
ResponseSenders::Listener(_) => panic!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a ResourceTask
|
/// Create a ResourceTask
|
||||||
|
@ -176,8 +181,8 @@ impl ResourceManager {
|
||||||
fn start(&mut self) {
|
fn start(&mut self) {
|
||||||
loop {
|
loop {
|
||||||
match self.from_client.recv().unwrap() {
|
match self.from_client.recv().unwrap() {
|
||||||
ControlMsg::Load(load_data) => {
|
ControlMsg::Load(load_data, consumer) => {
|
||||||
self.load(load_data)
|
self.load(load_data, consumer)
|
||||||
}
|
}
|
||||||
ControlMsg::SetCookiesForUrl(request, cookie_list, source) => {
|
ControlMsg::SetCookiesForUrl(request, cookie_list, source) => {
|
||||||
let header = Header::parse_header(&[cookie_list.into_bytes()]);
|
let header = Header::parse_header(&[cookie_list.into_bytes()]);
|
||||||
|
@ -199,7 +204,7 @@ impl ResourceManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load(&mut self, mut load_data: LoadData) {
|
fn load(&mut self, mut load_data: LoadData, consumer: LoadConsumer) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Some(host_table) = HOST_TABLE {
|
if let Some(host_table) = HOST_TABLE {
|
||||||
load_data = replace_hosts(load_data, host_table);
|
load_data = replace_hosts(load_data, host_table);
|
||||||
|
@ -208,13 +213,14 @@ impl ResourceManager {
|
||||||
|
|
||||||
self.user_agent.as_ref().map(|ua| load_data.headers.set(UserAgent(ua.clone())));
|
self.user_agent.as_ref().map(|ua| load_data.headers.set(UserAgent(ua.clone())));
|
||||||
|
|
||||||
fn from_factory(factory: fn(LoadData, Arc<MIMEClassifier>))
|
fn from_factory(factory: fn(LoadData, ResponseSenders, Arc<MIMEClassifier>))
|
||||||
-> Box<Invoke<(LoadData, Arc<MIMEClassifier>)> + Send> {
|
-> Box<Invoke<(LoadData, ResponseSenders, Arc<MIMEClassifier>)> + Send> {
|
||||||
box move |(load_data, classifier)| {
|
box move |(load_data, senders, classifier)| {
|
||||||
factory(load_data, classifier)
|
factory(load_data, senders, classifier)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let senders = ResponseSenders::from_consumer(consumer);
|
||||||
let loader = match &*load_data.url.scheme {
|
let loader = match &*load_data.url.scheme {
|
||||||
"file" => from_factory(file_loader::factory),
|
"file" => from_factory(file_loader::factory),
|
||||||
"http" | "https" | "view-source" => http_loader::factory(self.resource_task.clone()),
|
"http" | "https" | "view-source" => http_loader::factory(self.resource_task.clone()),
|
||||||
|
@ -222,13 +228,13 @@ 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(load_data.consumer, Metadata::default(load_data.url))
|
start_sending(senders, Metadata::default(load_data.url))
|
||||||
.send(ProgressMsg::Done(Err("no loader for scheme".to_string()))).unwrap();
|
.send(ProgressMsg::Done(Err("no loader for scheme".to_string()))).unwrap();
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
debug!("resource_task: loading url: {}", load_data.url.serialize());
|
debug!("resource_task: loading url: {}", load_data.url.serialize());
|
||||||
|
|
||||||
loader.invoke((load_data, self.mime_classifier.clone()));
|
loader.invoke((load_data, senders, self.mime_classifier.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* 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 image::base::Image;
|
use image::base::Image;
|
||||||
|
use LoadConsumer::Channel;
|
||||||
use {ControlMsg, LoadData, ProgressMsg, ResourceTask};
|
use {ControlMsg, LoadData, ProgressMsg, ResourceTask};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ impl ImageCacheTaskClient for ImageCacheTask {
|
||||||
|
|
||||||
pub fn load_image_data(url: Url, resource_task: ResourceTask, placeholder: &[u8]) -> Result<Vec<u8>, ()> {
|
pub fn load_image_data(url: Url, resource_task: ResourceTask, placeholder: &[u8]) -> Result<Vec<u8>, ()> {
|
||||||
let (response_chan, response_port) = channel();
|
let (response_chan, response_port) = channel();
|
||||||
resource_task.send(ControlMsg::Load(LoadData::new(url.clone(), response_chan))).unwrap();
|
resource_task.send(ControlMsg::Load(LoadData::new(url.clone()), Channel(response_chan))).unwrap();
|
||||||
|
|
||||||
let mut image_data = vec!();
|
let mut image_data = vec!();
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,10 @@ pub struct LoadData {
|
||||||
pub preserved_headers: Headers,
|
pub preserved_headers: Headers,
|
||||||
pub data: Option<Vec<u8>>,
|
pub data: Option<Vec<u8>>,
|
||||||
pub cors: Option<ResourceCORSData>,
|
pub cors: Option<ResourceCORSData>,
|
||||||
pub consumer: Sender<LoadResponse>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LoadData {
|
impl LoadData {
|
||||||
pub fn new(url: Url, consumer: Sender<LoadResponse>) -> LoadData {
|
pub fn new(url: Url) -> LoadData {
|
||||||
LoadData {
|
LoadData {
|
||||||
url: url,
|
url: url,
|
||||||
method: Method::Get,
|
method: Method::Get,
|
||||||
|
@ -63,17 +62,31 @@ impl LoadData {
|
||||||
preserved_headers: Headers::new(),
|
preserved_headers: Headers::new(),
|
||||||
data: None,
|
data: None,
|
||||||
cors: None,
|
cors: None,
|
||||||
consumer: consumer,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait AsyncResponseListener {
|
||||||
|
fn headers_available(&self, metadata: Metadata);
|
||||||
|
fn data_available(&self, payload: Vec<u8>);
|
||||||
|
fn response_complete(&self, status: Result<(), String>);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait AsyncResponseTarget {
|
||||||
|
fn get_listener(&self) -> &AsyncResponseListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum LoadConsumer {
|
||||||
|
Channel(Sender<LoadResponse>),
|
||||||
|
Listener(Box<AsyncResponseTarget + Send>),
|
||||||
|
}
|
||||||
|
|
||||||
/// Handle to a resource task
|
/// Handle to a resource task
|
||||||
pub type ResourceTask = Sender<ControlMsg>;
|
pub type ResourceTask = Sender<ControlMsg>;
|
||||||
|
|
||||||
pub enum ControlMsg {
|
pub enum ControlMsg {
|
||||||
/// Request the data associated with a particular URL
|
/// Request the data associated with a particular URL
|
||||||
Load(LoadData),
|
Load(LoadData, LoadConsumer),
|
||||||
/// Store a set of cookies for a given originating URL
|
/// Store a set of cookies for a given originating URL
|
||||||
SetCookiesForUrl(Url, String, CookieSource),
|
SetCookiesForUrl(Url, String, CookieSource),
|
||||||
/// Retrieve the stored cookies for a given URL
|
/// Retrieve the stored cookies for a given URL
|
||||||
|
@ -159,6 +172,20 @@ pub enum CookieSource {
|
||||||
NonHTTP,
|
NonHTTP,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum ResponseSenders {
|
||||||
|
Channel(Sender<LoadResponse>),
|
||||||
|
Listener(Box<AsyncResponseTarget + Send>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResponseSenders {
|
||||||
|
pub fn from_consumer(consumer: LoadConsumer) -> ResponseSenders {
|
||||||
|
match consumer {
|
||||||
|
LoadConsumer::Channel(c) => ResponseSenders::Channel(c),
|
||||||
|
LoadConsumer::Listener(l) => ResponseSenders::Listener(l),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Messages sent in response to a `Load` message
|
/// Messages sent in response to a `Load` message
|
||||||
#[derive(PartialEq,Debug)]
|
#[derive(PartialEq,Debug)]
|
||||||
pub enum ProgressMsg {
|
pub enum ProgressMsg {
|
||||||
|
@ -172,7 +199,7 @@ pub enum ProgressMsg {
|
||||||
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) = channel();
|
||||||
resource_task.send(ControlMsg::Load(LoadData::new(url, start_chan))).unwrap();
|
resource_task.send(ControlMsg::Load(LoadData::new(url), 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!();
|
||||||
|
@ -188,7 +215,7 @@ pub fn load_whole_resource(resource_task: &ResourceTask, url: Url)
|
||||||
/// Load a URL asynchronously and iterate over chunks of bytes from the response.
|
/// Load a URL asynchronously and iterate over chunks of bytes from the response.
|
||||||
pub fn load_bytes_iter(resource_task: &ResourceTask, url: Url) -> (Metadata, ProgressMsgPortIterator) {
|
pub fn load_bytes_iter(resource_task: &ResourceTask, url: Url) -> (Metadata, ProgressMsgPortIterator) {
|
||||||
let (input_chan, input_port) = channel();
|
let (input_chan, input_port) = channel();
|
||||||
resource_task.send(ControlMsg::Load(LoadData::new(url, input_chan))).unwrap();
|
resource_task.send(ControlMsg::Load(LoadData::new(url), LoadConsumer::Channel(input_chan))).unwrap();
|
||||||
|
|
||||||
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 };
|
||||||
|
|
|
@ -44,7 +44,7 @@ use js::jsval::{JSVal, NullValue, UndefinedValue};
|
||||||
|
|
||||||
use net_traits::ControlMsg::Load;
|
use net_traits::ControlMsg::Load;
|
||||||
use net_traits::ProgressMsg::{Payload, Done};
|
use net_traits::ProgressMsg::{Payload, Done};
|
||||||
use net_traits::{ResourceTask, ResourceCORSData, LoadData, LoadResponse};
|
use net_traits::{ResourceTask, ResourceCORSData, LoadData, LoadConsumer};
|
||||||
use cors::{allow_cross_origin_request, CORSRequest, RequestMode};
|
use cors::{allow_cross_origin_request, CORSRequest, RequestMode};
|
||||||
use util::str::DOMString;
|
use util::str::DOMString;
|
||||||
use util::task::spawn_named;
|
use util::task::spawn_named;
|
||||||
|
@ -213,8 +213,8 @@ impl XMLHttpRequest {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
fn fetch(fetch_type: &SyncOrAsync, resource_task: ResourceTask,
|
fn fetch(fetch_type: &SyncOrAsync, resource_task: ResourceTask,
|
||||||
mut load_data: LoadData, terminate_receiver: Receiver<TerminateReason>,
|
mut load_data: LoadData, terminate_receiver: Receiver<TerminateReason>,
|
||||||
cors_request: Result<Option<CORSRequest>,()>, gen_id: GenerationId,
|
cors_request: Result<Option<CORSRequest>,()>, gen_id: GenerationId)
|
||||||
start_port: Receiver<LoadResponse>) -> ErrorResult {
|
-> ErrorResult {
|
||||||
|
|
||||||
fn notify_partial_progress(fetch_type: &SyncOrAsync, msg: XHRProgress) {
|
fn notify_partial_progress(fetch_type: &SyncOrAsync, msg: XHRProgress) {
|
||||||
match *fetch_type {
|
match *fetch_type {
|
||||||
|
@ -283,7 +283,8 @@ impl XMLHttpRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 10, 13
|
// Step 10, 13
|
||||||
resource_task.send(Load(load_data)).unwrap();
|
let (start_chan, start_port) = channel();
|
||||||
|
resource_task.send(Load(load_data, LoadConsumer::Channel(start_chan))).unwrap();
|
||||||
|
|
||||||
|
|
||||||
let progress_port;
|
let progress_port;
|
||||||
|
@ -579,8 +580,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
|
||||||
|
|
||||||
let global = self.global.root();
|
let global = self.global.root();
|
||||||
let resource_task = global.r().resource_task();
|
let resource_task = global.r().resource_task();
|
||||||
let (start_chan, start_port) = channel();
|
let mut load_data = LoadData::new(self.request_url.borrow().clone().unwrap());
|
||||||
let mut load_data = LoadData::new(self.request_url.borrow().clone().unwrap(), start_chan);
|
|
||||||
load_data.data = extracted;
|
load_data.data = extracted;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -650,7 +650,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
|
||||||
let gen_id = self.generation_id.get();
|
let gen_id = self.generation_id.get();
|
||||||
if self.sync.get() {
|
if self.sync.get() {
|
||||||
return XMLHttpRequest::fetch(&mut SyncOrAsync::Sync(self), resource_task, load_data,
|
return XMLHttpRequest::fetch(&mut SyncOrAsync::Sync(self), resource_task, load_data,
|
||||||
terminate_receiver, cors_request, gen_id, start_port);
|
terminate_receiver, cors_request, gen_id);
|
||||||
} else {
|
} else {
|
||||||
self.fetch_time.set(time::now().to_timespec().sec);
|
self.fetch_time.set(time::now().to_timespec().sec);
|
||||||
let script_chan = global.r().script_chan();
|
let script_chan = global.r().script_chan();
|
||||||
|
@ -665,8 +665,7 @@ impl<'a> XMLHttpRequestMethods for JSRef<'a, XMLHttpRequest> {
|
||||||
load_data,
|
load_data,
|
||||||
terminate_receiver,
|
terminate_receiver,
|
||||||
cors_request,
|
cors_request,
|
||||||
gen_id,
|
gen_id);
|
||||||
start_port);
|
|
||||||
});
|
});
|
||||||
let timeout = self.timeout.get();
|
let timeout = self.timeout.get();
|
||||||
if timeout > 0 {
|
if timeout > 0 {
|
||||||
|
|
|
@ -61,7 +61,7 @@ use msg::constellation_msg::{ConstellationChan};
|
||||||
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, WorkerId};
|
use msg::constellation_msg::{LoadData, PipelineId, SubpageId, MozBrowserEvent, WorkerId};
|
||||||
use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType};
|
use msg::constellation_msg::{Failure, WindowSizeData, PipelineExitType};
|
||||||
use msg::constellation_msg::Msg as ConstellationMsg;
|
use msg::constellation_msg::Msg as ConstellationMsg;
|
||||||
use net_traits::{ResourceTask, ControlMsg, LoadResponse};
|
use net_traits::{ResourceTask, ControlMsg, LoadResponse, LoadConsumer};
|
||||||
use net_traits::LoadData as NetLoadData;
|
use net_traits::LoadData as NetLoadData;
|
||||||
use net_traits::image_cache_task::ImageCacheTask;
|
use net_traits::image_cache_task::ImageCacheTask;
|
||||||
use net_traits::storage_task::StorageTask;
|
use net_traits::storage_task::StorageTask;
|
||||||
|
@ -1331,8 +1331,7 @@ impl ScriptTask {
|
||||||
preserved_headers: load_data.headers,
|
preserved_headers: load_data.headers,
|
||||||
data: load_data.data,
|
data: load_data.data,
|
||||||
cors: None,
|
cors: None,
|
||||||
consumer: input_chan,
|
}, LoadConsumer::Channel(input_chan))).unwrap();
|
||||||
})).unwrap();
|
|
||||||
|
|
||||||
let load_response = input_port.recv().unwrap();
|
let load_response = input_port.recv().unwrap();
|
||||||
script_chan.send(ScriptMsg::PageFetchComplete(id, subpage, load_response)).unwrap();
|
script_chan.send(ScriptMsg::PageFetchComplete(id, subpage, load_response)).unwrap();
|
||||||
|
|
1
components/servo/Cargo.lock
generated
1
components/servo/Cargo.lock
generated
|
@ -932,6 +932,7 @@ dependencies = [
|
||||||
"cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)",
|
"cssparser 0.2.0 (git+https://github.com/servo/rust-cssparser)",
|
||||||
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
|
"geom 0.1.0 (git+https://github.com/servo/rust-geom)",
|
||||||
"gfx 0.0.1",
|
"gfx 0.0.1",
|
||||||
|
"hyper 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"net 0.0.1",
|
"net 0.0.1",
|
||||||
"net_traits 0.0.1",
|
"net_traits 0.0.1",
|
||||||
"profile 0.0.1",
|
"profile 0.0.1",
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
|
|
||||||
|
use net_traits::ResponseSenders::Channel;
|
||||||
use net_traits::LoadData;
|
use net_traits::LoadData;
|
||||||
use net_traits::ProgressMsg::{Payload, Done};
|
use net_traits::ProgressMsg::{Payload, Done};
|
||||||
use self::hyper::header::ContentType;
|
use self::hyper::header::ContentType;
|
||||||
|
@ -19,7 +20,7 @@ fn assert_parse(url: &'static str,
|
||||||
use net::data_loader::load;
|
use net::data_loader::load;
|
||||||
|
|
||||||
let (start_chan, start_port) = channel();
|
let (start_chan, start_port) = channel();
|
||||||
load(LoadData::new(Url::parse(url).unwrap(), start_chan));
|
load(LoadData::new(Url::parse(url).unwrap()), Channel(start_chan));
|
||||||
|
|
||||||
let response = start_port.recv().unwrap();
|
let response = start_port.recv().unwrap();
|
||||||
assert_eq!(&response.metadata.content_type, &content_type);
|
assert_eq!(&response.metadata.content_type, &content_type);
|
||||||
|
|
|
@ -7,7 +7,7 @@ use net_traits::image_cache_task::ImageResponseMsg::*;
|
||||||
use net_traits::image_cache_task::Msg::*;
|
use net_traits::image_cache_task::Msg::*;
|
||||||
|
|
||||||
use net::resource_task::start_sending;
|
use net::resource_task::start_sending;
|
||||||
use net_traits::{ControlMsg, Metadata, ProgressMsg, ResourceTask};
|
use net_traits::{ControlMsg, Metadata, ProgressMsg, ResourceTask, ResponseSenders};
|
||||||
use net_traits::image_cache_task::{ImageCacheTask, ImageCacheTaskClient, ImageResponseMsg, Msg};
|
use net_traits::image_cache_task::{ImageCacheTask, ImageCacheTaskClient, ImageResponseMsg, Msg};
|
||||||
use net_traits::ProgressMsg::{Payload, Done};
|
use net_traits::ProgressMsg::{Payload, Done};
|
||||||
use profile::time;
|
use profile::time;
|
||||||
|
@ -110,8 +110,8 @@ fn mock_resource_task<T: Closure + Send + 'static>(on_load: Box<T>) -> ResourceT
|
||||||
spawn_listener(move |port: Receiver<ControlMsg>| {
|
spawn_listener(move |port: Receiver<ControlMsg>| {
|
||||||
loop {
|
loop {
|
||||||
match port.recv().unwrap() {
|
match port.recv().unwrap() {
|
||||||
ControlMsg::Load(response) => {
|
ControlMsg::Load(response, consumer) => {
|
||||||
let chan = start_sending(response.consumer, Metadata::default(
|
let chan = start_sending(ResponseSenders::from_consumer(consumer), Metadata::default(
|
||||||
Url::parse("file:///fake").unwrap()));
|
Url::parse("file:///fake").unwrap()));
|
||||||
on_load.invoke(chan);
|
on_load.invoke(chan);
|
||||||
}
|
}
|
||||||
|
@ -280,8 +280,8 @@ fn should_not_request_image_from_resource_task_if_image_is_already_available() {
|
||||||
let mock_resource_task = spawn_listener(move |port: Receiver<ControlMsg>| {
|
let mock_resource_task = spawn_listener(move |port: Receiver<ControlMsg>| {
|
||||||
loop {
|
loop {
|
||||||
match port.recv().unwrap() {
|
match port.recv().unwrap() {
|
||||||
ControlMsg::Load(response) => {
|
ControlMsg::Load(response, consumer) => {
|
||||||
let chan = start_sending(response.consumer, Metadata::default(
|
let chan = start_sending(ResponseSenders::from_consumer(consumer), Metadata::default(
|
||||||
Url::parse("file:///fake").unwrap()));
|
Url::parse("file:///fake").unwrap()));
|
||||||
chan.send(Payload(test_image_bin()));
|
chan.send(Payload(test_image_bin()));
|
||||||
chan.send(Done(Ok(())));
|
chan.send(Done(Ok(())));
|
||||||
|
@ -329,8 +329,8 @@ fn should_not_request_image_from_resource_task_if_image_fetch_already_failed() {
|
||||||
let mock_resource_task = spawn_listener(move |port: Receiver<ControlMsg>| {
|
let mock_resource_task = spawn_listener(move |port: Receiver<ControlMsg>| {
|
||||||
loop {
|
loop {
|
||||||
match port.recv().unwrap() {
|
match port.recv().unwrap() {
|
||||||
ControlMsg::Load(response) => {
|
ControlMsg::Load(response, consumer) => {
|
||||||
let chan = start_sending(response.consumer, Metadata::default(
|
let chan = start_sending(ResponseSenders::from_consumer(consumer), Metadata::default(
|
||||||
Url::parse("file:///fake").unwrap()));
|
Url::parse("file:///fake").unwrap()));
|
||||||
chan.send(Payload(test_image_bin()));
|
chan.send(Payload(test_image_bin()));
|
||||||
chan.send(Done(Err("".to_string())));
|
chan.send(Done(Err("".to_string())));
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* 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, parse_hostsfile, replace_hosts};
|
use net::resource_task::{new_resource_task, parse_hostsfile, replace_hosts};
|
||||||
use net_traits::{ControlMsg, LoadData};
|
use net_traits::{ControlMsg, LoadData, LoadConsumer};
|
||||||
use net_traits::ProgressMsg;
|
use net_traits::ProgressMsg;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::boxed;
|
use std::boxed;
|
||||||
|
@ -23,7 +23,7 @@ fn test_bad_scheme() {
|
||||||
let resource_task = new_resource_task(None);
|
let resource_task = new_resource_task(None);
|
||||||
let (start_chan, start) = channel();
|
let (start_chan, start) = channel();
|
||||||
let url = Url::parse("bogus://whatever").unwrap();
|
let url = Url::parse("bogus://whatever").unwrap();
|
||||||
resource_task.send(ControlMsg::Load(LoadData::new(url, start_chan))).unwrap();
|
resource_task.send(ControlMsg::Load(LoadData::new(url), LoadConsumer::Channel(start_chan))).unwrap();
|
||||||
let response = start.recv().unwrap();
|
let response = start.recv().unwrap();
|
||||||
match response.progress_port.recv().unwrap() {
|
match response.progress_port.recv().unwrap() {
|
||||||
ProgressMsg::Done(result) => { assert!(result.is_err()) }
|
ProgressMsg::Done(result) => { assert!(result.is_err()) }
|
||||||
|
@ -173,7 +173,7 @@ fn test_replace_hosts() {
|
||||||
let resource_task = new_resource_task(None);
|
let resource_task = new_resource_task(None);
|
||||||
let (start_chan, _) = channel();
|
let (start_chan, _) = channel();
|
||||||
let url = Url::parse(&format!("http://foo.bar.com:{}", port)).unwrap();
|
let url = Url::parse(&format!("http://foo.bar.com:{}", port)).unwrap();
|
||||||
resource_task.send(ControlMsg::Load(replace_hosts(LoadData::new(url, start_chan), host_table))).unwrap();
|
resource_task.send(ControlMsg::Load(replace_hosts(LoadData::new(url), host_table), LoadConsumer::Channel(start_chan))).unwrap();
|
||||||
|
|
||||||
match listener.accept() {
|
match listener.accept() {
|
||||||
Ok(..) => assert!(true, "received request"),
|
Ok(..) => assert!(true, "received request"),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue