From 15e8f4f0d4ff437aa4ab98a43ee596a747fc0eed Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 3 Nov 2016 09:16:03 +0100 Subject: [PATCH 1/9] Properly exit the core resource thread. --- components/net/resource_thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index 17835b52747..988a095b57e 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -241,7 +241,7 @@ impl ResourceChannelManager { }; if let Ok(msg) = data.to() { if !self.process_msg(msg, group, &sender) { - break; + return; } } } From ce24edc2b363389c3af138622e5ac88d1dd09d2c Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 2 Nov 2016 17:32:50 +0100 Subject: [PATCH 2/9] Remove a test for the CoreResourceMsg::Cancel message. --- tests/unit/net/resource_thread.rs | 75 +------------------------------ 1 file changed, 1 insertion(+), 74 deletions(-) diff --git a/tests/unit/net/resource_thread.rs b/tests/unit/net/resource_thread.rs index 2ffc0a2cd36..ac651f99b5a 100644 --- a/tests/unit/net/resource_thread.rs +++ b/tests/unit/net/resource_thread.rs @@ -3,36 +3,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use ipc_channel::ipc; -use msg::constellation_msg::PipelineId; use net::resource_thread::new_core_resource_thread; -use net_traits::{CoreResourceMsg, LoadConsumer, LoadContext, LoadData}; -use net_traits::{LoadOrigin, NetworkError, ProgressMsg, ReferrerPolicy}; +use net_traits::CoreResourceMsg; use net_traits::hosts::{host_replacement, parse_hostsfile}; use profile_traits::time::ProfilerChan; use servo_url::ServoUrl; use std::borrow::ToOwned; use std::collections::HashMap; use std::net::IpAddr; -use std::sync::mpsc::channel; fn ip(s: &str) -> IpAddr { s.parse().unwrap() } -struct ResourceTest; - -impl LoadOrigin for ResourceTest { - fn referrer_url(&self) -> Option { - None - } - fn referrer_policy(&self) -> Option { - None - } - fn pipeline_id(&self) -> Option { - None - } -} - #[test] fn test_exit() { let (tx, _rx) = ipc::channel().unwrap(); @@ -176,59 +159,3 @@ fn test_replace_hosts() { let url = ServoUrl::parse("http://a.foo.bar.com").unwrap(); assert_eq!(host_replacement(&host_table, &url).host_str().unwrap(), "a.foo.bar.com"); } - -#[test] -fn test_cancelled_listener() { - use std::io::Write; - use std::net::TcpListener; - use std::thread; - - // http_loader always checks for headers in the response - let header = vec!["HTTP/1.1 200 OK", - "Server: test-server", - "Content-Type: text/plain", - "\r\n"]; - let body = vec!["Yay!", "We're doomed!"]; - - // Setup a TCP server to which requests are made - let listener = TcpListener::bind("127.0.0.1:0").unwrap(); - let port = listener.local_addr().unwrap().port(); - let (body_sender, body_receiver) = channel(); - thread::spawn(move || { - if let Ok((mut stream, _)) = listener.accept() { - // immediately stream the headers once the connection has been established - let _ = stream.write(header.join("\r\n").as_bytes()); - // wait for the main thread to send the body, so as to ensure that we're - // doing everything sequentially - let body_vec: Vec<&str> = body_receiver.recv().unwrap(); - let _ = stream.write(body_vec.join("\r\n").as_bytes()); - } - }); - - let (tx, _rx) = ipc::channel().unwrap(); - let (exit_sender, exit_receiver) = ipc::channel().unwrap(); - let (resource_thread, _) = new_core_resource_thread( - "".into(), None, ProfilerChan(tx), None); - let (sender, receiver) = ipc::channel().unwrap(); - let (id_sender, id_receiver) = ipc::channel().unwrap(); - let (sync_sender, sync_receiver) = ipc::channel().unwrap(); - let url = ServoUrl::parse(&format!("http://127.0.0.1:{}", port)).unwrap(); - - resource_thread.send(CoreResourceMsg::Load(LoadData::new(LoadContext::Browsing, url, &ResourceTest), - LoadConsumer::Channel(sender), - Some(id_sender))).unwrap(); - // get the `ResourceId` and send a cancel message, which should stop the loading loop - let res_id = id_receiver.recv().unwrap(); - resource_thread.send(CoreResourceMsg::Cancel(res_id)).unwrap(); - // synchronize with the resource_thread loop, so that we don't simply send everything at once! - resource_thread.send(CoreResourceMsg::Synchronize(sync_sender)).unwrap(); - let _ = sync_receiver.recv(); - // now, let's send the body, because the connection is still active and data would be loaded - // (but, the loading has been cancelled) - let _ = body_sender.send(body); - let response = receiver.recv().unwrap(); - assert_eq!(response.progress_port.recv().unwrap(), - ProgressMsg::Done(Err(NetworkError::LoadCancelled))); - resource_thread.send(CoreResourceMsg::Exit(exit_sender)).unwrap(); - exit_receiver.recv().unwrap(); -} From fb1279ec3a97c16b17ee9ae3add69152029a4bc0 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Wed, 2 Nov 2016 15:48:23 +0100 Subject: [PATCH 3/9] Remove CoreResourceMsg::Load. Also remove now-dead code that rustc warns about. It turns out that we lost support for some of our custom URL schemes; I intend to reimplement them, but I believe this will be significantly easier to do once the legacy code is out of the way. --- components/net/Cargo.toml | 1 - components/net/about_loader.rs | 68 ---- components/net/blob_loader.rs | 106 +----- components/net/chrome_loader.rs | 22 -- components/net/data_loader.rs | 47 --- components/net/file_loader.rs | 139 ------- components/net/http_loader.rs | 593 +----------------------------- components/net/lib.rs | 4 - components/net/resource_thread.rs | 84 +---- components/net_traits/lib.rs | 2 - ports/cef/Cargo.lock | 1 - ports/servo/Cargo.lock | 1 - 12 files changed, 16 insertions(+), 1052 deletions(-) delete mode 100644 components/net/about_loader.rs delete mode 100644 components/net/file_loader.rs diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml index 05dc06f0912..ca04ba2f3c2 100644 --- a/components/net/Cargo.toml +++ b/components/net/Cargo.toml @@ -16,7 +16,6 @@ content-blocker = "0.2.1" cookie = {version = "0.2.5", features = ["serialize-rustc"]} devtools_traits = {path = "../devtools_traits"} flate2 = "0.2.0" -fnv = "1.0" hyper = "0.9.9" hyper_serde = "0.1.4" immeta = "0.3.1" diff --git a/components/net/about_loader.rs b/components/net/about_loader.rs deleted file mode 100644 index b439733bfea..00000000000 --- a/components/net/about_loader.rs +++ /dev/null @@ -1,68 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use file_loader; -use hyper::header::ContentType; -use hyper::mime::{Mime, SubLevel, TopLevel}; -use hyper_serde::Serde; -use mime_classifier::MimeClassifier; -use net_traits::{LoadConsumer, LoadData, Metadata, NetworkError}; -use net_traits::ProgressMsg::Done; -use net_traits::response::HttpsState; -use resource_thread::{CancellationListener, send_error, start_sending_sniffed_opt}; -use servo_url::ServoUrl; -use std::io; -use std::sync::Arc; -use url::Url; -use util::resource_files::resources_dir_path; - -fn url_from_non_relative_scheme(load_data: &mut LoadData, filename: &str) -> io::Result<()> { - let mut path = try!(resources_dir_path()); - path.push(filename); - assert!(path.exists()); - load_data.url = ServoUrl::from_url(Url::from_file_path(&*path).unwrap()); - Ok(()) -} - -pub fn factory(mut load_data: LoadData, - start_chan: LoadConsumer, - classifier: Arc, - cancel_listener: CancellationListener) { - let url = load_data.url.clone(); - let res = match url.path() { - "blank" => { - let metadata = Metadata { - final_url: load_data.url, - content_type: - Some(Serde(ContentType(Mime(TopLevel::Text, SubLevel::Html, vec![])))), - charset: Some("utf-8".to_owned()), - headers: None, - status: Some((200, b"OK".to_vec())), - https_state: HttpsState::None, - referrer: None, - }; - if let Ok(chan) = start_sending_sniffed_opt(start_chan, - metadata, - classifier, - &[], - load_data.context) { - let _ = chan.send(Done(Ok(()))); - } - return - } - "crash" => panic!("Loading the about:crash URL."), - "failure" | "not-found" => - url_from_non_relative_scheme(&mut load_data, &(url.path().to_owned() + ".html")), - "sslfail" => url_from_non_relative_scheme(&mut load_data, "badcert.html"), - _ => { - send_error(load_data.url, NetworkError::Internal("Unknown about: URL.".to_owned()), start_chan); - return - } - }; - if res.is_ok() { - file_loader::factory(load_data, start_chan, classifier, cancel_listener) - } else { - send_error(load_data.url, NetworkError::Internal("Could not access resource folder".to_owned()), start_chan); - } -} diff --git a/components/net/blob_loader.rs b/components/net/blob_loader.rs index 6bd5ff4c23f..cd57dfd25be 100644 --- a/components/net/blob_loader.rs +++ b/components/net/blob_loader.rs @@ -5,120 +5,16 @@ use filemanager_thread::FileManager; use hyper::header::{Charset, ContentLength, ContentType, Headers}; use hyper::header::{ContentDisposition, DispositionParam, DispositionType}; -use hyper_serde::Serde; use ipc_channel::ipc; use mime::{Attr, Mime}; -use mime_classifier::MimeClassifier; -use net_traits::{LoadConsumer, LoadData, Metadata, NetworkError}; -use net_traits::ProgressMsg::{Done, Payload}; +use net_traits::NetworkError; use net_traits::blob_url_store::parse_blob_url; use net_traits::filemanager_thread::ReadFileProgress; -use net_traits::response::HttpsState; -use resource_thread::{send_error, start_sending_sniffed_opt}; -use resource_thread::CancellationListener; use servo_url::ServoUrl; -use std::boxed::FnBox; -use std::sync::Arc; -use util::thread::spawn_named; // TODO: Check on GET // https://w3c.github.io/FileAPI/#requestResponseModel -pub fn factory(filemanager: FileManager) - -> Box, CancellationListener) + Send> { - box move |load_data: LoadData, start_chan, classifier, cancel_listener| { - spawn_named(format!("blob loader for {}", load_data.url), move || { - load_blob(load_data, start_chan, classifier, filemanager, cancel_listener); - }) - } -} - -fn load_blob(load_data: LoadData, start_chan: LoadConsumer, - classifier: Arc, - filemanager: FileManager, - cancel_listener: CancellationListener) { - let (chan, recv) = ipc::channel().unwrap(); - if let Ok((id, origin, _fragment)) = parse_blob_url(&load_data.url.clone()) { - let check_url_validity = true; - filemanager.read_file(chan, id, check_url_validity, origin, Some(cancel_listener)); - - // Receive first chunk - match recv.recv().unwrap() { - Ok(ReadFileProgress::Meta(blob_buf)) => { - let content_type: Mime = blob_buf.type_string.parse().unwrap_or(mime!(Text / Plain)); - let charset = content_type.get_param(Attr::Charset); - - let mut headers = Headers::new(); - - if let Some(name) = blob_buf.filename { - let charset = charset.and_then(|c| c.as_str().parse().ok()); - headers.set(ContentDisposition { - disposition: DispositionType::Inline, - parameters: vec![ - DispositionParam::Filename(charset.unwrap_or(Charset::Us_Ascii), - None, name.as_bytes().to_vec()) - ] - }); - } - - headers.set(ContentType(content_type.clone())); - headers.set(ContentLength(blob_buf.size as u64)); - - let metadata = Metadata { - final_url: load_data.url.clone(), - content_type: Some(Serde(ContentType(content_type.clone()))), - charset: charset.map(|c| c.as_str().to_string()), - headers: Some(Serde(headers)), - // https://w3c.github.io/FileAPI/#TwoHundredOK - status: Some((200, b"OK".to_vec())), - https_state: HttpsState::None, - referrer: None, - }; - - if let Ok(chan) = - start_sending_sniffed_opt(start_chan, metadata, classifier, - &blob_buf.bytes, load_data.context.clone()) { - let _ = chan.send(Payload(blob_buf.bytes)); - - loop { - match recv.recv().unwrap() { - Ok(ReadFileProgress::Partial(bytes)) => { - let _ = chan.send(Payload(bytes)); - } - Ok(ReadFileProgress::EOF) => { - let _ = chan.send(Done(Ok(()))); - return; - } - Ok(_) => { - let err = NetworkError::Internal("Invalid filemanager reply".to_string()); - let _ = chan.send(Done(Err(err))); - return; - } - Err(e) => { - let err = NetworkError::Internal(format!("{:?}", e)); - let _ = chan.send(Done(Err(err))); - return; - } - } - } - } - } - Ok(_) => { - let err = NetworkError::Internal("Invalid filemanager reply".to_string()); - send_error(load_data.url, err, start_chan); - } - Err(e) => { - let err = NetworkError::Internal(format!("{:?}", e)); - send_error(load_data.url, err, start_chan); - } - } - } else { - let e = format!("Invalid blob URL format {:?}", load_data.url); - let format_err = NetworkError::Internal(e); - send_error(load_data.url.clone(), format_err, start_chan); - } -} - /// https://fetch.spec.whatwg.org/#concept-basic-fetch (partial) // TODO: make async. pub fn load_blob_sync diff --git a/components/net/chrome_loader.rs b/components/net/chrome_loader.rs index 5e14d130fb1..6ddb096548a 100644 --- a/components/net/chrome_loader.rs +++ b/components/net/chrome_loader.rs @@ -2,13 +2,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use file_loader; -use mime_classifier::MimeClassifier; -use net_traits::{LoadConsumer, LoadData, NetworkError}; -use resource_thread::{CancellationListener, send_error}; use servo_url::ServoUrl; use std::fs::canonicalize; -use std::sync::Arc; use url::percent_encoding::percent_decode; use util::resource_files::resources_dir_path; @@ -34,20 +29,3 @@ pub fn resolve_chrome_url(url: &ServoUrl) -> Result { _ => Err(()) } } - -pub fn factory(mut load_data: LoadData, - start_chan: LoadConsumer, - classifier: Arc, - cancel_listener: CancellationListener) { - let file_url = match resolve_chrome_url(&load_data.url) { - Ok(url) => url, - Err(_) => { - send_error(load_data.url, - NetworkError::Internal("Invalid chrome URL.".to_owned()), - start_chan); - return; - } - }; - load_data.url = file_url; - file_loader::factory(load_data, start_chan, classifier, cancel_listener) -} diff --git a/components/net/data_loader.rs b/components/net/data_loader.rs index 7c26efac2a9..9b2b8ce2ac7 100644 --- a/components/net/data_loader.rs +++ b/components/net/data_loader.rs @@ -3,28 +3,11 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use hyper::mime::{Attr, Mime, SubLevel, TopLevel, Value}; -use mime_classifier::MimeClassifier; -use net_traits::{LoadData, Metadata, NetworkError}; -use net_traits::LoadConsumer; -use net_traits::ProgressMsg::{Done, Payload}; -use resource_thread::{CancellationListener, send_error, start_sending_sniffed_opt}; use rustc_serialize::base64::FromBase64; use servo_url::ServoUrl; -use std::sync::Arc; use url::Position; use url::percent_encoding::percent_decode; -pub fn factory(load_data: LoadData, - senders: LoadConsumer, - classifier: Arc, - cancel_listener: CancellationListener) { - // NB: we don't spawn a new thread. - // Hypothesis: data URLs are too small for parallel base64 etc. to be worth it. - // Should be tested at some point. - // Left in separate function to allow easy moving to a thread, if desired. - load(load_data, senders, classifier, cancel_listener) -} - pub enum DecodeError { InvalidDataUri, NonBase64DataUri, @@ -70,33 +53,3 @@ pub fn decode(url: &ServoUrl) -> Result { } Ok((content_type, bytes)) } - -pub fn load(load_data: LoadData, - start_chan: LoadConsumer, - classifier: Arc, - cancel_listener: CancellationListener) { - let url = load_data.url; - - if cancel_listener.is_cancelled() { - return; - } - - match decode(&url) { - Ok((content_type, bytes)) => { - let mut metadata = Metadata::default(url); - metadata.set_content_type(Some(content_type).as_ref()); - if let Ok(chan) = start_sending_sniffed_opt(start_chan, - metadata, - classifier, - &bytes, - load_data.context) { - let _ = chan.send(Payload(bytes)); - let _ = chan.send(Done(Ok(()))); - } - }, - Err(DecodeError::InvalidDataUri) => - send_error(url, NetworkError::Internal("invalid data uri".to_owned()), start_chan), - Err(DecodeError::NonBase64DataUri) => - send_error(url, NetworkError::Internal("non-base64 data uri".to_owned()), start_chan), - } -} diff --git a/components/net/file_loader.rs b/components/net/file_loader.rs deleted file mode 100644 index f5737fecd72..00000000000 --- a/components/net/file_loader.rs +++ /dev/null @@ -1,139 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use about_loader; -use mime_classifier::MimeClassifier; -use mime_guess::guess_mime_type; -use msg::constellation_msg::PipelineId; -use net_traits::{LoadConsumer, LoadData, LoadOrigin, Metadata, NetworkError, ReferrerPolicy}; -use net_traits::ProgressMsg::{Done, Payload}; -use resource_thread::{CancellationListener, ProgressSender}; -use resource_thread::{send_error, start_sending_sniffed_opt}; -use servo_url::ServoUrl; -use std::borrow::ToOwned; -use std::error::Error; -use std::fs::File; -use std::io::Read; -use std::path::Path; -use std::sync::Arc; -use util::thread::spawn_named; - -static READ_SIZE: usize = 8192; - -enum ReadStatus { - Partial(Vec), - EOF, -} - -enum LoadResult { - Cancelled, - Finished, -} - -struct FileLoadOrigin; -impl LoadOrigin for FileLoadOrigin { - fn referrer_url(&self) -> Option { - None - } - fn referrer_policy(&self) -> Option { - None - } - fn pipeline_id(&self) -> Option { - None - } -} - -fn read_block(reader: &mut File) -> Result { - let mut buf = vec![0; READ_SIZE]; - match reader.read(&mut buf) { - Ok(0) => Ok(ReadStatus::EOF), - Ok(n) => { - buf.truncate(n); - Ok(ReadStatus::Partial(buf)) - } - Err(e) => Err(e.description().to_owned()), - } -} - -fn read_all(reader: &mut File, progress_chan: &ProgressSender, cancel_listener: &CancellationListener) - -> Result { - while !cancel_listener.is_cancelled() { - match try!(read_block(reader)) { - ReadStatus::Partial(buf) => progress_chan.send(Payload(buf)).unwrap(), - ReadStatus::EOF => return Ok(LoadResult::Finished), - } - } - let _ = progress_chan.send(Done(Err(NetworkError::LoadCancelled))); - Ok(LoadResult::Cancelled) -} - -fn get_progress_chan(load_data: LoadData, file_path: &Path, - senders: LoadConsumer, classifier: Arc, buf: &[u8]) - -> Result { - let mut metadata = Metadata::default(load_data.url); - let mime_type = guess_mime_type(file_path); - metadata.set_content_type(Some(&mime_type)); - return start_sending_sniffed_opt(senders, metadata, classifier, buf, load_data.context); -} - -pub fn factory(load_data: LoadData, - senders: LoadConsumer, - classifier: Arc, - cancel_listener: CancellationListener) { - assert!(load_data.url.scheme() == "file"); - spawn_named("file_loader".to_owned(), move || { - let file_path = match load_data.url.to_file_path() { - Ok(file_path) => file_path, - Err(_) => { - send_error(load_data.url, NetworkError::Internal("Could not parse path".to_owned()), senders); - return; - }, - }; - let mut file = File::open(&file_path); - let reader = match file { - Ok(ref mut reader) => reader, - Err(_) => { - // this should be one of the three errors listed in - // http://doc.rust-lang.org/std/fs/struct.OpenOptions.html#method.open - // but, we'll go for a "file not found!" - let url = ServoUrl::parse("about:not-found").unwrap(); - let load_data_404 = LoadData::new(load_data.context, url, &FileLoadOrigin); - about_loader::factory(load_data_404, senders, classifier, cancel_listener); - return; - } - }; - - if cancel_listener.is_cancelled() { - if let Ok(progress_chan) = get_progress_chan(load_data, &file_path, - senders, classifier, &[]) { - let _ = progress_chan.send(Done(Err(NetworkError::LoadCancelled))); - } - return; - } - - match read_block(reader) { - Ok(ReadStatus::Partial(buf)) => { - let progress_chan = get_progress_chan(load_data, &file_path, - senders, classifier, &buf).ok().unwrap(); - progress_chan.send(Payload(buf)).unwrap(); - let read_result = read_all(reader, &progress_chan, &cancel_listener); - if let Ok(load_result) = read_result { - match load_result { - LoadResult::Cancelled => return, - LoadResult::Finished => progress_chan.send(Done(Ok(()))).unwrap(), - } - } - } - Ok(ReadStatus::EOF) => { - if let Ok(chan) = get_progress_chan(load_data, &file_path, - senders, classifier, &[]) { - let _ = chan.send(Done(Ok(()))); - } - } - Err(e) => { - send_error(load_data.url, NetworkError::Internal(e), senders); - } - } - }); -} diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index f40934d5e7c..69dcf1dddcd 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -4,90 +4,39 @@ use brotli::Decompressor; use connector::Connector; -use content_blocker_parser::{LoadType, Reaction, Request as CBRequest, ResourceType}; -use content_blocker_parser::{RuleList, process_rules_for_request}; +use content_blocker_parser::RuleList; use cookie; use cookie_storage::CookieStorage; use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, HttpRequest as DevtoolsHttpRequest}; use devtools_traits::{HttpResponse as DevtoolsHttpResponse, NetworkEvent}; use flate2::read::{DeflateDecoder, GzDecoder}; -use fnv::FnvHashSet; -use hsts::{HstsEntry, HstsList, secure_url}; +use hsts::HstsList; use hyper::Error as HttpError; use hyper::LanguageTag; use hyper::client::{Pool, Request, Response}; -use hyper::header::{Accept, AcceptEncoding, ContentEncoding, ContentLength, ContentType, Host, Referer}; -use hyper::header::{AcceptLanguage, Authorization, Basic}; -use hyper::header::{Encoding, Header, Headers, Quality, QualityItem}; -use hyper::header::{Location, SetCookie, StrictTransportSecurity, UserAgent, qitem}; +use hyper::header::{AcceptEncoding, AcceptLanguage, Basic, ContentEncoding, ContentLength}; +use hyper::header::{Encoding, Header, Headers, Quality, QualityItem, Referer}; +use hyper::header::{SetCookie, qitem}; use hyper::http::RawStatus; use hyper::method::Method; -use hyper::mime::{Mime, SubLevel, TopLevel}; use hyper::net::Fresh; -use hyper::status::{StatusClass, StatusCode}; -use hyper_serde::Serde; -use ipc_channel::ipc::{self, IpcSender}; +use hyper::status::StatusCode; use log; -use mime_classifier::MimeClassifier; use msg::constellation_msg::PipelineId; -use net_traits::{CookieSource, IncludeSubdomains, LoadConsumer, LoadContext, LoadData}; -use net_traits::{CustomResponse, CustomResponseMediator, Metadata, NetworkError, ReferrerPolicy}; -use net_traits::ProgressMsg::{Done, Payload}; +use net_traits::{CookieSource, Metadata, ReferrerPolicy}; use net_traits::hosts::replace_hosts; -use net_traits::response::HttpsState; use openssl; use openssl::ssl::error::{OpensslError, SslError}; -use profile_traits::time::{ProfilerCategory, ProfilerChan, TimerMetadata, profile}; -use profile_traits::time::{TimerMetadataFrameType, TimerMetadataReflowType}; -use resource_thread::{AuthCache, AuthCacheEntry, CancellationListener, send_error, start_sending_sniffed_opt}; +use resource_thread::{AuthCache, CancellationListener}; use servo_url::ServoUrl; -use std::borrow::{Cow, ToOwned}; -use std::boxed::FnBox; use std::error::Error; use std::fmt; -use std::io::{self, Cursor, Read, Write}; -use std::ops::Deref; +use std::io::{self, Read, Write}; use std::sync::{Arc, RwLock}; use std::sync::mpsc::Sender; use time; use time::Tm; -#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] -use tinyfiledialogs; -use url::{Position, Origin}; -use util::thread::spawn_named; -use uuid; - -pub fn factory(user_agent: Cow<'static, str>, - http_state: HttpState, - devtools_chan: Option>, - profiler_chan: ProfilerChan, - swmanager_chan: Option>, - connector: Arc>) - -> Box, - CancellationListener) + Send> { - box move |load_data: LoadData, senders, classifier, cancel_listener| { - spawn_named(format!("http_loader for {}", load_data.url), move || { - let metadata = TimerMetadata { - url: load_data.url.as_str().into(), - iframe: TimerMetadataFrameType::RootWindow, - incremental: TimerMetadataReflowType::FirstReflow, - }; - profile(ProfilerCategory::NetHTTPRequestResponse, Some(metadata), profiler_chan, || { - load_for_consumer(load_data, - senders, - classifier, - connector, - http_state, - devtools_chan, - swmanager_chan, - cancel_listener, - user_agent) - }) - }) - } -} +use url::Origin; pub enum ReadResult { Payload(Vec), @@ -129,40 +78,6 @@ fn precise_time_ms() -> u64 { time::precise_time_ns() / (1000 * 1000) } -fn load_for_consumer(load_data: LoadData, - start_chan: LoadConsumer, - classifier: Arc, - connector: Arc>, - http_state: HttpState, - devtools_chan: Option>, - swmanager_chan: Option>, - cancel_listener: CancellationListener, - user_agent: Cow<'static, str>) { - let factory = NetworkHttpRequestFactory { - connector: connector, - }; - - let ui_provider = TFDProvider; - match load(&load_data, &ui_provider, &http_state, - devtools_chan, &factory, - user_agent, &cancel_listener, swmanager_chan) { - Err(error) => { - match error.error { - LoadErrorType::ConnectionAborted { .. } => unreachable!(), - LoadErrorType::Ssl { reason } => send_error(error.url.clone(), - NetworkError::SslValidation(error.url, reason), - start_chan), - LoadErrorType::Cancelled => send_error(error.url, NetworkError::LoadCancelled, start_chan), - _ => send_error(error.url, NetworkError::Internal(error.error.description().to_owned()), start_chan) - } - } - Ok(mut load_response) => { - let metadata = load_response.metadata.clone(); - send_data(load_data.context, &mut load_response, start_chan, metadata, classifier, &cancel_listener) - } - } -} - pub struct WrappedHttpResponse { pub response: Response } @@ -216,34 +131,6 @@ impl HttpResponse for WrappedHttpResponse { } } -pub struct ReadableCustomResponse { - headers: Headers, - raw_status: RawStatus, - body: Cursor> -} - -pub fn to_readable_response(custom_response: CustomResponse) -> ReadableCustomResponse { - ReadableCustomResponse { - headers: custom_response.headers, - raw_status: custom_response.raw_status, - body: Cursor::new(custom_response.body) - } -} - -impl HttpResponse for ReadableCustomResponse { - fn headers(&self) -> &Headers { &self.headers } - fn status(&self) -> StatusCode { - StatusCode::Ok - } - fn status_raw(&self) -> &RawStatus { &self.raw_status } -} - -impl Read for ReadableCustomResponse { - fn read(&mut self, buf: &mut [u8]) -> io::Result { - self.body.read(buf) - } -} - pub trait HttpRequestFactory { type R: HttpRequest; @@ -356,15 +243,8 @@ pub enum LoadErrorType { Cancelled, Connection { reason: String }, ConnectionAborted { reason: String }, - ContentBlocked, - // Preflight fetch inconsistent with main fetch - CorsPreflightFetchInconsistent, Decoding { reason: String }, - InvalidRedirect { reason: String }, - MaxRedirects(u32), // u32 indicates number of redirects that occurred - RedirectLoop, Ssl { reason: String }, - UnsupportedScheme { scheme: String }, } impl fmt::Display for LoadErrorType { @@ -379,14 +259,8 @@ impl Error for LoadErrorType { LoadErrorType::Cancelled => "load cancelled", LoadErrorType::Connection { ref reason } => reason, LoadErrorType::ConnectionAborted { ref reason } => reason, - LoadErrorType::ContentBlocked => "content blocked", - LoadErrorType::CorsPreflightFetchInconsistent => "preflight fetch inconsistent with main fetch", LoadErrorType::Decoding { ref reason } => reason, - LoadErrorType::InvalidRedirect { ref reason } => reason, - LoadErrorType::MaxRedirects(_) => "too many redirects", - LoadErrorType::RedirectLoop => "redirect loop", LoadErrorType::Ssl { ref reason } => reason, - LoadErrorType::UnsupportedScheme { .. } => "unsupported url scheme", } } } @@ -403,18 +277,6 @@ pub fn set_default_accept_encoding(headers: &mut Headers) { ])); } -fn set_default_accept(headers: &mut Headers) { - if !headers.has::() { - let accept = Accept(vec![ - qitem(Mime(TopLevel::Text, SubLevel::Html, vec![])), - qitem(Mime(TopLevel::Application, SubLevel::Ext("xhtml+xml".to_owned()), vec![])), - QualityItem::new(Mime(TopLevel::Application, SubLevel::Xml, vec![]), Quality(900u16)), - QualityItem::new(Mime(TopLevel::Star, SubLevel::Star, vec![]), Quality(800u16)), - ]); - headers.set(accept); - } -} - pub fn set_default_accept_language(headers: &mut Headers) { if headers.has::() { return; @@ -535,33 +397,6 @@ pub fn set_cookies_from_headers(url: &ServoUrl, headers: &Headers, cookie_jar: & } } -fn update_sts_list_from_response(url: &ServoUrl, response: &HttpResponse, hsts_list: &Arc>) { - if url.scheme() != "https" { - return; - } - - if let Some(header) = response.headers().get::() { - if let Some(host) = url.domain() { - let mut hsts_list = hsts_list.write().unwrap(); - let include_subdomains = if header.include_subdomains { - IncludeSubdomains::Included - } else { - IncludeSubdomains::NotIncluded - }; - - if let Some(entry) = HstsEntry::new(host.to_owned(), include_subdomains, Some(header.max_age)) { - info!("adding host {} to the strict transport security list", host); - info!("- max-age {}", header.max_age); - if header.include_subdomains { - info!("- includeSubdomains"); - } - - hsts_list.push(entry); - } - } - } -} - pub struct StreamedResponse { decoder: Decoder, pub metadata: Metadata @@ -662,63 +497,6 @@ pub fn send_response_to_devtools(devtools_chan: &Sender, let _ = devtools_chan.send(DevtoolsControlMsg::FromChrome(msg)); } -fn request_must_be_secured(url: &ServoUrl, hsts_list: &Arc>) -> bool { - match url.domain() { - Some(domain) => hsts_list.read().unwrap().is_host_secure(domain), - None => false - } -} - -pub fn modify_request_headers(headers: &mut Headers, - url: &ServoUrl, - user_agent: &str, - referrer_policy: Option, - referrer_url: &mut Option) { - // Ensure that the host header is set from the original url - let host = Host { - hostname: url.host_str().unwrap().to_owned(), - port: url.port_or_known_default() - }; - headers.set(host); - - // If the user-agent has not already been set, then use the - // browser's default user-agent or the user-agent override - // from the command line. If the user-agent is set, don't - // modify it, as setting of the user-agent by the user is - // allowed. - // https://fetch.spec.whatwg.org/#concept-http-network-or-cache-fetch step 8 - if !headers.has::() { - headers.set(UserAgent(user_agent.to_owned())); - } - - set_default_accept(headers); - set_default_accept_language(headers); - set_default_accept_encoding(headers); - - *referrer_url = determine_request_referrer(headers, - referrer_policy.clone(), - referrer_url.clone(), - url.clone()); - - if let Some(referrer_val) = referrer_url.clone() { - headers.set(Referer(referrer_val.into_string())); - } -} - -fn set_auth_header(headers: &mut Headers, - url: &ServoUrl, - auth_cache: &Arc>) { - if !headers.has::>() { - if let Some(auth) = auth_from_url(url) { - headers.set(auth); - } else { - if let Some(basic) = auth_from_cache(auth_cache, &url.origin()) { - headers.set(Authorization(basic)); - } - } - } -} - pub fn auth_from_cache(auth_cache: &Arc>, origin: &Origin) -> Option { if let Some(ref auth_entry) = auth_cache.read().unwrap().entries.get(&origin.ascii_serialization()) { let user_name = auth_entry.user_name.clone(); @@ -729,37 +507,6 @@ pub fn auth_from_cache(auth_cache: &Arc>, origin: &Origin) -> } } -fn auth_from_url(doc_url: &ServoUrl) -> Option> { - let username = doc_url.username(); - if username != "" { - Some(Authorization(Basic { - username: username.to_owned(), - password: Some(doc_url.password().unwrap_or("").to_owned()) - })) - } else { - None - } -} - -pub fn process_response_headers(response: &HttpResponse, - url: &ServoUrl, - cookie_jar: &Arc>, - hsts_list: &Arc>, - load_data: &LoadData) { - info!("got HTTP response {}, headers:", response.status()); - if log_enabled!(log::LogLevel::Info) { - for header in response.headers().iter() { - info!(" - {}", header); - } - } - - // https://fetch.spec.whatwg.org/#concept-http-network-fetch step 9 - if load_data.credentials_flag { - set_cookies_from_headers(url, response.headers(), cookie_jar); - } - update_sts_list_from_response(url, response, hsts_list); -} - pub fn obtain_response(request_factory: &HttpRequestFactory, url: &ServoUrl, method: &Method, @@ -871,312 +618,6 @@ pub trait UIProvider { fn input_username_and_password(&self, prompt: &str) -> (Option, Option); } -impl UIProvider for TFDProvider { - #[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))] - fn input_username_and_password(&self, prompt: &str) -> (Option, Option) { - (tinyfiledialogs::input_box(prompt, "Username:", ""), - tinyfiledialogs::input_box(prompt, "Password:", "")) - } - - #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))] - fn input_username_and_password(&self, _prompt: &str) -> (Option, Option) { - (None, None) - } -} - -struct TFDProvider; - -pub fn load(load_data: &LoadData, - ui_provider: &B, - http_state: &HttpState, - devtools_chan: Option>, - request_factory: &HttpRequestFactory, - user_agent: Cow<'static, str>, - cancel_listener: &CancellationListener, - swmanager_chan: Option>) - -> Result where A: HttpRequest + 'static, B: UIProvider { - let mut iters = 0; - // URL of the document being loaded, as seen by all the higher-level code. - let mut doc_url = load_data.url.clone(); - let mut redirected_to = FnvHashSet::with_hasher(Default::default()); - let mut method = load_data.method.clone(); - // URL of referrer - to be updated with redirects - let mut referrer_url = load_data.referrer_url.clone(); - - let mut new_auth_header: Option> = None; - - if cancel_listener.is_cancelled() { - return Err(LoadError::new(doc_url, LoadErrorType::Cancelled)); - } - - let (msg_sender, msg_receiver) = ipc::channel().unwrap(); - let response_mediator = CustomResponseMediator { - response_chan: msg_sender, - load_url: doc_url.clone() - }; - if let Some(sender) = swmanager_chan { - let _ = sender.send(response_mediator); - if let Ok(Some(custom_response)) = msg_receiver.recv() { - let metadata = Metadata::default(doc_url.clone()); - let readable_response = to_readable_response(custom_response); - return StreamedResponse::from_http_response(box readable_response, metadata); - } - } else { - debug!("Did not receive a custom response"); - } - - // If the URL is a view-source scheme then the scheme data contains the - // real URL that should be used for which the source is to be viewed. - // Change our existing URL to that and keep note that we are viewing - // the source rather than rendering the contents of the URL. - let viewing_source = doc_url.scheme() == "view-source"; - if viewing_source { - doc_url = ServoUrl::parse(&load_data.url[Position::BeforeUsername..]).unwrap(); - } - - // Loop to handle redirects. - loop { - iters = iters + 1; - - if doc_url.scheme() == "http" && request_must_be_secured(&doc_url, &http_state.hsts_list) { - info!("{} is in the strict transport security list, requesting secure host", doc_url); - doc_url = ServoUrl::from_url(secure_url(&doc_url.as_url().unwrap())); - } - - if iters > 20 { - return Err(LoadError::new(doc_url, LoadErrorType::MaxRedirects(iters - 1))); - } - - if !matches!(doc_url.scheme(), "http" | "https") { - let scheme = doc_url.scheme().to_owned(); - return Err(LoadError::new(doc_url, LoadErrorType::UnsupportedScheme { scheme: scheme })); - } - - if cancel_listener.is_cancelled() { - return Err(LoadError::new(doc_url, LoadErrorType::Cancelled)); - } - - let mut block_cookies = false; - if let Some(ref rules) = *http_state.blocked_content { - let same_origin = - load_data.referrer_url.as_ref() - .map(|url| url.origin() == doc_url.origin()) - .unwrap_or(false); - let load_type = if same_origin { LoadType::FirstParty } else { LoadType::ThirdParty }; - let actions = process_rules_for_request(rules, &CBRequest { - url: doc_url.as_url().unwrap(), - resource_type: to_resource_type(&load_data.context), - load_type: load_type, - }); - for action in actions { - match action { - Reaction::Block => { - return Err(LoadError::new(doc_url, LoadErrorType::ContentBlocked)); - }, - Reaction::BlockCookies => block_cookies = true, - Reaction::HideMatchingElements(_) => (), - } - } - } - - info!("requesting {}", doc_url); - - // Avoid automatically preserving request headers when redirects occur. - // See https://bugzilla.mozilla.org/show_bug.cgi?id=401564 and - // https://bugzilla.mozilla.org/show_bug.cgi?id=216828 . - // Only preserve ones which have been explicitly marked as such. - let mut request_headers = if iters == 1 { - let mut combined_headers = load_data.headers.clone(); - combined_headers.extend(load_data.preserved_headers.iter()); - combined_headers - } else { - load_data.preserved_headers.clone() - }; - - let request_id = devtools_chan.as_ref().map(|_| { - uuid::Uuid::new_v4().simple().to_string() - }); - - modify_request_headers(&mut request_headers, &doc_url, - &user_agent, load_data.referrer_policy, - &mut referrer_url); - - // https://fetch.spec.whatwg.org/#concept-http-network-or-cache-fetch step 11 - if load_data.credentials_flag { - if !block_cookies { - set_request_cookies(&doc_url, &mut request_headers, &http_state.cookie_jar); - } - - // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch step 12 - set_auth_header(&mut request_headers, &doc_url, &http_state.auth_cache); - } - - //if there is a new auth header then set the request headers with it - if let Some(ref auth_header) = new_auth_header { - request_headers.set(auth_header.clone()); - } - - let (response, msg) = - try!(obtain_response(request_factory, &doc_url, &method, &request_headers, - &cancel_listener, &load_data.data, &load_data.method, - &load_data.pipeline_id, iters, - request_id.as_ref().map(Deref::deref), false)); - - process_response_headers(&response, &doc_url, &http_state.cookie_jar, &http_state.hsts_list, &load_data); - - //if response status is unauthorized then prompt user for username and password - if response.status() == StatusCode::Unauthorized && - response.headers().get_raw("WWW-Authenticate").is_some() { - let (username_option, password_option) = - ui_provider.input_username_and_password(doc_url.as_str()); - - match username_option { - Some(name) => { - new_auth_header = Some(Authorization(Basic { username: name, password: password_option })); - continue; - }, - None => {}, - } - } - - new_auth_header = None; - - if let Some(auth_header) = request_headers.get::>() { - if response.status().class() == StatusClass::Success || - response.status().class() == StatusClass::Redirection { - let auth_entry = AuthCacheEntry { - user_name: auth_header.username.to_owned(), - password: auth_header.password.to_owned().unwrap(), - }; - - let serialized_origin = doc_url.origin().ascii_serialization(); - http_state.auth_cache.write().unwrap().entries.insert(serialized_origin, auth_entry); - } - } - - // --- Loop if there's a redirect - if response.status().class() == StatusClass::Redirection { - if let Some(&Location(ref new_url)) = response.headers().get::() { - // CORS (https://fetch.spec.whatwg.org/#http-fetch, status section, point 9, 10) - if let Some(ref c) = load_data.cors { - if c.preflight { - return Err(LoadError::new(doc_url, LoadErrorType::CorsPreflightFetchInconsistent)); - } else { - // XXXManishearth There are some CORS-related steps here, - // but they don't seem necessary until credentials are implemented - } - } - - let new_doc_url = match doc_url.join(&new_url) { - Ok(u) => u, - Err(e) => return Err( - LoadError::new(doc_url, LoadErrorType::InvalidRedirect { reason: e.to_string() })), - }; - - // According to https://tools.ietf.org/html/rfc7231#section-6.4.2, - // historically UAs have rewritten POST->GET on 301 and 302 responses. - if method == Method::Post && - (response.status() == StatusCode::MovedPermanently || - response.status() == StatusCode::Found) { - method = Method::Get; - } - - if redirected_to.contains(&new_doc_url) { - return Err(LoadError::new(doc_url, LoadErrorType::RedirectLoop)); - } - - info!("redirecting to {}", new_doc_url); - doc_url = new_doc_url; - - redirected_to.insert(doc_url.clone()); - } - } - - // Only notify the devtools about the final request that received a response. - if let Some(m) = msg { - send_request_to_devtools(m, devtools_chan.as_ref().unwrap()); - } - let mut adjusted_headers = response.headers().clone(); - - if viewing_source { - adjusted_headers.set(ContentType(Mime(TopLevel::Text, SubLevel::Plain, vec![]))); - } - - let mut metadata: Metadata = Metadata::default(doc_url.clone()); - metadata.set_content_type(match adjusted_headers.get() { - Some(&ContentType(ref mime)) => Some(mime), - None => None - }); - metadata.headers = Some(Serde(adjusted_headers)); - metadata.status = Some((response.status_raw().0, - response.status_raw().1.as_bytes().to_vec())); - metadata.https_state = if doc_url.scheme() == "https" { - HttpsState::Modern - } else { - HttpsState::None - }; - metadata.referrer = referrer_url.clone(); - - // --- Tell devtools that we got a response - // Send an HttpResponse message to devtools with the corresponding request_id - // TODO: Send this message even when the load fails? - if let Some(pipeline_id) = load_data.pipeline_id { - if let Some(ref chan) = devtools_chan { - send_response_to_devtools( - &chan, request_id.unwrap(), - metadata.headers.clone().map(Serde::into_inner), - metadata.status.clone(), - pipeline_id); - } - } - if response.status().class() == StatusClass::Redirection { - continue; - } else { - return StreamedResponse::from_http_response(box response, metadata); - } - } -} - -fn send_data(context: LoadContext, - reader: &mut R, - start_chan: LoadConsumer, - metadata: Metadata, - classifier: Arc, - cancel_listener: &CancellationListener) { - let (progress_chan, mut chunk) = { - let buf = match read_block(reader) { - Ok(ReadResult::Payload(buf)) => buf, - _ => vec!(), - }; - let p = match start_sending_sniffed_opt(start_chan, metadata, classifier, &buf, context) { - Ok(p) => p, - _ => return - }; - (p, buf) - }; - - loop { - if cancel_listener.is_cancelled() { - let _ = progress_chan.send(Done(Err(NetworkError::LoadCancelled))); - return; - } - - if progress_chan.send(Payload(chunk)).is_err() { - // The send errors when the receiver is out of scope, - // which will happen if the fetch has timed out (or has been aborted) - // so we don't need to continue with the loading of the file here. - return; - } - - chunk = match read_block(reader) { - Ok(ReadResult::Payload(buf)) => buf, - Ok(ReadResult::EOF) | Err(_) => break, - }; - } - - let _ = progress_chan.send(Done(Ok(()))); -} - // FIXME: This incredibly hacky. Make it more robust, and at least test it. fn is_cert_verify_error(error: &OpensslError) -> bool { match error { @@ -1205,17 +646,3 @@ fn format_ssl_error(error: &OpensslError) -> String { } } } - -fn to_resource_type(context: &LoadContext) -> ResourceType { - match *context { - LoadContext::Browsing => ResourceType::Document, - LoadContext::Image => ResourceType::Image, - LoadContext::AudioVideo => ResourceType::Media, - LoadContext::Plugin => ResourceType::Raw, - LoadContext::Style => ResourceType::StyleSheet, - LoadContext::Script => ResourceType::Script, - LoadContext::Font => ResourceType::Font, - LoadContext::TextTrack => ResourceType::Media, - LoadContext::CacheManifest => ResourceType::Raw, - } -} diff --git a/components/net/lib.rs b/components/net/lib.rs index f6c85a4949c..e5f3951d542 100644 --- a/components/net/lib.rs +++ b/components/net/lib.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #![feature(box_syntax)] -#![feature(fnbox)] #![feature(mpsc_select)] #![feature(plugin)] #![feature(proc_macro)] @@ -18,7 +17,6 @@ extern crate content_blocker as content_blocker_parser; extern crate cookie as cookie_rs; extern crate devtools_traits; extern crate flate2; -extern crate fnv; extern crate hyper; extern crate hyper_serde; extern crate immeta; @@ -49,7 +47,6 @@ extern crate uuid; extern crate webrender_traits; extern crate websocket; -mod about_loader; mod blob_loader; mod chrome_loader; mod connector; @@ -57,7 +54,6 @@ mod content_blocker; pub mod cookie; pub mod cookie_storage; mod data_loader; -mod file_loader; pub mod filemanager_thread; pub mod hsts; mod http_loader; diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index 988a095b57e..ad62cf148b8 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -3,21 +3,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ //! A thread that takes a URL and streams back the binary data. -use about_loader; -use blob_loader; -use chrome_loader; use connector::{Connector, create_http_connector}; use content_blocker::BLOCKED_CONTENT_RULES; use cookie; use cookie_rs; use cookie_storage::CookieStorage; -use data_loader; use devtools_traits::DevtoolsControlMsg; use fetch::methods::{FetchContext, fetch}; -use file_loader; use filemanager_thread::{FileManager, TFDProvider}; use hsts::HstsList; -use http_loader::{self, HttpState}; +use http_loader::HttpState; use hyper::client::pool::Pool; use hyper::header::{ContentType, Header, SetCookie}; use hyper::mime::{Mime, SubLevel, TopLevel}; @@ -26,7 +21,7 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcReceiverSet, IpcSender}; use mime_classifier::{ApacheBugFlag, MimeClassifier, NoSniffFlag}; use net_traits::{CookieSource, CoreResourceThread, Metadata, ProgressMsg}; use net_traits::{CoreResourceMsg, FetchResponseMsg, FetchTaskTarget, LoadConsumer}; -use net_traits::{CustomResponseMediator, LoadData, LoadResponse, NetworkError, ResourceId}; +use net_traits::{CustomResponseMediator, LoadResponse, NetworkError, ResourceId}; use net_traits::{ResourceThreads, WebSocketCommunicate, WebSocketConnectData}; use net_traits::LoadContext; use net_traits::ProgressMsg::Done; @@ -37,7 +32,6 @@ use rustc_serialize::{Decodable, Encodable}; use rustc_serialize::json; use servo_url::ServoUrl; use std::borrow::{Cow, ToOwned}; -use std::boxed::FnBox; use std::cell::Cell; use std::collections::HashMap; use std::error::Error; @@ -47,7 +41,7 @@ use std::ops::Deref; use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::{Arc, RwLock}; -use std::sync::mpsc::{Receiver, Sender, channel}; +use std::sync::mpsc::{Receiver, Sender}; use storage_thread::StorageThreadFactory; use util::prefs::PREFS; use util::thread::spawn_named; @@ -252,10 +246,8 @@ impl ResourceChannelManager { fn process_msg(&mut self, msg: CoreResourceMsg, group: &ResourceGroup, - control_sender: &CoreResourceThread) -> bool { + _control_sender: &CoreResourceThread) -> bool { match msg { - CoreResourceMsg::Load(load_data, consumer, id_sender) => - self.resource_manager.load(load_data, consumer, id_sender, control_sender.clone(), group), CoreResourceMsg::Fetch(init, sender) => self.resource_manager.fetch(init, sender, group), CoreResourceMsg::WebsocketConnect(connect, connect_data) => @@ -451,28 +443,22 @@ pub struct AuthCache { pub struct CoreResourceManager { user_agent: Cow<'static, str>, - mime_classifier: Arc, devtools_chan: Option>, swmanager_chan: Option>, - profiler_chan: ProfilerChan, filemanager: FileManager, cancel_load_map: HashMap>, - next_resource_id: ResourceId, } impl CoreResourceManager { pub fn new(user_agent: Cow<'static, str>, devtools_channel: Option>, - profiler_chan: ProfilerChan) -> CoreResourceManager { + _profiler_chan: ProfilerChan) -> CoreResourceManager { CoreResourceManager { user_agent: user_agent, - mime_classifier: Arc::new(MimeClassifier::new()), devtools_chan: devtools_channel, swmanager_chan: None, - profiler_chan: profiler_chan, filemanager: FileManager::new(), cancel_load_map: HashMap::new(), - next_resource_id: ResourceId(0), } } @@ -500,66 +486,6 @@ impl CoreResourceManager { } } - fn load(&mut self, - load_data: LoadData, - consumer: LoadConsumer, - id_sender: Option>, - resource_thread: CoreResourceThread, - resource_grp: &ResourceGroup) { - fn from_factory(factory: fn(LoadData, LoadConsumer, Arc, CancellationListener)) - -> Box, - CancellationListener) + Send> { - box move |load_data, senders, classifier, cancel_listener| { - factory(load_data, senders, classifier, cancel_listener) - } - } - - let cancel_resource = id_sender.map(|sender| { - let current_res_id = self.next_resource_id; - let _ = sender.send(current_res_id); - let (cancel_sender, cancel_receiver) = channel(); - self.cancel_load_map.insert(current_res_id, cancel_sender); - self.next_resource_id.0 += 1; - CancellableResource::new(cancel_receiver, current_res_id, resource_thread) - }); - - let cancel_listener = CancellationListener::new(cancel_resource); - let loader = match load_data.url.scheme() { - "chrome" => from_factory(chrome_loader::factory), - "file" => from_factory(file_loader::factory), - "http" | "https" | "view-source" => { - let http_state = HttpState { - blocked_content: BLOCKED_CONTENT_RULES.clone(), - hsts_list: resource_grp.hsts_list.clone(), - cookie_jar: resource_grp.cookie_jar.clone(), - auth_cache: resource_grp.auth_cache.clone() - }; - http_loader::factory(self.user_agent.clone(), - http_state, - self.devtools_chan.clone(), - self.profiler_chan.clone(), - self.swmanager_chan.clone(), - resource_grp.connector.clone()) - }, - "data" => from_factory(data_loader::factory), - "about" => from_factory(about_loader::factory), - "blob" => blob_loader::factory(self.filemanager.clone()), - _ => { - debug!("resource_thread: no loader for scheme {}", load_data.url.scheme()); - send_error(load_data.url, NetworkError::Internal("no loader for scheme".to_owned()), consumer); - return - } - }; - debug!("loading url: {}", load_data.url); - - loader.call_box((load_data, - consumer, - self.mime_classifier.clone(), - cancel_listener)); - } - fn fetch(&self, init: RequestInit, sender: IpcSender, diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index 9439102bf0c..a0ebcdde088 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -414,8 +414,6 @@ pub struct WebSocketConnectData { #[derive(Deserialize, Serialize)] pub enum CoreResourceMsg { - /// Request the data associated with a particular URL - Load(LoadData, LoadConsumer, Option>), Fetch(RequestInit, IpcSender), /// Try to make a websocket connection to a URL. WebsocketConnect(WebSocketCommunicate, WebSocketConnectData), diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 28687810609..31ff9f529b5 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -1471,7 +1471,6 @@ dependencies = [ "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "immeta 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/ports/servo/Cargo.lock b/ports/servo/Cargo.lock index 4c02e017bf3..af52dad8c24 100644 --- a/ports/servo/Cargo.lock +++ b/ports/servo/Cargo.lock @@ -1558,7 +1558,6 @@ dependencies = [ "cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "devtools_traits 0.0.1", "flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)", "hyper_serde 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "immeta 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", From ffc2e09ea7d8588b5c43d67f8888114b760e22a5 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 22 Nov 2016 00:04:08 +0100 Subject: [PATCH 4/9] Remove unused CancellationListener argument to obtain_response. --- components/net/fetch/methods.rs | 5 +---- components/net/http_loader.rs | 9 +-------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs index f6a6c62f489..adff11d425b 100644 --- a/components/net/fetch/methods.rs +++ b/components/net/fetch/methods.rs @@ -28,7 +28,6 @@ use net_traits::request::{CacheMode, CredentialsMode, Destination}; use net_traits::request::{RedirectMode, Referrer, Request, RequestMode, ResponseTainting}; use net_traits::request::{Type, Origin, Window}; use net_traits::response::{HttpsState, Response, ResponseBody, ResponseType}; -use resource_thread::CancellationListener; use servo_url::ServoUrl; use std::borrow::Cow; use std::collections::HashSet; @@ -992,7 +991,6 @@ fn http_network_fetch(request: Rc, connector: connection, }; let url = request.current_url(); - let cancellation_listener = CancellationListener::new(None); let request_id = context.devtools_chan.as_ref().map(|_| { uuid::Uuid::new_v4().simple().to_string() @@ -1004,7 +1002,7 @@ fn http_network_fetch(request: Rc, let is_xhr = request.destination == Destination::None; let wrapped_response = obtain_response(&factory, &url, &request.method.borrow(), &request.headers.borrow(), - &cancellation_listener, &request.body.borrow(), &request.method.borrow(), + &request.body.borrow(), &request.method.borrow(), &request.pipeline_id.get(), request.redirect_count.get() + 1, request_id.as_ref().map(Deref::deref), is_xhr); @@ -1015,7 +1013,6 @@ fn http_network_fetch(request: Rc, let error = match error.error { LoadErrorType::ConnectionAborted { .. } => unreachable!(), LoadErrorType::Ssl { reason } => NetworkError::SslValidation(error.url, reason), - LoadErrorType::Cancelled => NetworkError::LoadCancelled, e => NetworkError::Internal(e.description().to_owned()) }; return Response::network_error(error); diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 69dcf1dddcd..1d10f684a90 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -27,7 +27,7 @@ use net_traits::{CookieSource, Metadata, ReferrerPolicy}; use net_traits::hosts::replace_hosts; use openssl; use openssl::ssl::error::{OpensslError, SslError}; -use resource_thread::{AuthCache, CancellationListener}; +use resource_thread::AuthCache; use servo_url::ServoUrl; use std::error::Error; use std::fmt; @@ -240,7 +240,6 @@ impl LoadError { #[derive(Eq, PartialEq, Debug)] pub enum LoadErrorType { - Cancelled, Connection { reason: String }, ConnectionAborted { reason: String }, Decoding { reason: String }, @@ -256,7 +255,6 @@ impl fmt::Display for LoadErrorType { impl Error for LoadErrorType { fn description(&self) -> &str { match *self { - LoadErrorType::Cancelled => "load cancelled", LoadErrorType::Connection { ref reason } => reason, LoadErrorType::ConnectionAborted { ref reason } => reason, LoadErrorType::Decoding { ref reason } => reason, @@ -511,7 +509,6 @@ pub fn obtain_response(request_factory: &HttpRequestFactory, url: &ServoUrl, method: &Method, request_headers: &Headers, - cancel_listener: &CancellationListener, data: &Option>, load_data_method: &Method, pipeline_id: &Option, @@ -569,10 +566,6 @@ pub fn obtain_response(request_factory: &HttpRequestFactory, let connect_end = precise_time_ms(); - if cancel_listener.is_cancelled() { - return Err(LoadError::new(connection_url.clone(), LoadErrorType::Cancelled)); - } - let send_start = precise_time_ms(); let maybe_response = req.send(request_body); From d6db049a7f57304d55d0474ad23efe683a6b8654 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 22 Nov 2016 00:22:50 +0100 Subject: [PATCH 5/9] Remove unused LoadData and LoadOrigin types. --- components/net_traits/lib.rs | 56 ------------------------- components/script/dom/xmlhttprequest.rs | 19 +-------- components/script_traits/lib.rs | 1 - 3 files changed, 2 insertions(+), 74 deletions(-) diff --git a/components/net_traits/lib.rs b/components/net_traits/lib.rs index a0ebcdde088..6810bdb339d 100644 --- a/components/net_traits/lib.rs +++ b/components/net_traits/lib.rs @@ -40,7 +40,6 @@ use filemanager_thread::FileManagerThreadMsg; use heapsize::HeapSizeOf; use hyper::header::{ContentType, Headers}; use hyper::http::RawStatus; -use hyper::method::Method; use hyper::mime::{Attr, Mime}; use hyper_serde::Serde; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; @@ -134,61 +133,6 @@ pub enum ReferrerPolicy { StrictOriginWhenCrossOrigin, } -#[derive(Clone, Deserialize, Serialize, HeapSizeOf)] -pub struct LoadData { - pub url: ServoUrl, - #[ignore_heap_size_of = "Defined in hyper"] - #[serde(deserialize_with = "::hyper_serde::deserialize", - serialize_with = "::hyper_serde::serialize")] - pub method: Method, - #[ignore_heap_size_of = "Defined in hyper"] - #[serde(deserialize_with = "::hyper_serde::deserialize", - serialize_with = "::hyper_serde::serialize")] - /// Headers that will apply to the initial request only - pub headers: Headers, - #[ignore_heap_size_of = "Defined in hyper"] - #[serde(deserialize_with = "::hyper_serde::deserialize", - serialize_with = "::hyper_serde::serialize")] - /// Headers that will apply to the initial request and any redirects - /// Unused in fetch - pub preserved_headers: Headers, - pub data: Option>, - pub cors: Option, - pub pipeline_id: Option, - // https://fetch.spec.whatwg.org/#concept-http-fetch step 4.3 - pub credentials_flag: bool, - pub context: LoadContext, - /// The policy and referring URL for the originator of this request - pub referrer_policy: Option, - pub referrer_url: Option -} - -impl LoadData { - pub fn new(context: LoadContext, - url: ServoUrl, - load_origin: &LoadOrigin) -> LoadData { - LoadData { - url: url, - method: Method::Get, - headers: Headers::new(), - preserved_headers: Headers::new(), - data: None, - cors: None, - pipeline_id: load_origin.pipeline_id(), - credentials_flag: true, - context: context, - referrer_policy: load_origin.referrer_policy(), - referrer_url: load_origin.referrer_url().clone(), - } - } -} - -pub trait LoadOrigin { - fn referrer_url(&self) -> Option; - fn referrer_policy(&self) -> Option; - fn pipeline_id(&self) -> Option; -} - #[derive(Deserialize, Serialize)] pub enum FetchResponseMsg { // todo: should have fields for transmitted/total bytes diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index a89c5c51799..292de083c84 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -47,9 +47,8 @@ use ipc_channel::router::ROUTER; use js::jsapi::{JSContext, JS_ParseJSON}; use js::jsapi::JS_ClearPendingException; use js::jsval::{JSVal, NullValue, UndefinedValue}; -use msg::constellation_msg::PipelineId; use net_traits::{FetchMetadata, FilteredMetadata}; -use net_traits::{FetchResponseListener, LoadOrigin, NetworkError, ReferrerPolicy}; +use net_traits::{FetchResponseListener, NetworkError, ReferrerPolicy}; use net_traits::CoreResourceMsg::Fetch; use net_traits::request::{CredentialsMode, Destination, RequestInit, RequestMode}; use net_traits::trim_http_whitespace; @@ -272,20 +271,6 @@ impl XMLHttpRequest { } } -impl LoadOrigin for XMLHttpRequest { - fn referrer_url(&self) -> Option { - return self.referrer_url.clone(); - } - - fn referrer_policy(&self) -> Option { - return self.referrer_policy; - } - - fn pipeline_id(&self) -> Option { - Some(self.global().pipeline_id()) - } -} - impl XMLHttpRequestMethods for XMLHttpRequest { // https://xhr.spec.whatwg.org/#handler-xhr-onreadystatechange event_handler!(readystatechange, GetOnreadystatechange, SetOnreadystatechange); @@ -597,7 +582,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest { origin: self.global().get_url(), referrer_url: self.referrer_url.clone(), referrer_policy: self.referrer_policy.clone(), - pipeline_id: self.pipeline_id(), + pipeline_id: Some(self.global().pipeline_id()), .. RequestInit::default() }; diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 458972283db..1f825e60783 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -125,7 +125,6 @@ pub enum LayoutControlMsg { GetWebFontLoadState(IpcSender), } -/// Similar to `net::resource_thread::LoadData` /// can be passed to `LoadUrl` to load a page with GET/POST /// parameters or headers #[derive(Clone, Deserialize, Serialize)] From 5febfdc4d646fd9924873cd9e13c618981490663 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 22 Nov 2016 00:29:19 +0100 Subject: [PATCH 6/9] Remove unused UIProvider trait definition. --- components/net/http_loader.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/components/net/http_loader.rs b/components/net/http_loader.rs index 1d10f684a90..b7bc1fa5302 100644 --- a/components/net/http_loader.rs +++ b/components/net/http_loader.rs @@ -607,10 +607,6 @@ pub fn obtain_response(request_factory: &HttpRequestFactory, Ok((response, msg)) } -pub trait UIProvider { - fn input_username_and_password(&self, prompt: &str) -> (Option, Option); -} - // FIXME: This incredibly hacky. Make it more robust, and at least test it. fn is_cert_verify_error(error: &OpensslError) -> bool { match error { From 7913f3adafd680f05340f7d2201d6e618d187ace Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 22 Nov 2016 10:12:25 +0100 Subject: [PATCH 7/9] Remove the unused CancellationListener arguments in filemanager_thread. --- components/net/blob_loader.rs | 2 +- components/net/filemanager_thread.rs | 31 +++++++++------------------- components/net/resource_thread.rs | 2 +- tests/unit/net/filemanager_thread.rs | 8 +++---- 4 files changed, 16 insertions(+), 27 deletions(-) diff --git a/components/net/blob_loader.rs b/components/net/blob_loader.rs index cd57dfd25be..3594dccc265 100644 --- a/components/net/blob_loader.rs +++ b/components/net/blob_loader.rs @@ -31,7 +31,7 @@ pub fn load_blob_sync let (sender, receiver) = ipc::channel().unwrap(); let check_url_validity = true; - filemanager.read_file(sender, id, check_url_validity, origin, None); + filemanager.read_file(sender, id, check_url_validity, origin); let blob_buf = match receiver.recv().unwrap() { Ok(ReadFileProgress::Meta(blob_buf)) => blob_buf, diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index f109c77c251..641b1394539 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.rs @@ -7,7 +7,6 @@ use mime_guess::guess_mime_type_opt; use net_traits::blob_url_store::{BlobBuf, BlobURLStoreError}; use net_traits::filemanager_thread::{FileManagerResult, FileManagerThreadMsg, FileOrigin, FilterPattern}; use net_traits::filemanager_thread::{FileManagerThreadError, ReadFileProgress, RelativePos, SelectedFile}; -use resource_thread::CancellationListener; use std::collections::HashMap; use std::fs::File; use std::io::{Read, Seek, SeekFrom}; @@ -128,12 +127,11 @@ impl FileManager { sender: IpcSender>, id: Uuid, check_url_validity: bool, - origin: FileOrigin, - cancel_listener: Option) { + origin: FileOrigin) { let store = self.store.clone(); spawn_named("read file".to_owned(), move || { if let Err(e) = store.try_read_file(&sender, id, check_url_validity, - origin, cancel_listener) { + origin) { let _ = sender.send(Err(FileManagerThreadError::BlobURLStoreError(e))); } }) @@ -153,7 +151,6 @@ impl FileManager { /// Message handler pub fn handle(&self, msg: FileManagerThreadMsg, - cancel_listener: Option, ui: &'static UI) where UI: UIProvider + 'static, { @@ -171,7 +168,7 @@ impl FileManager { }) } FileManagerThreadMsg::ReadFile(sender, id, check_url_validity, origin) => { - self.read_file(sender, id, check_url_validity, origin, cancel_listener); + self.read_file(sender, id, check_url_validity, origin); } FileManagerThreadMsg::PromoteMemory(blob_buf, set_valid, sender, origin) => { self.promote_memory(blob_buf, set_valid, sender, origin); @@ -393,8 +390,7 @@ impl FileManagerStore { fn get_blob_buf(&self, sender: &IpcSender>, id: &Uuid, origin_in: &FileOrigin, rel_pos: RelativePos, - check_url_validity: bool, - cancel_listener: Option) -> Result<(), BlobURLStoreError> { + check_url_validity: bool) -> Result<(), BlobURLStoreError> { let file_impl = try!(self.get_impl(id, origin_in, check_url_validity)); match file_impl { FileImpl::Memory(buf) => { @@ -437,7 +433,7 @@ impl FileManagerStore { }; chunked_read(sender, &mut file, range.len(), opt_filename, - type_string, cancel_listener); + type_string); Ok(()) } else { Err(BlobURLStoreError::InvalidEntry) @@ -447,17 +443,16 @@ impl FileManagerStore { // Next time we don't need to check validity since // we have already done that for requesting URL if necessary self.get_blob_buf(sender, &parent_id, origin_in, - rel_pos.slice_inner(&inner_rel_pos), false, - cancel_listener) + rel_pos.slice_inner(&inner_rel_pos), false) } } } // Convenient wrapper over get_blob_buf fn try_read_file(&self, sender: &IpcSender>, - id: Uuid, check_url_validity: bool, origin_in: FileOrigin, - cancel_listener: Option) -> Result<(), BlobURLStoreError> { - self.get_blob_buf(sender, &id, &origin_in, RelativePos::full_range(), check_url_validity, cancel_listener) + id: Uuid, check_url_validity: bool, origin_in: FileOrigin) + -> Result<(), BlobURLStoreError> { + self.get_blob_buf(sender, &id, &origin_in, RelativePos::full_range(), check_url_validity) } fn dec_ref(&self, id: &Uuid, origin_in: &FileOrigin) -> Result<(), BlobURLStoreError> { @@ -569,7 +564,7 @@ const CHUNK_SIZE: usize = 8192; fn chunked_read(sender: &IpcSender>, file: &mut File, size: usize, opt_filename: Option, - type_string: String, cancel_listener: Option) { + type_string: String) { // First chunk let mut buf = vec![0; CHUNK_SIZE]; match file.read(&mut buf) { @@ -591,12 +586,6 @@ fn chunked_read(sender: &IpcSender>, // Send the remaining chunks loop { - if let Some(ref listener) = cancel_listener.as_ref() { - if listener.is_cancelled() { - break; - } - } - let mut buf = vec![0; CHUNK_SIZE]; match file.read(&mut buf) { Ok(0) => { diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index ad62cf148b8..f626dfda87d 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -277,7 +277,7 @@ impl ResourceChannelManager { CoreResourceMsg::Synchronize(sender) => { let _ = sender.send(()); } - CoreResourceMsg::ToFileManager(msg) => self.resource_manager.filemanager.handle(msg, None, TFD_PROVIDER), + CoreResourceMsg::ToFileManager(msg) => self.resource_manager.filemanager.handle(msg, TFD_PROVIDER), CoreResourceMsg::Exit(sender) => { if let Some(ref config_dir) = self.config_dir { match group.auth_cache.read() { diff --git a/tests/unit/net/filemanager_thread.rs b/tests/unit/net/filemanager_thread.rs index fbbe4aa4ca4..1ca283f7145 100644 --- a/tests/unit/net/filemanager_thread.rs +++ b/tests/unit/net/filemanager_thread.rs @@ -42,7 +42,7 @@ fn test_filemanager() { // Try to select a dummy file "tests/unit/net/test.jpeg" let (tx, rx) = ipc::channel().unwrap(); filemanager.handle(FileManagerThreadMsg::SelectFile(patterns.clone(), tx, origin.clone(), None), - None, TEST_PROVIDER); + TEST_PROVIDER); let selected = rx.recv().expect("Broken channel") .expect("The file manager failed to find test.jpeg"); @@ -54,7 +54,7 @@ fn test_filemanager() { { let (tx2, rx2) = ipc::channel().unwrap(); filemanager.handle(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone()), - None, TEST_PROVIDER); + TEST_PROVIDER); let msg = rx2.recv().expect("Broken channel"); @@ -85,7 +85,7 @@ fn test_filemanager() { { let (tx2, rx2) = ipc::channel().unwrap(); filemanager.handle(FileManagerThreadMsg::DecRef(selected.id.clone(), origin.clone(), tx2), - None, TEST_PROVIDER); + TEST_PROVIDER); let ret = rx2.recv().expect("Broken channel"); assert!(ret.is_ok(), "DecRef is not okay"); @@ -95,7 +95,7 @@ fn test_filemanager() { { let (tx2, rx2) = ipc::channel().unwrap(); filemanager.handle(FileManagerThreadMsg::ReadFile(tx2, selected.id.clone(), false, origin.clone()), - None, TEST_PROVIDER); + TEST_PROVIDER); let msg = rx2.recv().expect("Broken channel"); From 69f856486a12ec8870946b7398ac33e1932851f7 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 22 Nov 2016 10:19:02 +0100 Subject: [PATCH 8/9] Remove unused CancellableResource and CancellationListener types. --- components/net/resource_thread.rs | 66 +------------------------------ 1 file changed, 1 insertion(+), 65 deletions(-) diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index f626dfda87d..83a2e4cb063 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -32,7 +32,6 @@ use rustc_serialize::{Decodable, Encodable}; use rustc_serialize::json; use servo_url::ServoUrl; use std::borrow::{Cow, ToOwned}; -use std::cell::Cell; use std::collections::HashMap; use std::error::Error; use std::fs::File; @@ -41,7 +40,7 @@ use std::ops::Deref; use std::path::{Path, PathBuf}; use std::rc::Rc; use std::sync::{Arc, RwLock}; -use std::sync::mpsc::{Receiver, Sender}; +use std::sync::mpsc::Sender; use storage_thread::StorageThreadFactory; use util::prefs::PREFS; use util::thread::spawn_named; @@ -357,69 +356,6 @@ pub fn write_json_to_file(data: &T, config_dir: &Path, filename: &str) } } -/// The optional resources required by the `CancellationListener` -pub struct CancellableResource { - /// The receiver which receives a message on load cancellation - cancel_receiver: Receiver<()>, - /// The `CancellationListener` is unique to this `ResourceId` - resource_id: ResourceId, - /// If we haven't initiated any cancel requests, then the loaders ask - /// the listener to remove the `ResourceId` in the `HashMap` of - /// `CoreResourceManager` once they finish loading - resource_thread: CoreResourceThread, -} - -impl CancellableResource { - pub fn new(receiver: Receiver<()>, res_id: ResourceId, res_thread: CoreResourceThread) -> CancellableResource { - CancellableResource { - cancel_receiver: receiver, - resource_id: res_id, - resource_thread: res_thread, - } - } -} - -/// A listener which is basically a wrapped optional receiver which looks -/// for the load cancellation message. Some of the loading processes always keep -/// an eye out for this message and stop loading stuff once they receive it. -pub struct CancellationListener { - /// We'll be needing the resources only if we plan to cancel it - cancel_resource: Option, - /// This lets us know whether the request has already been cancelled - cancel_status: Cell, -} - -impl CancellationListener { - pub fn new(resources: Option) -> CancellationListener { - CancellationListener { - cancel_resource: resources, - cancel_status: Cell::new(false), - } - } - - pub fn is_cancelled(&self) -> bool { - let resource = match self.cancel_resource { - Some(ref resource) => resource, - None => return false, // channel doesn't exist! - }; - if resource.cancel_receiver.try_recv().is_ok() { - self.cancel_status.set(true); - true - } else { - self.cancel_status.get() - } - } -} - -impl Drop for CancellationListener { - fn drop(&mut self) { - if let Some(ref resource) = self.cancel_resource { - // Ensure that the resource manager stops tracking this request now that it's terminated. - let _ = resource.resource_thread.send(CoreResourceMsg::Cancel(resource.resource_id)); - } - } -} - #[derive(RustcDecodable, RustcEncodable, Clone)] pub struct AuthCacheEntry { pub user_name: String, From 761524c01b1eabdc004c27d78aaa2f1c297a1049 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 3 Nov 2016 09:28:05 +0100 Subject: [PATCH 9/9] Remove some unused arguments. The change to the unit test is necessary because the resource thread is not resilient against either of these Senders being dropped while the resource thread is running. Before this change, it held clones of those senders itself (public_setup_chan_clone, private_setup_chan_clone). --- components/net/resource_thread.rs | 19 ++++++------------- tests/unit/net/resource_thread.rs | 2 +- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/components/net/resource_thread.rs b/components/net/resource_thread.rs index 83a2e4cb063..24feb34dd9c 100644 --- a/components/net/resource_thread.rs +++ b/components/net/resource_thread.rs @@ -161,8 +161,6 @@ pub fn new_core_resource_thread(user_agent: Cow<'static, str>, -> (CoreResourceThread, CoreResourceThread) { let (public_setup_chan, public_setup_port) = ipc::channel().unwrap(); let (private_setup_chan, private_setup_port) = ipc::channel().unwrap(); - let public_setup_chan_clone = public_setup_chan.clone(); - let private_setup_chan_clone = private_setup_chan.clone(); spawn_named("ResourceManager".to_owned(), move || { let resource_manager = CoreResourceManager::new( user_agent, devtools_chan, profiler_chan @@ -172,9 +170,7 @@ pub fn new_core_resource_thread(user_agent: Cow<'static, str>, resource_manager: resource_manager, config_dir: config_dir, }; - channel_manager.start(public_setup_chan_clone, - private_setup_chan_clone, - public_setup_port, + channel_manager.start(public_setup_port, private_setup_port); }); (public_setup_chan, private_setup_chan) @@ -213,8 +209,6 @@ fn create_resource_groups(config_dir: Option<&Path>) impl ResourceChannelManager { #[allow(unsafe_code)] fn start(&mut self, - public_control_sender: CoreResourceThread, - private_control_sender: CoreResourceThread, public_receiver: IpcReceiver, private_receiver: IpcReceiver) { let (public_resource_group, private_resource_group) = @@ -226,14 +220,14 @@ impl ResourceChannelManager { loop { for (id, data) in rx_set.select().unwrap().into_iter().map(|m| m.unwrap()) { - let (group, sender) = if id == private_id { - (&private_resource_group, &private_control_sender) + let group = if id == private_id { + &private_resource_group } else { assert_eq!(id, public_id); - (&public_resource_group, &public_control_sender) + &public_resource_group }; if let Ok(msg) = data.to() { - if !self.process_msg(msg, group, &sender) { + if !self.process_msg(msg, group) { return; } } @@ -244,8 +238,7 @@ impl ResourceChannelManager { /// Returns false if the thread should exit. fn process_msg(&mut self, msg: CoreResourceMsg, - group: &ResourceGroup, - _control_sender: &CoreResourceThread) -> bool { + group: &ResourceGroup) -> bool { match msg { CoreResourceMsg::Fetch(init, sender) => self.resource_manager.fetch(init, sender, group), diff --git a/tests/unit/net/resource_thread.rs b/tests/unit/net/resource_thread.rs index ac651f99b5a..0e3f01bb54c 100644 --- a/tests/unit/net/resource_thread.rs +++ b/tests/unit/net/resource_thread.rs @@ -20,7 +20,7 @@ fn ip(s: &str) -> IpAddr { fn test_exit() { let (tx, _rx) = ipc::channel().unwrap(); let (sender, receiver) = ipc::channel().unwrap(); - let (resource_thread, _) = new_core_resource_thread( + let (resource_thread, _private_resource_thread) = new_core_resource_thread( "".into(), None, ProfilerChan(tx), None); resource_thread.send(CoreResourceMsg::Exit(sender)).unwrap(); receiver.recv().unwrap();