mirror of
https://github.com/servo/servo.git
synced 2025-07-26 00:30:22 +01:00
delegate resource reading to embedder
This commit is contained in:
parent
21517504cb
commit
9fb5795f37
52 changed files with 472 additions and 396 deletions
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -193,10 +193,10 @@ dependencies = [
|
||||||
name = "bluetooth_traits"
|
name = "bluetooth_traits"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"servo_config 0.0.1",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -452,6 +452,7 @@ dependencies = [
|
||||||
"compositing 0.0.1",
|
"compositing 0.0.1",
|
||||||
"debugger 0.0.1",
|
"debugger 0.0.1",
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gaol 0.0.1 (git+https://github.com/servo/gaol)",
|
"gaol 0.0.1 (git+https://github.com/servo/gaol)",
|
||||||
"gfx 0.0.1",
|
"gfx 0.0.1",
|
||||||
|
@ -782,6 +783,13 @@ name = "either"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embedder_traits"
|
||||||
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
@ -1453,6 +1461,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gfx 0.0.1",
|
"gfx 0.0.1",
|
||||||
|
@ -1563,6 +1572,7 @@ dependencies = [
|
||||||
"debugger 0.0.1",
|
"debugger 0.0.1",
|
||||||
"devtools 0.0.1",
|
"devtools 0.0.1",
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gaol 0.0.1 (git+https://github.com/servo/gaol)",
|
"gaol 0.0.1 (git+https://github.com/servo/gaol)",
|
||||||
|
@ -1882,6 +1892,7 @@ dependencies = [
|
||||||
"brotli 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"brotli 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper-openssl 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper-openssl 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1932,6 +1943,7 @@ name = "net_traits"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"hyper_serde 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"image 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"image 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2510,6 +2522,7 @@ dependencies = [
|
||||||
"devtools_traits 0.0.1",
|
"devtools_traits 0.0.1",
|
||||||
"dom_struct 0.0.1",
|
"dom_struct 0.0.1",
|
||||||
"domobject_derive 0.0.1",
|
"domobject_derive 0.0.1",
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2736,6 +2749,7 @@ dependencies = [
|
||||||
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"gleam 0.4.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
"gleam 0.4.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"glutin 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glutin 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libservo 0.0.1",
|
"libservo 0.0.1",
|
||||||
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"osmesa-src 17.3.1-devel (git+https://github.com/servo/osmesa-src)",
|
"osmesa-src 17.3.1-devel (git+https://github.com/servo/osmesa-src)",
|
||||||
|
@ -2852,6 +2866,7 @@ name = "servo_config"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"android_injected_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"android_injected_glue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3078,6 +3093,7 @@ dependencies = [
|
||||||
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.23.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"embedder_traits 0.0.1",
|
||||||
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.17.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever 0.22.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -13,4 +13,4 @@ path = "lib.rs"
|
||||||
ipc-channel = "0.10"
|
ipc-channel = "0.10"
|
||||||
regex = "0.2"
|
regex = "0.2"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
servo_config = {path = "../config"}
|
embedder_traits = { path = "../embedder_traits" }
|
||||||
|
|
|
@ -2,15 +2,12 @@
|
||||||
* 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 embedder_traits::resources::{self, Resource};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use servo_config::resource_files::read_resource_file;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::BufRead;
|
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
|
|
||||||
const BLOCKLIST_FILE: &'static str = "gatt_blocklist.txt";
|
|
||||||
const BLOCKLIST_FILE_NOT_FOUND: &'static str = "Could not find gatt_blocklist.txt file";
|
|
||||||
const EXCLUDE_READS: &'static str = "exclude-reads";
|
const EXCLUDE_READS: &'static str = "exclude-reads";
|
||||||
const EXCLUDE_WRITES: &'static str = "exclude-writes";
|
const EXCLUDE_WRITES: &'static str = "exclude-writes";
|
||||||
const VALID_UUID_REGEX: &'static str = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
const VALID_UUID_REGEX: &'static str = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}";
|
||||||
|
@ -75,15 +72,11 @@ impl BluetoothBlocklist {
|
||||||
fn parse_blocklist() -> Option<HashMap<String, Blocklist>> {
|
fn parse_blocklist() -> Option<HashMap<String, Blocklist>> {
|
||||||
// Step 1 missing, currently we parse ./resources/gatt_blocklist.txt.
|
// Step 1 missing, currently we parse ./resources/gatt_blocklist.txt.
|
||||||
let valid_uuid_regex = Regex::new(VALID_UUID_REGEX).unwrap();
|
let valid_uuid_regex = Regex::new(VALID_UUID_REGEX).unwrap();
|
||||||
let content = read_resource_file(BLOCKLIST_FILE).expect(BLOCKLIST_FILE_NOT_FOUND);
|
let content = resources::read_string(Resource::BluetoothBlocklist);
|
||||||
// Step 3
|
// Step 3
|
||||||
let mut result = HashMap::new();
|
let mut result = HashMap::new();
|
||||||
// Step 2 and 4
|
// Step 2 and 4
|
||||||
for line in content.lines() {
|
for line in content.lines() {
|
||||||
let line = match line {
|
|
||||||
Ok(l) => l,
|
|
||||||
Err(_) => return None,
|
|
||||||
};
|
|
||||||
// Step 4.1
|
// Step 4.1
|
||||||
if line.is_empty() || line.starts_with('#') {
|
if line.is_empty() || line.starts_with('#') {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
* 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/. */
|
||||||
|
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate ipc_channel;
|
extern crate ipc_channel;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
#[macro_use] extern crate serde;
|
#[macro_use] extern crate serde;
|
||||||
extern crate servo_config;
|
|
||||||
|
|
||||||
pub mod blocklist;
|
pub mod blocklist;
|
||||||
pub mod scanfilter;
|
pub mod scanfilter;
|
||||||
|
|
|
@ -13,6 +13,7 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
euclid = "0.17"
|
euclid = "0.17"
|
||||||
|
embedder_traits = { path = "../embedder_traits" }
|
||||||
getopts = "0.2.11"
|
getopts = "0.2.11"
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
extern crate android_injected_glue;
|
extern crate android_injected_glue;
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
#[macro_use] extern crate lazy_static;
|
#[macro_use] extern crate lazy_static;
|
||||||
|
@ -22,7 +23,6 @@ extern crate xdg;
|
||||||
pub mod basedir;
|
pub mod basedir;
|
||||||
#[allow(unsafe_code)] pub mod opts;
|
#[allow(unsafe_code)] pub mod opts;
|
||||||
pub mod prefs;
|
pub mod prefs;
|
||||||
pub mod resource_files;
|
|
||||||
|
|
||||||
pub fn servo_version() -> String {
|
pub fn servo_version() -> String {
|
||||||
let cargo_version = env!("CARGO_PKG_VERSION");
|
let cargo_version = env!("CARGO_PKG_VERSION");
|
||||||
|
|
|
@ -9,7 +9,6 @@ use euclid::TypedSize2D;
|
||||||
use getopts::Options;
|
use getopts::Options;
|
||||||
use num_cpus;
|
use num_cpus;
|
||||||
use prefs::{self, PrefValue, PREFS};
|
use prefs::{self, PrefValue, PREFS};
|
||||||
use resource_files::set_resources_path;
|
|
||||||
use servo_geometry::DeviceIndependentPixel;
|
use servo_geometry::DeviceIndependentPixel;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -196,6 +195,9 @@ pub struct Opts {
|
||||||
/// True if webrender is allowed to batch draw calls as instances.
|
/// True if webrender is allowed to batch draw calls as instances.
|
||||||
pub webrender_batch: bool,
|
pub webrender_batch: bool,
|
||||||
|
|
||||||
|
/// Load shaders from disk.
|
||||||
|
pub shaders_dir: Option<PathBuf>,
|
||||||
|
|
||||||
/// True to compile all webrender shaders at init time. This is mostly
|
/// True to compile all webrender shaders at init time. This is mostly
|
||||||
/// useful when modifying the shaders, to ensure they all compile
|
/// useful when modifying the shaders, to ensure they all compile
|
||||||
/// after each change is made.
|
/// after each change is made.
|
||||||
|
@ -544,6 +546,7 @@ pub fn default_opts() -> Opts {
|
||||||
is_printing_version: false,
|
is_printing_version: false,
|
||||||
webrender_record: false,
|
webrender_record: false,
|
||||||
webrender_batch: true,
|
webrender_batch: true,
|
||||||
|
shaders_dir: None,
|
||||||
precache_shaders: false,
|
precache_shaders: false,
|
||||||
signpost: false,
|
signpost: false,
|
||||||
certificate_path: None,
|
certificate_path: None,
|
||||||
|
@ -575,6 +578,8 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
|
||||||
"Uses userscripts in resources/user-agent-js, or a specified full path", "");
|
"Uses userscripts in resources/user-agent-js, or a specified full path", "");
|
||||||
opts.optmulti("", "user-stylesheet",
|
opts.optmulti("", "user-stylesheet",
|
||||||
"A user stylesheet to be added to every document", "file.css");
|
"A user stylesheet to be added to every document", "file.css");
|
||||||
|
opts.optopt("", "shaders",
|
||||||
|
"Shaders will be loaded from the specified directory instead of using the builtin ones.", "");
|
||||||
opts.optflag("z", "headless", "Headless mode");
|
opts.optflag("z", "headless", "Headless mode");
|
||||||
opts.optflag("f", "hard-fail", "Exit on thread failure instead of displaying about:failure");
|
opts.optflag("f", "hard-fail", "Exit on thread failure instead of displaying about:failure");
|
||||||
opts.optflag("F", "soft-fail", "Display about:failure on thread failure instead of exiting");
|
opts.optflag("F", "soft-fail", "Display about:failure on thread failure instead of exiting");
|
||||||
|
@ -619,8 +624,6 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
|
||||||
Err(f) => args_fail(&f.to_string()),
|
Err(f) => args_fail(&f.to_string()),
|
||||||
};
|
};
|
||||||
|
|
||||||
set_resources_path(opt_match.opt_str("resources-path"));
|
|
||||||
|
|
||||||
if opt_match.opt_present("h") || opt_match.opt_present("help") {
|
if opt_match.opt_present("h") || opt_match.opt_present("help") {
|
||||||
print_usage(app_name, &opts);
|
print_usage(app_name, &opts);
|
||||||
process::exit(0);
|
process::exit(0);
|
||||||
|
@ -844,6 +847,7 @@ pub fn from_cmdline_args(args: &[String]) -> ArgumentParsingResult {
|
||||||
is_printing_version: is_printing_version,
|
is_printing_version: is_printing_version,
|
||||||
webrender_record: debug_options.webrender_record,
|
webrender_record: debug_options.webrender_record,
|
||||||
webrender_batch: !debug_options.webrender_disable_batch,
|
webrender_batch: !debug_options.webrender_disable_batch,
|
||||||
|
shaders_dir: opt_match.opt_str("shaders").map(Into::into),
|
||||||
precache_shaders: debug_options.precache_shaders,
|
precache_shaders: debug_options.precache_shaders,
|
||||||
signpost: debug_options.signpost,
|
signpost: debug_options.signpost,
|
||||||
certificate_path: opt_match.opt_str("certificate-path"),
|
certificate_path: opt_match.opt_str("certificate-path"),
|
||||||
|
|
|
@ -3,9 +3,9 @@
|
||||||
* 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 basedir::default_config_dir;
|
use basedir::default_config_dir;
|
||||||
|
use embedder_traits::resources::{self, Resource};
|
||||||
use num_cpus;
|
use num_cpus;
|
||||||
use opts;
|
use opts;
|
||||||
use resource_files::resources_dir_path;
|
|
||||||
use rustc_serialize::json::{Json, ToJson};
|
use rustc_serialize::json::{Json, ToJson};
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
|
@ -18,7 +18,7 @@ use std::sync::{Arc, RwLock};
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref PREFS: Preferences = {
|
pub static ref PREFS: Preferences = {
|
||||||
let defaults = default_prefs();
|
let defaults = default_prefs();
|
||||||
if let Ok(prefs) = read_prefs() {
|
if let Ok(prefs) = read_prefs(&resources::read_string(Resource::Preferences)) {
|
||||||
defaults.extend(prefs);
|
defaults.extend(prefs);
|
||||||
}
|
}
|
||||||
defaults
|
defaults
|
||||||
|
@ -156,9 +156,8 @@ pub fn default_prefs() -> Preferences {
|
||||||
prefs
|
prefs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_prefs_from_file<T>(mut file: T)
|
pub fn read_prefs(txt: &str) -> Result<HashMap<String, Pref>, ()> {
|
||||||
-> Result<HashMap<String, Pref>, ()> where T: Read {
|
let json = Json::from_str(txt).or_else(|e| {
|
||||||
let json = Json::from_reader(&mut file).or_else(|e| {
|
|
||||||
println!("Ignoring invalid JSON in preferences: {:?}.", e);
|
println!("Ignoring invalid JSON in preferences: {:?}.", e);
|
||||||
Err(())
|
Err(())
|
||||||
})?;
|
})?;
|
||||||
|
@ -194,8 +193,10 @@ pub fn add_user_prefs() {
|
||||||
|
|
||||||
fn init_user_prefs(path: &mut PathBuf) {
|
fn init_user_prefs(path: &mut PathBuf) {
|
||||||
path.push("prefs.json");
|
path.push("prefs.json");
|
||||||
if let Ok(file) = File::open(path) {
|
if let Ok(mut file) = File::open(path) {
|
||||||
if let Ok(prefs) = read_prefs_from_file(file) {
|
let mut txt = String::new();
|
||||||
|
file.read_to_string(&mut txt).expect("Can't read use prefs");
|
||||||
|
if let Ok(prefs) = read_prefs(&txt) {
|
||||||
PREFS.extend(prefs);
|
PREFS.extend(prefs);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -204,19 +205,6 @@ fn init_user_prefs(path: &mut PathBuf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_prefs() -> Result<HashMap<String, Pref>, ()> {
|
|
||||||
let mut path = resources_dir_path().map_err(|_| ())?;
|
|
||||||
path.push("prefs.json");
|
|
||||||
|
|
||||||
let file = File::open(path).or_else(|e| {
|
|
||||||
writeln!(&mut stderr(), "Error opening preferences: {:?}.", e)
|
|
||||||
.expect("failed printing to stderr");
|
|
||||||
Err(())
|
|
||||||
})?;
|
|
||||||
|
|
||||||
read_prefs_from_file(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Preferences(Arc<RwLock<HashMap<String, Pref>>>);
|
pub struct Preferences(Arc<RwLock<HashMap<String, Pref>>>);
|
||||||
|
|
||||||
impl Preferences {
|
impl Preferences {
|
||||||
|
|
|
@ -1,83 +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/. */
|
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
use android_injected_glue;
|
|
||||||
#[cfg(not(target_os = "android"))]
|
|
||||||
use std::env;
|
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
use std::ffi::CStr;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::{self, Read};
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
static ref CMD_RESOURCE_DIR: Arc<Mutex<Option<String>>> = {
|
|
||||||
Arc::new(Mutex::new(None))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_resources_path(path: Option<String>) {
|
|
||||||
let mut dir = CMD_RESOURCE_DIR.lock().unwrap();
|
|
||||||
*dir = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
pub fn resources_dir_path() -> io::Result<PathBuf> {
|
|
||||||
let mut dir = CMD_RESOURCE_DIR.lock().unwrap();
|
|
||||||
|
|
||||||
if let Some(ref path) = *dir {
|
|
||||||
return Ok(PathBuf::from(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
let data_path = unsafe {
|
|
||||||
CStr::from_ptr((*android_injected_glue::get_app().activity).externalDataPath)
|
|
||||||
};
|
|
||||||
let path = PathBuf::from(data_path.to_str().unwrap());
|
|
||||||
*dir = Some(path.to_str().unwrap().to_owned());
|
|
||||||
Ok(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
|
||||||
pub fn resources_dir_path() -> io::Result<PathBuf> {
|
|
||||||
let mut dir = CMD_RESOURCE_DIR.lock().unwrap();
|
|
||||||
|
|
||||||
if let Some(ref path) = *dir {
|
|
||||||
return Ok(PathBuf::from(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Find a way to not rely on the executable being
|
|
||||||
// under `<servo source>[/$target_triple]/target/debug`
|
|
||||||
// or `<servo source>[/$target_triple]/target/release`.
|
|
||||||
let mut path = env::current_exe()?;
|
|
||||||
// Follow symlink
|
|
||||||
path = path.canonicalize()?;
|
|
||||||
|
|
||||||
while path.pop() {
|
|
||||||
path.push("resources");
|
|
||||||
if path.is_dir() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
path.pop();
|
|
||||||
// Check for Resources on mac when using a case sensitive filesystem.
|
|
||||||
path.push("Resources");
|
|
||||||
if path.is_dir() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
path.pop();
|
|
||||||
}
|
|
||||||
*dir = Some(path.to_str().unwrap().to_owned());
|
|
||||||
Ok(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_resource_file<P: AsRef<Path>>(relative_path: P) -> io::Result<Vec<u8>> {
|
|
||||||
let mut path = resources_dir_path()?;
|
|
||||||
path.push(relative_path);
|
|
||||||
let mut file = File::open(&path)?;
|
|
||||||
let mut data = Vec::new();
|
|
||||||
file.read_to_end(&mut data)?;
|
|
||||||
Ok(data)
|
|
||||||
}
|
|
|
@ -2,8 +2,10 @@
|
||||||
* 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/. */
|
||||||
|
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate servo_config;
|
extern crate servo_config;
|
||||||
|
|
||||||
|
use embedder_traits::resources::register_resources_for_tests;
|
||||||
use servo_config::opts::{parse_url_or_filename, parse_pref_from_command_line};
|
use servo_config::opts::{parse_url_or_filename, parse_pref_from_command_line};
|
||||||
use servo_config::prefs::{PrefValue, PREFS};
|
use servo_config::prefs::{PrefValue, PREFS};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
@ -73,6 +75,7 @@ fn test_argument_parsing_special() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_pref_from_command_line() {
|
fn test_parse_pref_from_command_line() {
|
||||||
|
register_resources_for_tests();
|
||||||
// Test with boolean values.
|
// Test with boolean values.
|
||||||
parse_pref_from_command_line("testtrue=true");
|
parse_pref_from_command_line("testtrue=true");
|
||||||
assert_eq!(*PREFS.get("testtrue"), PrefValue::Boolean(true));
|
assert_eq!(*PREFS.get("testtrue"), PrefValue::Boolean(true));
|
||||||
|
|
|
@ -2,10 +2,12 @@
|
||||||
* 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/. */
|
||||||
|
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate servo_config;
|
extern crate servo_config;
|
||||||
|
|
||||||
|
use embedder_traits::resources::register_resources_for_tests;
|
||||||
use servo_config::basedir;
|
use servo_config::basedir;
|
||||||
use servo_config::prefs::{PREFS, PrefValue, read_prefs_from_file};
|
use servo_config::prefs::{PREFS, PrefValue, read_prefs};
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
@ -17,7 +19,7 @@ fn test_create_pref() {
|
||||||
\"shell.homepage\": \"https://servo.org\"\
|
\"shell.homepage\": \"https://servo.org\"\
|
||||||
}";
|
}";
|
||||||
|
|
||||||
let prefs = read_prefs_from_file(json_str.as_bytes());
|
let prefs = read_prefs(json_str);
|
||||||
assert!(prefs.is_ok());
|
assert!(prefs.is_ok());
|
||||||
let prefs = prefs.unwrap();
|
let prefs = prefs.unwrap();
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ fn test_create_pref() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_get_set_reset_extend() {
|
fn test_get_set_reset_extend() {
|
||||||
|
register_resources_for_tests();
|
||||||
let json_str = "{\
|
let json_str = "{\
|
||||||
\"layout.writing-mode.enabled\": true,\
|
\"layout.writing-mode.enabled\": true,\
|
||||||
\"extra.stuff\": false,\
|
\"extra.stuff\": false,\
|
||||||
|
@ -41,7 +44,7 @@ fn test_get_set_reset_extend() {
|
||||||
PREFS.reset("shell.homepage");
|
PREFS.reset("shell.homepage");
|
||||||
assert_eq!(*PREFS.get("shell.homepage"), PrefValue::String("https://servo.org".to_owned()));
|
assert_eq!(*PREFS.get("shell.homepage"), PrefValue::String("https://servo.org".to_owned()));
|
||||||
|
|
||||||
let extension = read_prefs_from_file(json_str.as_bytes()).unwrap();
|
let extension = read_prefs(json_str).unwrap();
|
||||||
PREFS.extend(extension);
|
PREFS.extend(extension);
|
||||||
assert_eq!(*PREFS.get("shell.homepage"), PrefValue::String("https://google.com".to_owned()));
|
assert_eq!(*PREFS.get("shell.homepage"), PrefValue::String("https://google.com".to_owned()));
|
||||||
assert_eq!(*PREFS.get("layout.writing-mode.enabled"), PrefValue::Boolean(true));
|
assert_eq!(*PREFS.get("layout.writing-mode.enabled"), PrefValue::Boolean(true));
|
||||||
|
|
|
@ -19,6 +19,7 @@ compositing = {path = "../compositing"}
|
||||||
debugger = {path = "../debugger"}
|
debugger = {path = "../debugger"}
|
||||||
devtools_traits = {path = "../devtools_traits"}
|
devtools_traits = {path = "../devtools_traits"}
|
||||||
euclid = "0.17"
|
euclid = "0.17"
|
||||||
|
embedder_traits = { path = "../embedder_traits" }
|
||||||
gfx = {path = "../gfx"}
|
gfx = {path = "../gfx"}
|
||||||
gfx_traits = {path = "../gfx_traits"}
|
gfx_traits = {path = "../gfx_traits"}
|
||||||
hyper = "0.10"
|
hyper = "0.10"
|
||||||
|
|
|
@ -14,6 +14,8 @@ extern crate clipboard;
|
||||||
extern crate compositing;
|
extern crate compositing;
|
||||||
extern crate debugger;
|
extern crate debugger;
|
||||||
extern crate devtools_traits;
|
extern crate devtools_traits;
|
||||||
|
#[cfg(all(not(target_os = "windows"), not(target_os = "ios")))]
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
#[cfg(all(not(target_os = "windows"), not(target_os = "ios")))]
|
#[cfg(all(not(target_os = "windows"), not(target_os = "ios")))]
|
||||||
extern crate gaol;
|
extern crate gaol;
|
||||||
|
|
|
@ -2,18 +2,17 @@
|
||||||
* 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 embedder_traits::resources;
|
||||||
use gaol::profile::{Operation, PathPattern, Profile};
|
use gaol::profile::{Operation, PathPattern, Profile};
|
||||||
use servo_config::resource_files;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/// Our content process sandbox profile on Mac. As restrictive as possible.
|
/// Our content process sandbox profile on Mac. As restrictive as possible.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
pub fn content_process_sandbox_profile() -> Profile {
|
pub fn content_process_sandbox_profile() -> Profile {
|
||||||
use gaol::platform;
|
use gaol::platform;
|
||||||
Profile::new(vec![
|
|
||||||
|
let mut operations = vec![
|
||||||
Operation::FileReadAll(PathPattern::Literal(PathBuf::from("/dev/urandom"))),
|
Operation::FileReadAll(PathPattern::Literal(PathBuf::from("/dev/urandom"))),
|
||||||
Operation::FileReadAll(PathPattern::Subpath(resource_files::resources_dir_path()
|
|
||||||
.expect("Cannot find resource dir"))),
|
|
||||||
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/Library/Fonts"))),
|
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/Library/Fonts"))),
|
||||||
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/System/Library/Fonts"))),
|
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/System/Library/Fonts"))),
|
||||||
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from(
|
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from(
|
||||||
|
@ -27,16 +26,32 @@ pub fn content_process_sandbox_profile() -> Profile {
|
||||||
Operation::SystemInfoRead,
|
Operation::SystemInfoRead,
|
||||||
Operation::PlatformSpecific(platform::macos::Operation::MachLookup(
|
Operation::PlatformSpecific(platform::macos::Operation::MachLookup(
|
||||||
b"com.apple.FontServer".to_vec())),
|
b"com.apple.FontServer".to_vec())),
|
||||||
]).expect("Failed to create sandbox profile!")
|
];
|
||||||
|
|
||||||
|
operations.extend(resources::sandbox_access_files().into_iter().map(|p| {
|
||||||
|
Operation::FileReadAll(PathPattern::Literal(p))
|
||||||
|
}));
|
||||||
|
operations.extend(resources::sandbox_access_files_dirs().into_iter().map(|p| {
|
||||||
|
Operation::FileReadAll(PathPattern::Subpath(p))
|
||||||
|
}));
|
||||||
|
|
||||||
|
Profile::new(operations).expect("Failed to create sandbox profile!")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Our content process sandbox profile on Linux. As restrictive as possible.
|
/// Our content process sandbox profile on Linux. As restrictive as possible.
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
pub fn content_process_sandbox_profile() -> Profile {
|
pub fn content_process_sandbox_profile() -> Profile {
|
||||||
Profile::new(vec![
|
let mut operations = vec![
|
||||||
Operation::FileReadAll(PathPattern::Literal(PathBuf::from("/dev/urandom"))),
|
Operation::FileReadAll(PathPattern::Literal(PathBuf::from("/dev/urandom"))),
|
||||||
Operation::FileReadAll(PathPattern::Subpath(resource_files::resources_dir_path()
|
];
|
||||||
.expect("Cannot find resource dir"))),
|
|
||||||
]).expect("Failed to create sandbox profile!")
|
operations.extend(resources::sandbox_access_files().into_iter().map(|p| {
|
||||||
|
Operation::FileReadAll(PathPattern::Literal(p))
|
||||||
|
}));
|
||||||
|
operations.extend(resources::sandbox_access_files_dirs().into_iter().map(|p| {
|
||||||
|
Operation::FileReadAll(PathPattern::Subpath(p))
|
||||||
|
}));
|
||||||
|
|
||||||
|
Profile::new(operations).expect("Failed to create sandbox profile!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
components/embedder_traits/Cargo.toml
Normal file
13
components/embedder_traits/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "embedder_traits"
|
||||||
|
version = "0.0.1"
|
||||||
|
authors = ["The Servo Project Developers"]
|
||||||
|
license = "MPL-2.0"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "embedder_traits"
|
||||||
|
path = "lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
lazy_static = "1"
|
7
components/embedder_traits/lib.rs
Normal file
7
components/embedder_traits/lib.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
#[macro_use] extern crate lazy_static;
|
||||||
|
|
||||||
|
pub mod resources;
|
97
components/embedder_traits/resources.rs
Normal file
97
components/embedder_traits/resources.rs
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
/* 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 std::env;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::sync::{Once, ONCE_INIT, RwLock};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref RES: RwLock<Option<Box<ResourceReaderMethods + Sync + Send>>> = RwLock::new(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(reader: Box<ResourceReaderMethods + Sync + Send>) {
|
||||||
|
*RES.write().unwrap() = Some(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_bytes(res: Resource) -> Vec<u8> {
|
||||||
|
RES.read().unwrap().as_ref().expect("Resource reader not set.").read(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_string(res: Resource) -> String {
|
||||||
|
String::from_utf8(read_bytes(res)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sandbox_access_files() -> Vec<PathBuf> {
|
||||||
|
RES.read().unwrap().as_ref().expect("Resource reader not set.").sandbox_access_files()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sandbox_access_files_dirs() -> Vec<PathBuf> {
|
||||||
|
RES.read().unwrap().as_ref().expect("Resource reader not set.").sandbox_access_files_dirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Resource {
|
||||||
|
Preferences,
|
||||||
|
BluetoothBlocklist,
|
||||||
|
DomainList,
|
||||||
|
HstsPreloadList,
|
||||||
|
SSLCertificates,
|
||||||
|
BadCertHTML,
|
||||||
|
NetErrorHTML,
|
||||||
|
UserAgentCSS,
|
||||||
|
ServoCSS,
|
||||||
|
PresentationalHintsCSS,
|
||||||
|
QuirksModeCSS,
|
||||||
|
RippyPNG,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait ResourceReaderMethods {
|
||||||
|
fn read(&self, res: Resource) -> Vec<u8>;
|
||||||
|
fn sandbox_access_files(&self) -> Vec<PathBuf>;
|
||||||
|
fn sandbox_access_files_dirs(&self) -> Vec<PathBuf>;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INIT: Once = ONCE_INIT;
|
||||||
|
|
||||||
|
pub fn register_resources_for_tests() {
|
||||||
|
INIT.call_once(|| {
|
||||||
|
struct ResourceReader;
|
||||||
|
impl ResourceReaderMethods for ResourceReader {
|
||||||
|
fn sandbox_access_files(&self) -> Vec<PathBuf> { vec![] }
|
||||||
|
fn sandbox_access_files_dirs(&self) -> Vec<PathBuf> { vec![] }
|
||||||
|
fn read(&self, file: Resource) -> Vec<u8> {
|
||||||
|
let file = match file {
|
||||||
|
Resource::Preferences => "prefs.json",
|
||||||
|
Resource::BluetoothBlocklist => "gatt_blocklist.txt",
|
||||||
|
Resource::DomainList => "public_domains.txt",
|
||||||
|
Resource::HstsPreloadList => "hsts_preload.json",
|
||||||
|
Resource::SSLCertificates => "certs",
|
||||||
|
Resource::BadCertHTML => "badcert.html",
|
||||||
|
Resource::NetErrorHTML => "neterror.html",
|
||||||
|
Resource::UserAgentCSS => "user-agent.css",
|
||||||
|
Resource::ServoCSS => "servo.css",
|
||||||
|
Resource::PresentationalHintsCSS => "presentational-hints.css",
|
||||||
|
Resource::QuirksModeCSS => "quirks-mode.css",
|
||||||
|
Resource::RippyPNG => "rippy.png",
|
||||||
|
};
|
||||||
|
let mut path = env::current_exe().unwrap();
|
||||||
|
path = path.canonicalize().unwrap();
|
||||||
|
while path.pop() {
|
||||||
|
path.push("resources");
|
||||||
|
if path.is_dir() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
path.pop();
|
||||||
|
}
|
||||||
|
path.push(file);
|
||||||
|
let mut buffer = vec![];
|
||||||
|
File::open(path).expect(&format!("Can't find file: {}", file))
|
||||||
|
.read_to_end(&mut buffer).expect("Can't read file");
|
||||||
|
buffer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set(Box::new(ResourceReader));
|
||||||
|
});
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ unstable = ["parking_lot/nightly"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
app_units = "0.6"
|
app_units = "0.6"
|
||||||
atomic_refcell = "0.1"
|
atomic_refcell = "0.1"
|
||||||
|
embedder_traits = {path = "../embedder_traits"}
|
||||||
euclid = "0.17"
|
euclid = "0.17"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
gfx = {path = "../gfx"}
|
gfx = {path = "../gfx"}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
extern crate app_units;
|
extern crate app_units;
|
||||||
extern crate atomic_refcell;
|
extern crate atomic_refcell;
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
extern crate fnv;
|
extern crate fnv;
|
||||||
extern crate gfx;
|
extern crate gfx;
|
||||||
|
@ -55,6 +56,7 @@ mod dom_wrapper;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use dom_wrapper::{ServoLayoutElement, ServoLayoutDocument, ServoLayoutNode};
|
use dom_wrapper::{ServoLayoutElement, ServoLayoutDocument, ServoLayoutNode};
|
||||||
use dom_wrapper::drop_style_and_layout_data;
|
use dom_wrapper::drop_style_and_layout_data;
|
||||||
|
use embedder_traits::resources::{self, Resource};
|
||||||
use euclid::{Point2D, Rect, Size2D, TypedScale, TypedSize2D};
|
use euclid::{Point2D, Rect, Size2D, TypedScale, TypedSize2D};
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use gfx::display_list::{OpaqueNode, WebRenderImageInfo};
|
use gfx::display_list::{OpaqueNode, WebRenderImageInfo};
|
||||||
|
@ -110,7 +112,6 @@ use servo_arc::Arc as ServoArc;
|
||||||
use servo_atoms::Atom;
|
use servo_atoms::Atom;
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use servo_config::prefs::PREFS;
|
use servo_config::prefs::PREFS;
|
||||||
use servo_config::resource_files::read_resource_file;
|
|
||||||
use servo_geometry::MaxRect;
|
use servo_geometry::MaxRect;
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
@ -1740,11 +1741,11 @@ fn get_root_flow_background_color(flow: &mut Flow) -> webrender_api::ColorF {
|
||||||
fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
|
fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
|
||||||
fn parse_ua_stylesheet(
|
fn parse_ua_stylesheet(
|
||||||
shared_lock: &SharedRwLock,
|
shared_lock: &SharedRwLock,
|
||||||
filename: &'static str,
|
filename: &str,
|
||||||
|
content: &[u8],
|
||||||
) -> Result<DocumentStyleSheet, &'static str> {
|
) -> Result<DocumentStyleSheet, &'static str> {
|
||||||
let res = read_resource_file(filename).map_err(|_| filename)?;
|
|
||||||
Ok(DocumentStyleSheet(ServoArc::new(Stylesheet::from_bytes(
|
Ok(DocumentStyleSheet(ServoArc::new(Stylesheet::from_bytes(
|
||||||
&res,
|
content,
|
||||||
ServoUrl::parse(&format!("chrome://resources/{:?}", filename)).unwrap(),
|
ServoUrl::parse(&format!("chrome://resources/{:?}", filename)).unwrap(),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
@ -1758,12 +1759,17 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let shared_lock = SharedRwLock::new();
|
let shared_lock = SharedRwLock::new();
|
||||||
let mut user_or_user_agent_stylesheets = vec!();
|
|
||||||
// FIXME: presentational-hints.css should be at author origin with zero specificity.
|
// FIXME: presentational-hints.css should be at author origin with zero specificity.
|
||||||
// (Does it make a difference?)
|
// (Does it make a difference?)
|
||||||
for &filename in &["user-agent.css", "servo.css", "presentational-hints.css"] {
|
let mut user_or_user_agent_stylesheets = vec![
|
||||||
user_or_user_agent_stylesheets.push(parse_ua_stylesheet(&shared_lock, filename)?);
|
parse_ua_stylesheet(&shared_lock, "user-agent.css",
|
||||||
}
|
&resources::read_bytes(Resource::UserAgentCSS))?,
|
||||||
|
parse_ua_stylesheet(&shared_lock, "servo.css",
|
||||||
|
&resources::read_bytes(Resource::ServoCSS))?,
|
||||||
|
parse_ua_stylesheet(&shared_lock, "presentational-hints.css",
|
||||||
|
&resources::read_bytes(Resource::PresentationalHintsCSS))?,
|
||||||
|
];
|
||||||
|
|
||||||
for &(ref contents, ref url) in &opts::get().user_stylesheets {
|
for &(ref contents, ref url) in &opts::get().user_stylesheets {
|
||||||
user_or_user_agent_stylesheets.push(
|
user_or_user_agent_stylesheets.push(
|
||||||
DocumentStyleSheet(ServoArc::new(Stylesheet::from_bytes(
|
DocumentStyleSheet(ServoArc::new(Stylesheet::from_bytes(
|
||||||
|
@ -1781,7 +1787,8 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let quirks_mode_stylesheet = parse_ua_stylesheet(&shared_lock, "quirks-mode.css")?;
|
let quirks_mode_stylesheet = parse_ua_stylesheet(&shared_lock, "quirks-mode.css",
|
||||||
|
&resources::read_bytes(Resource::QuirksModeCSS))?;
|
||||||
|
|
||||||
Ok(UserAgentStylesheets {
|
Ok(UserAgentStylesheets {
|
||||||
shared_lock: shared_lock,
|
shared_lock: shared_lock,
|
||||||
|
|
|
@ -16,6 +16,7 @@ base64 = "0.6"
|
||||||
brotli = "1.0.6"
|
brotli = "1.0.6"
|
||||||
cookie = "0.10"
|
cookie = "0.10"
|
||||||
devtools_traits = {path = "../devtools_traits"}
|
devtools_traits = {path = "../devtools_traits"}
|
||||||
|
embedder_traits = { path = "../embedder_traits" }
|
||||||
flate2 = "1"
|
flate2 = "1"
|
||||||
hyper = "0.10"
|
hyper = "0.10"
|
||||||
hyper_serde = "0.8"
|
hyper_serde = "0.8"
|
||||||
|
|
|
@ -1,31 +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 servo_config::resource_files::resources_dir_path;
|
|
||||||
use servo_url::ServoUrl;
|
|
||||||
use std::fs::canonicalize;
|
|
||||||
use url::percent_encoding::percent_decode;
|
|
||||||
|
|
||||||
pub fn resolve_chrome_url(url: &ServoUrl) -> Result<ServoUrl, ()> {
|
|
||||||
assert_eq!(url.scheme(), "chrome");
|
|
||||||
if url.host_str() != Some("resources") {
|
|
||||||
return Err(())
|
|
||||||
}
|
|
||||||
let resources = canonicalize(resources_dir_path().expect("Error finding resource folder"))
|
|
||||||
.expect("Error canonicalizing path to the resources directory");
|
|
||||||
let mut path = resources.clone();
|
|
||||||
for segment in url.path_segments().unwrap() {
|
|
||||||
match percent_decode(segment.as_bytes()).decode_utf8() {
|
|
||||||
// Check ".." to prevent access to files outside of the resources directory.
|
|
||||||
Ok(segment) => path.push(&*segment),
|
|
||||||
_ => return Err(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match canonicalize(path) {
|
|
||||||
Ok(ref path) if path.starts_with(&resources) && path.exists() => {
|
|
||||||
Ok(ServoUrl::from_file_path(path).unwrap())
|
|
||||||
}
|
|
||||||
_ => Err(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -9,9 +9,9 @@ use hyper::net::{NetworkConnector, HttpsStream, HttpStream, SslClient};
|
||||||
use hyper_openssl::OpensslClient;
|
use hyper_openssl::OpensslClient;
|
||||||
use openssl::ssl::{SSL_OP_NO_COMPRESSION, SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3};
|
use openssl::ssl::{SSL_OP_NO_COMPRESSION, SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3};
|
||||||
use openssl::ssl::{SslConnectorBuilder, SslMethod};
|
use openssl::ssl::{SslConnectorBuilder, SslMethod};
|
||||||
|
use openssl::x509;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
pub struct HttpsConnector {
|
pub struct HttpsConnector {
|
||||||
ssl: OpensslClient,
|
ssl: OpensslClient,
|
||||||
|
@ -50,9 +50,33 @@ impl NetworkConnector for HttpsConnector {
|
||||||
|
|
||||||
pub type Connector = HttpsConnector;
|
pub type Connector = HttpsConnector;
|
||||||
|
|
||||||
pub fn create_ssl_client(ca_file: &PathBuf) -> OpensslClient {
|
pub fn create_ssl_client(certs: &str) -> OpensslClient {
|
||||||
|
// certs include multiple certificates. We could add all of them at once,
|
||||||
|
// but if any of them were already added, openssl would fail to insert all
|
||||||
|
// of them.
|
||||||
|
let mut certs = certs;
|
||||||
let mut ssl_connector_builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
|
let mut ssl_connector_builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
|
||||||
ssl_connector_builder.set_ca_file(ca_file).expect("could not set CA file");
|
loop {
|
||||||
|
let token = "-----END CERTIFICATE-----";
|
||||||
|
if let Some(index) = certs.find(token) {
|
||||||
|
let (cert, rest) = certs.split_at(index + token.len());
|
||||||
|
certs = rest;
|
||||||
|
let cert = x509::X509::from_pem(cert.as_bytes()).unwrap();
|
||||||
|
ssl_connector_builder.cert_store_mut().add_cert(cert).or_else(|e| {
|
||||||
|
let v: Option<Option<&str>> = e.errors().iter().nth(0).map(|e| e.reason());
|
||||||
|
if v == Some(Some("cert already in hash table")) {
|
||||||
|
warn!("Cert already in hash table. Ignoring.");
|
||||||
|
// Ignore error X509_R_CERT_ALREADY_IN_HASH_TABLE which means the
|
||||||
|
// certificate is already in the store.
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
}).expect("could not set CA file");
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
ssl_connector_builder.set_cipher_list(DEFAULT_CIPHERS).expect("could not set ciphers");
|
ssl_connector_builder.set_cipher_list(DEFAULT_CIPHERS).expect("could not set ciphers");
|
||||||
ssl_connector_builder.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3 | SSL_OP_NO_COMPRESSION);
|
ssl_connector_builder.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3 | SSL_OP_NO_COMPRESSION);
|
||||||
let ssl_connector = ssl_connector_builder.build();
|
let ssl_connector = ssl_connector_builder.build();
|
||||||
|
|
|
@ -2,14 +2,13 @@
|
||||||
* 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 embedder_traits::resources::{self, Resource};
|
||||||
use net_traits::IncludeSubdomains;
|
use net_traits::IncludeSubdomains;
|
||||||
use net_traits::pub_domains::reg_suffix;
|
use net_traits::pub_domains::reg_suffix;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use servo_config::resource_files::read_resource_file;
|
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::{Ipv4Addr, Ipv6Addr};
|
use std::net::{Ipv4Addr, Ipv6Addr};
|
||||||
use std::str::from_utf8;
|
|
||||||
use time;
|
use time;
|
||||||
|
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
|
@ -64,15 +63,13 @@ impl HstsList {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create an `HstsList` from the bytes of a JSON preload file.
|
/// Create an `HstsList` from the bytes of a JSON preload file.
|
||||||
pub fn from_preload(preload_content: &[u8]) -> Option<HstsList> {
|
pub fn from_preload(preload_content: &str) -> Option<HstsList> {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct HstsEntries {
|
struct HstsEntries {
|
||||||
entries: Vec<HstsEntry>,
|
entries: Vec<HstsEntry>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let hsts_entries: Option<HstsEntries> = from_utf8(&preload_content)
|
let hsts_entries: Option<HstsEntries> = serde_json::from_str(preload_content).ok();
|
||||||
.ok()
|
|
||||||
.and_then(|c| serde_json::from_str(c).ok());
|
|
||||||
|
|
||||||
hsts_entries.map_or(None, |hsts_entries| {
|
hsts_entries.map_or(None, |hsts_entries| {
|
||||||
let mut hsts_list: HstsList = HstsList::new();
|
let mut hsts_list: HstsList = HstsList::new();
|
||||||
|
@ -86,10 +83,8 @@ impl HstsList {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_servo_preload() -> HstsList {
|
pub fn from_servo_preload() -> HstsList {
|
||||||
let file_bytes = read_resource_file("hsts_preload.json")
|
let list = resources::read_string(Resource::HstsPreloadList);
|
||||||
.expect("Could not find Servo HSTS preload file");
|
HstsList::from_preload(&list).expect("Servo HSTS preload file is invalid")
|
||||||
HstsList::from_preload(&file_bytes)
|
|
||||||
.expect("Servo HSTS preload file is invalid")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_host_secure(&self, host: &str) -> bool {
|
pub fn is_host_secure(&self, host: &str) -> bool {
|
||||||
|
|
|
@ -2,20 +2,18 @@
|
||||||
* 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 embedder_traits::resources::{self, Resource};
|
||||||
use immeta::load_from_buf;
|
use immeta::load_from_buf;
|
||||||
use net_traits::{FetchMetadata, FetchResponseMsg, NetworkError};
|
use net_traits::{FetchMetadata, FetchResponseMsg, NetworkError};
|
||||||
use net_traits::image::base::{Image, ImageMetadata, PixelFormat, load_from_memory};
|
use net_traits::image::base::{Image, ImageMetadata, PixelFormat, load_from_memory};
|
||||||
use net_traits::image_cache::{CanRequestImages, ImageCache, ImageResponder};
|
use net_traits::image_cache::{CanRequestImages, ImageCache, ImageResponder};
|
||||||
use net_traits::image_cache::{ImageOrMetadataAvailable, ImageResponse, ImageState};
|
use net_traits::image_cache::{ImageOrMetadataAvailable, ImageResponse, ImageState};
|
||||||
use net_traits::image_cache::{PendingImageId, UsePlaceholder};
|
use net_traits::image_cache::{PendingImageId, UsePlaceholder};
|
||||||
use servo_config::resource_files::resources_dir_path;
|
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
use std::collections::hash_map::Entry::{Occupied, Vacant};
|
||||||
use std::fs::File;
|
use std::io;
|
||||||
use std::io::{self, Read};
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use webrender_api;
|
use webrender_api;
|
||||||
|
@ -42,11 +40,8 @@ fn decode_bytes_sync(key: LoadKey, bytes: &[u8]) -> DecoderMsg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_placeholder_image(webrender_api: &webrender_api::RenderApi, path: &PathBuf) -> io::Result<Arc<Image>> {
|
fn get_placeholder_image(webrender_api: &webrender_api::RenderApi, data: &[u8]) -> io::Result<Arc<Image>> {
|
||||||
let mut file = File::open(path)?;
|
let mut image = load_from_memory(&data).unwrap();
|
||||||
let mut image_data = vec![];
|
|
||||||
file.read_to_end(&mut image_data)?;
|
|
||||||
let mut image = load_from_memory(&image_data).unwrap();
|
|
||||||
set_webrender_image_key(webrender_api, &mut image);
|
set_webrender_image_key(webrender_api, &mut image);
|
||||||
Ok(Arc::new(image))
|
Ok(Arc::new(image))
|
||||||
}
|
}
|
||||||
|
@ -403,15 +398,14 @@ impl ImageCache for ImageCacheImpl {
|
||||||
fn new(webrender_api: webrender_api::RenderApi) -> ImageCacheImpl {
|
fn new(webrender_api: webrender_api::RenderApi) -> ImageCacheImpl {
|
||||||
debug!("New image cache");
|
debug!("New image cache");
|
||||||
|
|
||||||
let mut placeholder_path = resources_dir_path().expect("Can't figure out resources path.");
|
let rippy_data = resources::read_bytes(Resource::RippyPNG);
|
||||||
placeholder_path.push("rippy.png");
|
|
||||||
|
|
||||||
ImageCacheImpl {
|
ImageCacheImpl {
|
||||||
store: Arc::new(Mutex::new(ImageCacheStore {
|
store: Arc::new(Mutex::new(ImageCacheStore {
|
||||||
pending_loads: AllPendingLoads::new(),
|
pending_loads: AllPendingLoads::new(),
|
||||||
completed_loads: HashMap::new(),
|
completed_loads: HashMap::new(),
|
||||||
placeholder_image: get_placeholder_image(&webrender_api, &placeholder_path).ok(),
|
placeholder_image: get_placeholder_image(&webrender_api, &rippy_data).ok(),
|
||||||
placeholder_url: ServoUrl::from_file_path(&placeholder_path).unwrap(),
|
placeholder_url: ServoUrl::parse("chrome://resources/rippy.png").unwrap(),
|
||||||
webrender_api: webrender_api,
|
webrender_api: webrender_api,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ extern crate base64;
|
||||||
extern crate brotli;
|
extern crate brotli;
|
||||||
extern crate cookie as cookie_rs;
|
extern crate cookie as cookie_rs;
|
||||||
extern crate devtools_traits;
|
extern crate devtools_traits;
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate flate2;
|
extern crate flate2;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
extern crate hyper_openssl;
|
extern crate hyper_openssl;
|
||||||
|
@ -44,7 +45,6 @@ extern crate webrender_api;
|
||||||
extern crate websocket;
|
extern crate websocket;
|
||||||
|
|
||||||
mod blob_loader;
|
mod blob_loader;
|
||||||
mod chrome_loader;
|
|
||||||
pub mod connector;
|
pub mod connector;
|
||||||
pub mod cookie;
|
pub mod cookie;
|
||||||
pub mod cookie_storage;
|
pub mod cookie_storage;
|
||||||
|
@ -68,7 +68,6 @@ pub mod fetch {
|
||||||
|
|
||||||
/// A module for re-exports of items used in unit tests.
|
/// A module for re-exports of items used in unit tests.
|
||||||
pub mod test {
|
pub mod test {
|
||||||
pub use chrome_loader::resolve_chrome_url;
|
|
||||||
pub use http_loader::HttpState;
|
pub use http_loader::HttpState;
|
||||||
pub use hosts::{replace_host_table, parse_hostsfile};
|
pub use hosts::{replace_host_table, parse_hostsfile};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ use cookie;
|
||||||
use cookie_rs;
|
use cookie_rs;
|
||||||
use cookie_storage::CookieStorage;
|
use cookie_storage::CookieStorage;
|
||||||
use devtools_traits::DevtoolsControlMsg;
|
use devtools_traits::DevtoolsControlMsg;
|
||||||
|
use embedder_traits::resources::{self, Resource};
|
||||||
use fetch::cors_cache::CorsCache;
|
use fetch::cors_cache::CorsCache;
|
||||||
use fetch::methods::{CancellationListener, FetchContext, fetch};
|
use fetch::methods::{CancellationListener, FetchContext, fetch};
|
||||||
use filemanager_thread::{FileManager, TFDProvider};
|
use filemanager_thread::{FileManager, TFDProvider};
|
||||||
|
@ -31,12 +32,11 @@ use serde::{Deserialize, Serialize};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use servo_allocator;
|
use servo_allocator;
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use servo_config::resource_files::resources_dir_path;
|
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::borrow::{Cow, ToOwned};
|
use std::borrow::{Cow, ToOwned};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs::File;
|
use std::fs::{self, File};
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
@ -118,14 +118,16 @@ fn create_http_states(config_dir: Option<&Path>) -> (Arc<HttpState>, Arc<HttpSta
|
||||||
read_json_from_file(&mut cookie_jar, config_dir, "cookie_jar.json");
|
read_json_from_file(&mut cookie_jar, config_dir, "cookie_jar.json");
|
||||||
}
|
}
|
||||||
|
|
||||||
let ca_file = match opts::get().certificate_path {
|
let certs = match opts::get().certificate_path {
|
||||||
Some(ref path) => PathBuf::from(path),
|
Some(ref path) => {
|
||||||
None => resources_dir_path()
|
fs::read_to_string(path).expect("Couldn't not find certificate file")
|
||||||
.expect("Need certificate file to make network requests")
|
}
|
||||||
.join("certs"),
|
None => {
|
||||||
|
resources::read_string(Resource::SSLCertificates)
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let ssl_client = create_ssl_client(&ca_file);
|
let ssl_client = create_ssl_client(&certs);
|
||||||
let http_state = HttpState {
|
let http_state = HttpState {
|
||||||
cookie_jar: RwLock::new(cookie_jar),
|
cookie_jar: RwLock::new(cookie_jar),
|
||||||
auth_cache: RwLock::new(auth_cache),
|
auth_cache: RwLock::new(auth_cache),
|
||||||
|
@ -136,7 +138,7 @@ fn create_http_states(config_dir: Option<&Path>) -> (Arc<HttpState>, Arc<HttpSta
|
||||||
connector: create_http_connector(ssl_client),
|
connector: create_http_connector(ssl_client),
|
||||||
};
|
};
|
||||||
|
|
||||||
let private_ssl_client = create_ssl_client(&ca_file);
|
let private_ssl_client = create_ssl_client(&certs);
|
||||||
let private_http_state = HttpState::new(private_ssl_client);
|
let private_http_state = HttpState::new(private_ssl_client);
|
||||||
|
|
||||||
(Arc::new(http_state), Arc::new(private_http_state))
|
(Arc::new(http_state), Arc::new(private_http_state))
|
||||||
|
|
|
@ -1,44 +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 net::test::resolve_chrome_url;
|
|
||||||
use servo_url::ServoUrl;
|
|
||||||
|
|
||||||
fn c(s: &str) -> Result<ServoUrl, ()> {
|
|
||||||
resolve_chrome_url(&ServoUrl::parse(s).unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_resolve_chrome_url() {
|
|
||||||
assert_eq!(c("chrome://resources/nonexistent.jpg"), Err(()));
|
|
||||||
assert_eq!(c("chrome://not-resources/badcert.jpg"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources/badcert.jpg").unwrap().scheme(), "file");
|
|
||||||
assert_eq!(c("chrome://resources/subdir/../badcert.jpg").unwrap().scheme(), "file");
|
|
||||||
assert_eq!(c("chrome://resources/subdir/../../badcert.jpg").unwrap().scheme(), "file");
|
|
||||||
assert_eq!(c("chrome://resources/../badcert.jpg").unwrap().scheme(), "file");
|
|
||||||
assert_eq!(c("chrome://resources/../README.md"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources/%2e%2e/README.md"), Err(()));
|
|
||||||
|
|
||||||
assert_eq!(c("chrome://resources/etc/passwd"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources//etc/passwd"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources/%2Fetc%2Fpasswd"), Err(()));
|
|
||||||
|
|
||||||
assert_eq!(c("chrome://resources/C:/Windows/notepad.exe"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources/C:\\Windows\\notepad.exe"), Err(()));
|
|
||||||
|
|
||||||
assert_eq!(c("chrome://resources/localhost/C:/Windows/notepad.exe"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources//localhost/C:/Windows/notepad.exe"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources///localhost/C:/Windows/notepad.exe"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources/\\\\localhost\\C:\\Windows\\notepad.exe"), Err(()));
|
|
||||||
|
|
||||||
assert_eq!(c("chrome://resources/%3F/C:/Windows/notepad.exe"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources//%3F/C:/Windows/notepad.exe"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources///%3F/C:/Windows/notepad.exe"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources/\\\\%3F\\C:\\Windows\\notepad.exe"), Err(()));
|
|
||||||
|
|
||||||
assert_eq!(c("chrome://resources/%3F/UNC/localhost/C:/Windows/notepad.exe"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources//%3F/UNC/localhost/C:/Windows/notepad.exe"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources///%3F/UNC/localhost/C:/Windows/notepad.exe"), Err(()));
|
|
||||||
assert_eq!(c("chrome://resources/\\\\%3F\\UNC\\localhost\\C:\\Windows\\notepad.exe"), Err(()));
|
|
||||||
}
|
|
|
@ -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 cookie_rs;
|
use cookie_rs;
|
||||||
|
use embedder_traits::resources::register_resources_for_tests;
|
||||||
use hyper::header::{Header, SetCookie};
|
use hyper::header::{Header, SetCookie};
|
||||||
use net::cookie::Cookie;
|
use net::cookie::Cookie;
|
||||||
use net::cookie_storage::CookieStorage;
|
use net::cookie_storage::CookieStorage;
|
||||||
|
@ -56,6 +57,7 @@ fn test_default_path() {
|
||||||
#[test]
|
#[test]
|
||||||
fn fn_cookie_constructor() {
|
fn fn_cookie_constructor() {
|
||||||
use net_traits::CookieSource;
|
use net_traits::CookieSource;
|
||||||
|
register_resources_for_tests();
|
||||||
|
|
||||||
let url = &ServoUrl::parse("http://example.com/foo").unwrap();
|
let url = &ServoUrl::parse("http://example.com/foo").unwrap();
|
||||||
|
|
||||||
|
@ -102,6 +104,7 @@ fn fn_cookie_constructor() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cookie_secure_prefix() {
|
fn test_cookie_secure_prefix() {
|
||||||
|
register_resources_for_tests();
|
||||||
let url = &ServoUrl::parse("https://example.com").unwrap();
|
let url = &ServoUrl::parse("https://example.com").unwrap();
|
||||||
let cookie = cookie_rs::Cookie::parse("__Secure-SID=12345").unwrap();
|
let cookie = cookie_rs::Cookie::parse("__Secure-SID=12345").unwrap();
|
||||||
assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none());
|
assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none());
|
||||||
|
@ -129,6 +132,7 @@ fn test_cookie_secure_prefix() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cookie_host_prefix() {
|
fn test_cookie_host_prefix() {
|
||||||
|
register_resources_for_tests();
|
||||||
let url = &ServoUrl::parse("https://example.com").unwrap();
|
let url = &ServoUrl::parse("https://example.com").unwrap();
|
||||||
let cookie = cookie_rs::Cookie::parse("__Host-SID=12345").unwrap();
|
let cookie = cookie_rs::Cookie::parse("__Host-SID=12345").unwrap();
|
||||||
assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none());
|
assert!(Cookie::new_wrapped(cookie, url, CookieSource::HTTP).is_none());
|
||||||
|
@ -182,6 +186,7 @@ fn delay_to_ensure_different_timestamp() {}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sort_order() {
|
fn test_sort_order() {
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
register_resources_for_tests();
|
||||||
|
|
||||||
let url = &ServoUrl::parse("http://example.com/foo").unwrap();
|
let url = &ServoUrl::parse("http://example.com/foo").unwrap();
|
||||||
let a_wrapped = cookie_rs::Cookie::parse("baz=bar; Path=/foo/bar/").unwrap();
|
let a_wrapped = cookie_rs::Cookie::parse("baz=bar; Path=/foo/bar/").unwrap();
|
||||||
|
@ -201,6 +206,7 @@ fn test_sort_order() {
|
||||||
|
|
||||||
fn add_cookie_to_storage(storage: &mut CookieStorage, url: &ServoUrl, cookie_str: &str)
|
fn add_cookie_to_storage(storage: &mut CookieStorage, url: &ServoUrl, cookie_str: &str)
|
||||||
{
|
{
|
||||||
|
register_resources_for_tests();
|
||||||
let source = CookieSource::HTTP;
|
let source = CookieSource::HTTP;
|
||||||
let cookie = cookie_rs::Cookie::parse(cookie_str.to_owned()).unwrap();
|
let cookie = cookie_rs::Cookie::parse(cookie_str.to_owned()).unwrap();
|
||||||
let cookie = Cookie::new_wrapped(cookie, url, source).unwrap();
|
let cookie = Cookie::new_wrapped(cookie, url, source).unwrap();
|
||||||
|
@ -209,6 +215,7 @@ fn add_cookie_to_storage(storage: &mut CookieStorage, url: &ServoUrl, cookie_str
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_insecure_cookies_cannot_evict_secure_cookie() {
|
fn test_insecure_cookies_cannot_evict_secure_cookie() {
|
||||||
|
register_resources_for_tests();
|
||||||
let mut storage = CookieStorage::new(5);
|
let mut storage = CookieStorage::new(5);
|
||||||
let secure_url = ServoUrl::parse("https://home.example.org:8888/cookie-parser?0001").unwrap();
|
let secure_url = ServoUrl::parse("https://home.example.org:8888/cookie-parser?0001").unwrap();
|
||||||
let source = CookieSource::HTTP;
|
let source = CookieSource::HTTP;
|
||||||
|
@ -245,6 +252,7 @@ fn test_insecure_cookies_cannot_evict_secure_cookie() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_secure_cookies_eviction() {
|
fn test_secure_cookies_eviction() {
|
||||||
|
register_resources_for_tests();
|
||||||
let mut storage = CookieStorage::new(5);
|
let mut storage = CookieStorage::new(5);
|
||||||
let url = ServoUrl::parse("https://home.example.org:8888/cookie-parser?0001").unwrap();
|
let url = ServoUrl::parse("https://home.example.org:8888/cookie-parser?0001").unwrap();
|
||||||
let source = CookieSource::HTTP;
|
let source = CookieSource::HTTP;
|
||||||
|
@ -280,6 +288,7 @@ fn test_secure_cookies_eviction() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_secure_cookies_eviction_non_http_source() {
|
fn test_secure_cookies_eviction_non_http_source() {
|
||||||
|
register_resources_for_tests();
|
||||||
let mut storage = CookieStorage::new(5);
|
let mut storage = CookieStorage::new(5);
|
||||||
let url = ServoUrl::parse("https://home.example.org:8888/cookie-parser?0001").unwrap();
|
let url = ServoUrl::parse("https://home.example.org:8888/cookie-parser?0001").unwrap();
|
||||||
let source = CookieSource::NonHTTP;
|
let source = CookieSource::NonHTTP;
|
||||||
|
@ -341,6 +350,7 @@ fn add_retrieve_cookies(set_location: &str,
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cookie_eviction_expired() {
|
fn test_cookie_eviction_expired() {
|
||||||
|
register_resources_for_tests();
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
for i in 1..6 {
|
for i in 1..6 {
|
||||||
let st = format!("extra{}=bar; Secure; expires=Sun, 18-Apr-2000 21:06:29 GMT",
|
let st = format!("extra{}=bar; Secure; expires=Sun, 18-Apr-2000 21:06:29 GMT",
|
||||||
|
@ -356,6 +366,7 @@ fn test_cookie_eviction_expired() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cookie_eviction_all_secure_one_nonsecure() {
|
fn test_cookie_eviction_all_secure_one_nonsecure() {
|
||||||
|
register_resources_for_tests();
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
for i in 1..5 {
|
for i in 1..5 {
|
||||||
let st = format!("extra{}=bar; Secure; expires=Sun, 18-Apr-2026 21:06:29 GMT",
|
let st = format!("extra{}=bar; Secure; expires=Sun, 18-Apr-2026 21:06:29 GMT",
|
||||||
|
@ -372,6 +383,7 @@ fn test_cookie_eviction_all_secure_one_nonsecure() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cookie_eviction_all_secure_new_nonsecure() {
|
fn test_cookie_eviction_all_secure_new_nonsecure() {
|
||||||
|
register_resources_for_tests();
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
for i in 1..6 {
|
for i in 1..6 {
|
||||||
let st = format!("extra{}=bar; Secure; expires=Sun, 18-Apr-2026 21:06:29 GMT",
|
let st = format!("extra{}=bar; Secure; expires=Sun, 18-Apr-2026 21:06:29 GMT",
|
||||||
|
@ -387,6 +399,7 @@ fn test_cookie_eviction_all_secure_new_nonsecure() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cookie_eviction_all_nonsecure_new_secure() {
|
fn test_cookie_eviction_all_nonsecure_new_secure() {
|
||||||
|
register_resources_for_tests();
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
for i in 1..6 {
|
for i in 1..6 {
|
||||||
let st = format!("extra{}=bar; expires=Sun, 18-Apr-2026 21:06:29 GMT", i);
|
let st = format!("extra{}=bar; expires=Sun, 18-Apr-2026 21:06:29 GMT", i);
|
||||||
|
@ -401,6 +414,7 @@ fn test_cookie_eviction_all_nonsecure_new_secure() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cookie_eviction_all_nonsecure_new_nonsecure() {
|
fn test_cookie_eviction_all_nonsecure_new_nonsecure() {
|
||||||
|
register_resources_for_tests();
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
for i in 1..6 {
|
for i in 1..6 {
|
||||||
let st = format!("extra{}=bar; expires=Sun, 18-Apr-2026 21:06:29 GMT", i);
|
let st = format!("extra{}=bar; expires=Sun, 18-Apr-2026 21:06:29 GMT", i);
|
||||||
|
|
|
@ -6,6 +6,7 @@ use {DEFAULT_USER_AGENT, new_fetch_context, fetch, make_server};
|
||||||
use devtools_traits::DevtoolsControlMsg;
|
use devtools_traits::DevtoolsControlMsg;
|
||||||
use devtools_traits::HttpRequest as DevtoolsHttpRequest;
|
use devtools_traits::HttpRequest as DevtoolsHttpRequest;
|
||||||
use devtools_traits::HttpResponse as DevtoolsHttpResponse;
|
use devtools_traits::HttpResponse as DevtoolsHttpResponse;
|
||||||
|
use embedder_traits::resources::register_resources_for_tests;
|
||||||
use fetch_with_context;
|
use fetch_with_context;
|
||||||
use fetch_with_cors_cache;
|
use fetch_with_cors_cache;
|
||||||
use http_loader::{expect_devtools_http_request, expect_devtools_http_response};
|
use http_loader::{expect_devtools_http_request, expect_devtools_http_response};
|
||||||
|
@ -34,10 +35,10 @@ use net_traits::NetworkError;
|
||||||
use net_traits::ReferrerPolicy;
|
use net_traits::ReferrerPolicy;
|
||||||
use net_traits::request::{Destination, Origin, RedirectMode, Referrer, Request, RequestMode};
|
use net_traits::request::{Destination, Origin, RedirectMode, Referrer, Request, RequestMode};
|
||||||
use net_traits::response::{CacheState, Response, ResponseBody, ResponseType};
|
use net_traits::response::{CacheState, Response, ResponseBody, ResponseType};
|
||||||
use servo_config::resource_files::resources_dir_path;
|
|
||||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
|
use std::path::Path;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::mpsc::{Sender, channel};
|
use std::sync::mpsc::{Sender, channel};
|
||||||
|
@ -48,6 +49,7 @@ use unicase::UniCase;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_response_is_not_network_error() {
|
fn test_fetch_response_is_not_network_error() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"";
|
static MESSAGE: &'static [u8] = b"";
|
||||||
let handler = move |_: HyperRequest, response: HyperResponse| {
|
let handler = move |_: HyperRequest, response: HyperResponse| {
|
||||||
response.send(MESSAGE).unwrap();
|
response.send(MESSAGE).unwrap();
|
||||||
|
@ -67,6 +69,7 @@ fn test_fetch_response_is_not_network_error() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_on_bad_port_is_network_error() {
|
fn test_fetch_on_bad_port_is_network_error() {
|
||||||
|
register_resources_for_tests();
|
||||||
let url = ServoUrl::parse("http://www.example.org:6667").unwrap();
|
let url = ServoUrl::parse("http://www.example.org:6667").unwrap();
|
||||||
let origin = Origin::Origin(url.origin());
|
let origin = Origin::Origin(url.origin());
|
||||||
let mut request = Request::new(url, Some(origin), None);
|
let mut request = Request::new(url, Some(origin), None);
|
||||||
|
@ -79,6 +82,7 @@ fn test_fetch_on_bad_port_is_network_error() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_response_body_matches_const_message() {
|
fn test_fetch_response_body_matches_const_message() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"Hello World!";
|
static MESSAGE: &'static [u8] = b"Hello World!";
|
||||||
let handler = move |_: HyperRequest, response: HyperResponse| {
|
let handler = move |_: HyperRequest, response: HyperResponse| {
|
||||||
response.send(MESSAGE).unwrap();
|
response.send(MESSAGE).unwrap();
|
||||||
|
@ -104,6 +108,7 @@ fn test_fetch_response_body_matches_const_message() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_aboutblank() {
|
fn test_fetch_aboutblank() {
|
||||||
|
register_resources_for_tests();
|
||||||
let url = ServoUrl::parse("about:blank").unwrap();
|
let url = ServoUrl::parse("about:blank").unwrap();
|
||||||
let origin = Origin::Origin(url.origin());
|
let origin = Origin::Origin(url.origin());
|
||||||
let mut request = Request::new(url, Some(origin), None);
|
let mut request = Request::new(url, Some(origin), None);
|
||||||
|
@ -115,6 +120,7 @@ fn test_fetch_aboutblank() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_blob() {
|
fn test_fetch_blob() {
|
||||||
|
register_resources_for_tests();
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
use net_traits::blob_url_store::BlobBuf;
|
use net_traits::blob_url_store::BlobBuf;
|
||||||
|
|
||||||
|
@ -155,9 +161,8 @@ fn test_fetch_blob() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_file() {
|
fn test_fetch_file() {
|
||||||
let mut path = resources_dir_path().expect("Cannot find resource dir");
|
register_resources_for_tests();
|
||||||
path.push("servo.css");
|
let path = Path::new("../../resources/servo.css").canonicalize().unwrap();
|
||||||
|
|
||||||
let url = ServoUrl::from_file_path(path.clone()).unwrap();
|
let url = ServoUrl::from_file_path(path.clone()).unwrap();
|
||||||
let origin = Origin::Origin(url.origin());
|
let origin = Origin::Origin(url.origin());
|
||||||
let mut request = Request::new(url, Some(origin), None);
|
let mut request = Request::new(url, Some(origin), None);
|
||||||
|
@ -183,6 +188,7 @@ fn test_fetch_file() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_ftp() {
|
fn test_fetch_ftp() {
|
||||||
|
register_resources_for_tests();
|
||||||
let url = ServoUrl::parse("ftp://not-supported").unwrap();
|
let url = ServoUrl::parse("ftp://not-supported").unwrap();
|
||||||
let origin = Origin::Origin(url.origin());
|
let origin = Origin::Origin(url.origin());
|
||||||
let mut request = Request::new(url, Some(origin), None);
|
let mut request = Request::new(url, Some(origin), None);
|
||||||
|
@ -193,6 +199,7 @@ fn test_fetch_ftp() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_bogus_scheme() {
|
fn test_fetch_bogus_scheme() {
|
||||||
|
register_resources_for_tests();
|
||||||
let url = ServoUrl::parse("bogus://whatever").unwrap();
|
let url = ServoUrl::parse("bogus://whatever").unwrap();
|
||||||
let origin = Origin::Origin(url.origin());
|
let origin = Origin::Origin(url.origin());
|
||||||
let mut request = Request::new(url, Some(origin), None);
|
let mut request = Request::new(url, Some(origin), None);
|
||||||
|
@ -203,6 +210,7 @@ fn test_fetch_bogus_scheme() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cors_preflight_fetch() {
|
fn test_cors_preflight_fetch() {
|
||||||
|
register_resources_for_tests();
|
||||||
static ACK: &'static [u8] = b"ACK";
|
static ACK: &'static [u8] = b"ACK";
|
||||||
let state = Arc::new(AtomicUsize::new(0));
|
let state = Arc::new(AtomicUsize::new(0));
|
||||||
let handler = move |request: HyperRequest, mut response: HyperResponse| {
|
let handler = move |request: HyperRequest, mut response: HyperResponse| {
|
||||||
|
@ -240,6 +248,7 @@ fn test_cors_preflight_fetch() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cors_preflight_cache_fetch() {
|
fn test_cors_preflight_cache_fetch() {
|
||||||
|
register_resources_for_tests();
|
||||||
static ACK: &'static [u8] = b"ACK";
|
static ACK: &'static [u8] = b"ACK";
|
||||||
let state = Arc::new(AtomicUsize::new(0));
|
let state = Arc::new(AtomicUsize::new(0));
|
||||||
let counter = state.clone();
|
let counter = state.clone();
|
||||||
|
@ -292,6 +301,7 @@ fn test_cors_preflight_cache_fetch() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cors_preflight_fetch_network_error() {
|
fn test_cors_preflight_fetch_network_error() {
|
||||||
|
register_resources_for_tests();
|
||||||
static ACK: &'static [u8] = b"ACK";
|
static ACK: &'static [u8] = b"ACK";
|
||||||
let state = Arc::new(AtomicUsize::new(0));
|
let state = Arc::new(AtomicUsize::new(0));
|
||||||
let handler = move |request: HyperRequest, mut response: HyperResponse| {
|
let handler = move |request: HyperRequest, mut response: HyperResponse| {
|
||||||
|
@ -322,6 +332,7 @@ fn test_cors_preflight_fetch_network_error() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_response_is_basic_filtered() {
|
fn test_fetch_response_is_basic_filtered() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"";
|
static MESSAGE: &'static [u8] = b"";
|
||||||
let handler = move |_: HyperRequest, mut response: HyperResponse| {
|
let handler = move |_: HyperRequest, mut response: HyperResponse| {
|
||||||
response.headers_mut().set(SetCookie(vec![]));
|
response.headers_mut().set(SetCookie(vec![]));
|
||||||
|
@ -348,6 +359,7 @@ fn test_fetch_response_is_basic_filtered() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_response_is_cors_filtered() {
|
fn test_fetch_response_is_cors_filtered() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"";
|
static MESSAGE: &'static [u8] = b"";
|
||||||
let handler = move |_: HyperRequest, mut response: HyperResponse| {
|
let handler = move |_: HyperRequest, mut response: HyperResponse| {
|
||||||
// this is mandatory for the Cors Check to pass
|
// this is mandatory for the Cors Check to pass
|
||||||
|
@ -402,6 +414,7 @@ fn test_fetch_response_is_cors_filtered() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_response_is_opaque_filtered() {
|
fn test_fetch_response_is_opaque_filtered() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"";
|
static MESSAGE: &'static [u8] = b"";
|
||||||
let handler = move |_: HyperRequest, response: HyperResponse| {
|
let handler = move |_: HyperRequest, response: HyperResponse| {
|
||||||
response.send(MESSAGE).unwrap();
|
response.send(MESSAGE).unwrap();
|
||||||
|
@ -435,6 +448,7 @@ fn test_fetch_response_is_opaque_filtered() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_response_is_opaque_redirect_filtered() {
|
fn test_fetch_response_is_opaque_redirect_filtered() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"";
|
static MESSAGE: &'static [u8] = b"";
|
||||||
let handler = move |request: HyperRequest, mut response: HyperResponse| {
|
let handler = move |request: HyperRequest, mut response: HyperResponse| {
|
||||||
let redirects = match request.uri {
|
let redirects = match request.uri {
|
||||||
|
@ -481,6 +495,7 @@ fn test_fetch_response_is_opaque_redirect_filtered() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_with_local_urls_only() {
|
fn test_fetch_with_local_urls_only() {
|
||||||
|
register_resources_for_tests();
|
||||||
// If flag `local_urls_only` is set, fetching a non-local URL must result in network error.
|
// If flag `local_urls_only` is set, fetching a non-local URL must result in network error.
|
||||||
|
|
||||||
static MESSAGE: &'static [u8] = b"";
|
static MESSAGE: &'static [u8] = b"";
|
||||||
|
@ -519,26 +534,24 @@ fn test_fetch_with_local_urls_only() {
|
||||||
// And make sure to specify `localhost` as the server name.
|
// And make sure to specify `localhost` as the server name.
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_with_hsts() {
|
fn test_fetch_with_hsts() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"";
|
static MESSAGE: &'static [u8] = b"";
|
||||||
let handler = move |_: HyperRequest, response: HyperResponse| {
|
let handler = move |_: HyperRequest, response: HyperResponse| {
|
||||||
response.send(MESSAGE).unwrap();
|
response.send(MESSAGE).unwrap();
|
||||||
};
|
};
|
||||||
|
|
||||||
let path = resources_dir_path().expect("Cannot find resource dir");
|
let cert_path = Path::new("../../resources/self_signed_certificate_for_testing.crt").canonicalize().unwrap();
|
||||||
let mut cert_path = path.clone();
|
let key_path = Path::new("../../resources/privatekey_for_testing.key").canonicalize().unwrap();
|
||||||
cert_path.push("self_signed_certificate_for_testing.crt");
|
|
||||||
|
|
||||||
let mut key_path = path.clone();
|
let ssl = hyper_openssl::OpensslServer::from_files(key_path, cert_path.clone())
|
||||||
key_path.push("privatekey_for_testing.key");
|
|
||||||
|
|
||||||
let ssl = hyper_openssl::OpensslServer::from_files(key_path, cert_path)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
//takes an address and something that implements hyper::net::Ssl
|
//takes an address and something that implements hyper::net::Ssl
|
||||||
let mut server = Server::https("0.0.0.0:0", ssl).unwrap().handle_threads(handler, 1).unwrap();
|
let mut server = Server::https("0.0.0.0:0", ssl).unwrap().handle_threads(handler, 1).unwrap();
|
||||||
|
|
||||||
let ca_file = resources_dir_path().unwrap().join("self_signed_certificate_for_testing.crt");
|
let mut ca_content = String::new();
|
||||||
let ssl_client = create_ssl_client(&ca_file);
|
File::open(cert_path).unwrap().read_to_string(&mut ca_content).unwrap();
|
||||||
|
let ssl_client = create_ssl_client(&ca_content);
|
||||||
|
|
||||||
let context = FetchContext {
|
let context = FetchContext {
|
||||||
state: Arc::new(HttpState::new(ssl_client)),
|
state: Arc::new(HttpState::new(ssl_client)),
|
||||||
|
@ -568,6 +581,7 @@ fn test_fetch_with_hsts() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_with_sri_network_error() {
|
fn test_fetch_with_sri_network_error() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"alert('Hello, Network Error');";
|
static MESSAGE: &'static [u8] = b"alert('Hello, Network Error');";
|
||||||
let handler = move |_: HyperRequest, response: HyperResponse| {
|
let handler = move |_: HyperRequest, response: HyperResponse| {
|
||||||
response.send(MESSAGE).unwrap();
|
response.send(MESSAGE).unwrap();
|
||||||
|
@ -592,6 +606,7 @@ fn test_fetch_with_sri_network_error() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_with_sri_sucess() {
|
fn test_fetch_with_sri_sucess() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"alert('Hello, world.');";
|
static MESSAGE: &'static [u8] = b"alert('Hello, world.');";
|
||||||
let handler = move |_: HyperRequest, response: HyperResponse| {
|
let handler = move |_: HyperRequest, response: HyperResponse| {
|
||||||
response.send(MESSAGE).unwrap();
|
response.send(MESSAGE).unwrap();
|
||||||
|
@ -659,6 +674,7 @@ fn test_fetch_blocked_nosniff() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_server_and_fetch(message: &'static [u8], redirect_cap: u32) -> Response {
|
fn setup_server_and_fetch(message: &'static [u8], redirect_cap: u32) -> Response {
|
||||||
|
register_resources_for_tests();
|
||||||
let handler = move |request: HyperRequest, mut response: HyperResponse| {
|
let handler = move |request: HyperRequest, mut response: HyperResponse| {
|
||||||
let redirects = match request.uri {
|
let redirects = match request.uri {
|
||||||
RequestUri::AbsolutePath(url) =>
|
RequestUri::AbsolutePath(url) =>
|
||||||
|
@ -689,6 +705,7 @@ fn setup_server_and_fetch(message: &'static [u8], redirect_cap: u32) -> Response
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_redirect_count_ceiling() {
|
fn test_fetch_redirect_count_ceiling() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"no more redirects";
|
static MESSAGE: &'static [u8] = b"no more redirects";
|
||||||
// how many redirects to cause
|
// how many redirects to cause
|
||||||
let redirect_cap = 20;
|
let redirect_cap = 20;
|
||||||
|
@ -708,6 +725,7 @@ fn test_fetch_redirect_count_ceiling() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_redirect_count_failure() {
|
fn test_fetch_redirect_count_failure() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"this message shouldn't be reachable";
|
static MESSAGE: &'static [u8] = b"this message shouldn't be reachable";
|
||||||
// how many redirects to cause
|
// how many redirects to cause
|
||||||
let redirect_cap = 21;
|
let redirect_cap = 21;
|
||||||
|
@ -773,6 +791,7 @@ fn test_fetch_redirect_updates_method_runner(tx: Sender<bool>, status_code: Stat
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_redirect_updates_method() {
|
fn test_fetch_redirect_updates_method() {
|
||||||
|
register_resources_for_tests();
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
|
|
||||||
test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::MovedPermanently, Method::Post);
|
test_fetch_redirect_updates_method_runner(tx.clone(), StatusCode::MovedPermanently, Method::Post);
|
||||||
|
@ -831,6 +850,7 @@ fn response_is_done(response: &Response) -> bool {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_async_returns_complete_response() {
|
fn test_fetch_async_returns_complete_response() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"this message should be retrieved in full";
|
static MESSAGE: &'static [u8] = b"this message should be retrieved in full";
|
||||||
let handler = move |_: HyperRequest, response: HyperResponse| {
|
let handler = move |_: HyperRequest, response: HyperResponse| {
|
||||||
response.send(MESSAGE).unwrap();
|
response.send(MESSAGE).unwrap();
|
||||||
|
@ -849,6 +869,7 @@ fn test_fetch_async_returns_complete_response() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_opaque_filtered_fetch_async_returns_complete_response() {
|
fn test_opaque_filtered_fetch_async_returns_complete_response() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"";
|
static MESSAGE: &'static [u8] = b"";
|
||||||
let handler = move |_: HyperRequest, response: HyperResponse| {
|
let handler = move |_: HyperRequest, response: HyperResponse| {
|
||||||
response.send(MESSAGE).unwrap();
|
response.send(MESSAGE).unwrap();
|
||||||
|
@ -870,6 +891,7 @@ fn test_opaque_filtered_fetch_async_returns_complete_response() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_opaque_redirect_filtered_fetch_async_returns_complete_response() {
|
fn test_opaque_redirect_filtered_fetch_async_returns_complete_response() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"";
|
static MESSAGE: &'static [u8] = b"";
|
||||||
let handler = move |request: HyperRequest, mut response: HyperResponse| {
|
let handler = move |request: HyperRequest, mut response: HyperResponse| {
|
||||||
let redirects = match request.uri {
|
let redirects = match request.uri {
|
||||||
|
@ -906,6 +928,7 @@ fn test_opaque_redirect_filtered_fetch_async_returns_complete_response() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_fetch_with_devtools() {
|
fn test_fetch_with_devtools() {
|
||||||
|
register_resources_for_tests();
|
||||||
static MESSAGE: &'static [u8] = b"Yay!";
|
static MESSAGE: &'static [u8] = b"Yay!";
|
||||||
let handler = move |_: HyperRequest, response: HyperResponse| {
|
let handler = move |_: HyperRequest, response: HyperResponse| {
|
||||||
response.send(MESSAGE).unwrap();
|
response.send(MESSAGE).unwrap();
|
||||||
|
|
|
@ -176,24 +176,24 @@ fn test_push_entry_to_hsts_list_should_add_an_entry() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_hsts_preload_should_return_none_when_json_invalid() {
|
fn test_parse_hsts_preload_should_return_none_when_json_invalid() {
|
||||||
let mock_preload_content = b"derp";
|
let mock_preload_content = "derp";
|
||||||
assert!(HstsList::from_preload(mock_preload_content).is_none(), "invalid preload list should not have parsed")
|
assert!(HstsList::from_preload(mock_preload_content).is_none(), "invalid preload list should not have parsed")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_hsts_preload_should_return_none_when_json_contains_no_entries_map_key() {
|
fn test_parse_hsts_preload_should_return_none_when_json_contains_no_entries_map_key() {
|
||||||
let mock_preload_content = b"{\"nothing\": \"to see here\"}";
|
let mock_preload_content = "{\"nothing\": \"to see here\"}";
|
||||||
assert!(HstsList::from_preload(mock_preload_content).is_none(), "invalid preload list should not have parsed")
|
assert!(HstsList::from_preload(mock_preload_content).is_none(), "invalid preload list should not have parsed")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parse_hsts_preload_should_decode_host_and_includes_subdomains() {
|
fn test_parse_hsts_preload_should_decode_host_and_includes_subdomains() {
|
||||||
let mock_preload_content = b"{\
|
let mock_preload_content = "{\
|
||||||
\"entries\": [\
|
\"entries\": [\
|
||||||
{\"host\": \"mozilla.org\",\
|
{\"host\": \"mozilla.org\",\
|
||||||
\"include_subdomains\": false}\
|
\"include_subdomains\": false}\
|
||||||
]\
|
]\
|
||||||
}";
|
}";
|
||||||
let hsts_list = HstsList::from_preload(mock_preload_content);
|
let hsts_list = HstsList::from_preload(mock_preload_content);
|
||||||
let entries_map = hsts_list.unwrap().entries_map;
|
let entries_map = hsts_list.unwrap().entries_map;
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ use cookie_rs::Cookie as CookiePair;
|
||||||
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent};
|
use devtools_traits::{ChromeToDevtoolsControlMsg, DevtoolsControlMsg, NetworkEvent};
|
||||||
use devtools_traits::HttpRequest as DevtoolsHttpRequest;
|
use devtools_traits::HttpRequest as DevtoolsHttpRequest;
|
||||||
use devtools_traits::HttpResponse as DevtoolsHttpResponse;
|
use devtools_traits::HttpResponse as DevtoolsHttpResponse;
|
||||||
|
use embedder_traits::resources::register_resources_for_tests;
|
||||||
use fetch;
|
use fetch;
|
||||||
use fetch_with_context;
|
use fetch_with_context;
|
||||||
use flate2::Compression;
|
use flate2::Compression;
|
||||||
|
@ -312,6 +313,7 @@ fn test_request_and_response_message_from_devtool_without_pipeline_id() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_redirected_request_to_devtools() {
|
fn test_redirected_request_to_devtools() {
|
||||||
|
register_resources_for_tests();
|
||||||
let post_handler = move |request: HyperRequest, response: HyperResponse| {
|
let post_handler = move |request: HyperRequest, response: HyperResponse| {
|
||||||
assert_eq!(request.method, Method::Get);
|
assert_eq!(request.method, Method::Get);
|
||||||
response.send(b"Yay!").unwrap();
|
response.send(b"Yay!").unwrap();
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
extern crate cookie as cookie_rs;
|
extern crate cookie as cookie_rs;
|
||||||
extern crate devtools_traits;
|
extern crate devtools_traits;
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate flate2;
|
extern crate flate2;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
extern crate hyper_openssl;
|
extern crate hyper_openssl;
|
||||||
|
@ -15,13 +16,11 @@ extern crate msg;
|
||||||
extern crate net;
|
extern crate net;
|
||||||
extern crate net_traits;
|
extern crate net_traits;
|
||||||
extern crate profile_traits;
|
extern crate profile_traits;
|
||||||
extern crate servo_config;
|
|
||||||
extern crate servo_url;
|
extern crate servo_url;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
extern crate unicase;
|
extern crate unicase;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
mod chrome_loader;
|
|
||||||
mod cookie;
|
mod cookie;
|
||||||
mod cookie_http_state;
|
mod cookie_http_state;
|
||||||
mod data_loader;
|
mod data_loader;
|
||||||
|
@ -35,6 +34,7 @@ mod resource_thread;
|
||||||
mod subresource_integrity;
|
mod subresource_integrity;
|
||||||
|
|
||||||
use devtools_traits::DevtoolsControlMsg;
|
use devtools_traits::DevtoolsControlMsg;
|
||||||
|
use embedder_traits::resources::{self, Resource};
|
||||||
use hyper::server::{Handler, Listening, Server};
|
use hyper::server::{Handler, Listening, Server};
|
||||||
use net::connector::create_ssl_client;
|
use net::connector::create_ssl_client;
|
||||||
use net::fetch::cors_cache::CorsCache;
|
use net::fetch::cors_cache::CorsCache;
|
||||||
|
@ -44,7 +44,6 @@ use net::test::HttpState;
|
||||||
use net_traits::FetchTaskTarget;
|
use net_traits::FetchTaskTarget;
|
||||||
use net_traits::request::Request;
|
use net_traits::request::Request;
|
||||||
use net_traits::response::Response;
|
use net_traits::response::Response;
|
||||||
use servo_config::resource_files::resources_dir_path;
|
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::sync::mpsc::{Sender, channel};
|
use std::sync::mpsc::{Sender, channel};
|
||||||
|
@ -56,8 +55,7 @@ struct FetchResponseCollector {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_fetch_context(dc: Option<Sender<DevtoolsControlMsg>>) -> FetchContext {
|
fn new_fetch_context(dc: Option<Sender<DevtoolsControlMsg>>) -> FetchContext {
|
||||||
let ca_file = resources_dir_path().unwrap().join("certs");
|
let ssl_client = create_ssl_client(&resources::read_string(Resource::SSLCertificates));
|
||||||
let ssl_client = create_ssl_client(&ca_file);
|
|
||||||
FetchContext {
|
FetchContext {
|
||||||
state: Arc::new(HttpState::new(ssl_client)),
|
state: Arc::new(HttpState::new(ssl_client)),
|
||||||
user_agent: DEFAULT_USER_AGENT.into(),
|
user_agent: DEFAULT_USER_AGENT.into(),
|
||||||
|
|
|
@ -13,6 +13,7 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cookie = "0.10"
|
cookie = "0.10"
|
||||||
|
embedder_traits = { path = "../embedder_traits" }
|
||||||
hyper = "0.10"
|
hyper = "0.10"
|
||||||
hyper_serde = "0.8"
|
hyper_serde = "0.8"
|
||||||
image = "0.18"
|
image = "0.18"
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#![deny(unsafe_code)]
|
#![deny(unsafe_code)]
|
||||||
|
|
||||||
extern crate cookie as cookie_rs;
|
extern crate cookie as cookie_rs;
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate hyper;
|
extern crate hyper;
|
||||||
extern crate hyper_serde;
|
extern crate hyper_serde;
|
||||||
extern crate image as piston_image;
|
extern crate image as piston_image;
|
||||||
|
@ -18,7 +19,6 @@ extern crate msg;
|
||||||
extern crate num_traits;
|
extern crate num_traits;
|
||||||
#[macro_use] extern crate serde;
|
#[macro_use] extern crate serde;
|
||||||
extern crate servo_arc;
|
extern crate servo_arc;
|
||||||
extern crate servo_config;
|
|
||||||
extern crate servo_url;
|
extern crate servo_url;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
extern crate uuid;
|
extern crate uuid;
|
||||||
|
|
|
@ -14,11 +14,10 @@
|
||||||
//! we don't need to make the code more complex for it. The `mach` update command makes sure that
|
//! we don't need to make the code more complex for it. The `mach` update command makes sure that
|
||||||
//! those cases are not present.
|
//! those cases are not present.
|
||||||
|
|
||||||
use servo_config::resource_files::read_resource_file;
|
use embedder_traits::resources::{self, Resource};
|
||||||
use servo_url::{Host, ImmutableOrigin, ServoUrl};
|
use servo_url::{Host, ImmutableOrigin, ServoUrl};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
use std::str::from_utf8;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct PubDomainRules {
|
pub struct PubDomainRules {
|
||||||
|
@ -121,9 +120,7 @@ impl PubDomainRules {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_pub_domains() -> PubDomainRules {
|
fn load_pub_domains() -> PubDomainRules {
|
||||||
let content = read_resource_file("public_domains.txt").expect("Could not find public suffix list file");
|
PubDomainRules::parse(&resources::read_string(Resource::DomainList))
|
||||||
let content = from_utf8(&content).expect("Could not read public suffix list file");
|
|
||||||
PubDomainRules::parse(content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pub_suffix(domain: &str) -> &str {
|
pub fn pub_suffix(domain: &str) -> &str {
|
||||||
|
|
|
@ -2,14 +2,17 @@
|
||||||
* 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/. */
|
||||||
|
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate net_traits;
|
extern crate net_traits;
|
||||||
|
|
||||||
|
use embedder_traits::resources::register_resources_for_tests;
|
||||||
use net_traits::pub_domains::{is_pub_domain, is_reg_domain, pub_suffix, reg_suffix};
|
use net_traits::pub_domains::{is_pub_domain, is_reg_domain, pub_suffix, reg_suffix};
|
||||||
|
|
||||||
// These tests may need to be updated if the PSL changes.
|
// These tests may need to be updated if the PSL changes.
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_pub_domain_plain() {
|
fn test_is_pub_domain_plain() {
|
||||||
|
register_resources_for_tests();
|
||||||
assert!(is_pub_domain("com"));
|
assert!(is_pub_domain("com"));
|
||||||
assert!(is_pub_domain(".org"));
|
assert!(is_pub_domain(".org"));
|
||||||
assert!(is_pub_domain("za.org"));
|
assert!(is_pub_domain("za.org"));
|
||||||
|
@ -19,6 +22,7 @@ fn test_is_pub_domain_plain() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_pub_domain_wildcard() {
|
fn test_is_pub_domain_wildcard() {
|
||||||
|
register_resources_for_tests();
|
||||||
assert!(is_pub_domain("hello.bd"));
|
assert!(is_pub_domain("hello.bd"));
|
||||||
assert!(is_pub_domain("world.jm"));
|
assert!(is_pub_domain("world.jm"));
|
||||||
assert!(is_pub_domain("toto.kobe.jp"));
|
assert!(is_pub_domain("toto.kobe.jp"));
|
||||||
|
@ -26,6 +30,7 @@ fn test_is_pub_domain_wildcard() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_pub_domain_exception() {
|
fn test_is_pub_domain_exception() {
|
||||||
|
register_resources_for_tests();
|
||||||
assert_eq!(is_pub_domain("www.ck"), false);
|
assert_eq!(is_pub_domain("www.ck"), false);
|
||||||
assert_eq!(is_pub_domain("city.kawasaki.jp"), false);
|
assert_eq!(is_pub_domain("city.kawasaki.jp"), false);
|
||||||
assert_eq!(is_pub_domain("city.nagoya.jp"), false);
|
assert_eq!(is_pub_domain("city.nagoya.jp"), false);
|
||||||
|
@ -34,6 +39,7 @@ fn test_is_pub_domain_exception() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_pub_domain_not() {
|
fn test_is_pub_domain_not() {
|
||||||
|
register_resources_for_tests();
|
||||||
assert_eq!(is_pub_domain(""), false);
|
assert_eq!(is_pub_domain(""), false);
|
||||||
assert_eq!(is_pub_domain("."), false);
|
assert_eq!(is_pub_domain("."), false);
|
||||||
assert_eq!(is_pub_domain("..."), false);
|
assert_eq!(is_pub_domain("..."), false);
|
||||||
|
@ -46,6 +52,7 @@ fn test_is_pub_domain_not() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_pub_domain() {
|
fn test_is_pub_domain() {
|
||||||
|
register_resources_for_tests();
|
||||||
assert!(!is_pub_domain("city.yokohama.jp"));
|
assert!(!is_pub_domain("city.yokohama.jp"));
|
||||||
assert!(!is_pub_domain("foo.bar.baz.yokohama.jp"));
|
assert!(!is_pub_domain("foo.bar.baz.yokohama.jp"));
|
||||||
assert!(!is_pub_domain("foo.bar.city.yokohama.jp"));
|
assert!(!is_pub_domain("foo.bar.city.yokohama.jp"));
|
||||||
|
@ -64,6 +71,7 @@ fn test_is_pub_domain() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_reg_domain() {
|
fn test_is_reg_domain() {
|
||||||
|
register_resources_for_tests();
|
||||||
assert!(!is_reg_domain("com"));
|
assert!(!is_reg_domain("com"));
|
||||||
assert!(!is_reg_domain("foo.bar.baz.yokohama.jp"));
|
assert!(!is_reg_domain("foo.bar.baz.yokohama.jp"));
|
||||||
assert!(!is_reg_domain("foo.bar.com"));
|
assert!(!is_reg_domain("foo.bar.com"));
|
||||||
|
@ -81,6 +89,7 @@ fn test_is_reg_domain() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_pub_suffix() {
|
fn test_pub_suffix() {
|
||||||
|
register_resources_for_tests();
|
||||||
assert_eq!(pub_suffix("city.yokohama.jp"), "yokohama.jp");
|
assert_eq!(pub_suffix("city.yokohama.jp"), "yokohama.jp");
|
||||||
assert_eq!(pub_suffix("com"), "com");
|
assert_eq!(pub_suffix("com"), "com");
|
||||||
assert_eq!(pub_suffix("foo.bar.baz.yokohama.jp"), "baz.yokohama.jp");
|
assert_eq!(pub_suffix("foo.bar.baz.yokohama.jp"), "baz.yokohama.jp");
|
||||||
|
@ -98,6 +107,7 @@ fn test_pub_suffix() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_reg_suffix() {
|
fn test_reg_suffix() {
|
||||||
|
register_resources_for_tests();
|
||||||
assert_eq!(reg_suffix("city.yokohama.jp"), "city.yokohama.jp");
|
assert_eq!(reg_suffix("city.yokohama.jp"), "city.yokohama.jp");
|
||||||
assert_eq!(reg_suffix("com"), "com");
|
assert_eq!(reg_suffix("com"), "com");
|
||||||
assert_eq!(reg_suffix("foo.bar.baz.yokohama.jp"), "bar.baz.yokohama.jp");
|
assert_eq!(reg_suffix("foo.bar.baz.yokohama.jp"), "bar.baz.yokohama.jp");
|
||||||
|
@ -115,6 +125,7 @@ fn test_reg_suffix() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_weirdness() {
|
fn test_weirdness() {
|
||||||
|
register_resources_for_tests();
|
||||||
// These are weird results, but AFAICT they are spec-compliant.
|
// These are weird results, but AFAICT they are spec-compliant.
|
||||||
assert_ne!(pub_suffix("city.yokohama.jp"), pub_suffix(pub_suffix("city.yokohama.jp")));
|
assert_ne!(pub_suffix("city.yokohama.jp"), pub_suffix(pub_suffix("city.yokohama.jp")));
|
||||||
assert!(!is_pub_domain(pub_suffix("city.yokohama.jp")));
|
assert!(!is_pub_domain(pub_suffix("city.yokohama.jp")));
|
||||||
|
|
|
@ -42,6 +42,7 @@ deny_public_fields = {path = "../deny_public_fields"}
|
||||||
devtools_traits = {path = "../devtools_traits"}
|
devtools_traits = {path = "../devtools_traits"}
|
||||||
dom_struct = {path = "../dom_struct"}
|
dom_struct = {path = "../dom_struct"}
|
||||||
domobject_derive = {path = "../domobject_derive"}
|
domobject_derive = {path = "../domobject_derive"}
|
||||||
|
embedder_traits = {path = "../embedder_traits"}
|
||||||
encoding_rs = "0.7"
|
encoding_rs = "0.7"
|
||||||
euclid = "0.17"
|
euclid = "0.17"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
|
|
|
@ -30,6 +30,7 @@ use dom::processinginstruction::ProcessingInstruction;
|
||||||
use dom::text::Text;
|
use dom::text::Text;
|
||||||
use dom::virtualmethods::vtable_for;
|
use dom::virtualmethods::vtable_for;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
|
use embedder_traits::resources::{self, Resource};
|
||||||
use html5ever::{Attribute, ExpandedName, LocalName, QualName};
|
use html5ever::{Attribute, ExpandedName, LocalName, QualName};
|
||||||
use html5ever::buffer_queue::BufferQueue;
|
use html5ever::buffer_queue::BufferQueue;
|
||||||
use html5ever::tendril::{StrTendril, ByteTendril, IncompleteUtf8};
|
use html5ever::tendril::{StrTendril, ByteTendril, IncompleteUtf8};
|
||||||
|
@ -45,7 +46,6 @@ use profile_traits::time::{TimerMetadataReflowType, ProfilerCategory, profile};
|
||||||
use script_thread::ScriptThread;
|
use script_thread::ScriptThread;
|
||||||
use script_traits::DocumentActivity;
|
use script_traits::DocumentActivity;
|
||||||
use servo_config::prefs::PREFS;
|
use servo_config::prefs::PREFS;
|
||||||
use servo_config::resource_files::read_resource_file;
|
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
@ -671,16 +671,14 @@ impl FetchResponseListener for ParserContext {
|
||||||
// Handle text/html
|
// Handle text/html
|
||||||
if let Some(reason) = ssl_error {
|
if let Some(reason) = ssl_error {
|
||||||
self.is_synthesized_document = true;
|
self.is_synthesized_document = true;
|
||||||
let page_bytes = read_resource_file("badcert.html").unwrap();
|
let page = resources::read_string(Resource::BadCertHTML);
|
||||||
let page = String::from_utf8(page_bytes).unwrap();
|
|
||||||
let page = page.replace("${reason}", &reason);
|
let page = page.replace("${reason}", &reason);
|
||||||
parser.push_string_input_chunk(page);
|
parser.push_string_input_chunk(page);
|
||||||
parser.parse_sync();
|
parser.parse_sync();
|
||||||
}
|
}
|
||||||
if let Some(reason) = network_error {
|
if let Some(reason) = network_error {
|
||||||
self.is_synthesized_document = true;
|
self.is_synthesized_document = true;
|
||||||
let page_bytes = read_resource_file("neterror.html").unwrap();
|
let page = resources::read_string(Resource::NetErrorHTML);
|
||||||
let page = String::from_utf8(page_bytes).unwrap();
|
|
||||||
let page = page.replace("${reason}", &reason);
|
let page = page.replace("${reason}", &reason);
|
||||||
parser.push_string_input_chunk(page);
|
parser.push_string_input_chunk(page);
|
||||||
parser.parse_sync();
|
parser.parse_sync();
|
||||||
|
|
|
@ -8,7 +8,6 @@ use dom::htmlheadelement::HTMLHeadElement;
|
||||||
use dom::node::Node;
|
use dom::node::Node;
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use servo_config::resource_files::resources_dir_path;
|
|
||||||
use std::fs::{File, read_dir};
|
use std::fs::{File, read_dir};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -22,17 +21,7 @@ pub fn load_script(head: &HTMLHeadElement) {
|
||||||
let cx = win.get_cx();
|
let cx = win.get_cx();
|
||||||
rooted!(in(cx) let mut rval = UndefinedValue());
|
rooted!(in(cx) let mut rval = UndefinedValue());
|
||||||
|
|
||||||
let path = if &**path_str == "" {
|
let path = PathBuf::from(path_str);
|
||||||
if let Ok(mut p) = resources_dir_path() {
|
|
||||||
p.push("user-agent-js");
|
|
||||||
p
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PathBuf::from(path_str)
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut files = read_dir(&path).expect("Bad path passed to --userscripts")
|
let mut files = read_dir(&path).expect("Bad path passed to --userscripts")
|
||||||
.filter_map(|e| e.ok())
|
.filter_map(|e| e.ok())
|
||||||
.map(|e| e.path()).collect::<Vec<_>>();
|
.map(|e| e.path()).collect::<Vec<_>>();
|
||||||
|
|
|
@ -35,6 +35,7 @@ extern crate devtools_traits;
|
||||||
extern crate dom_struct;
|
extern crate dom_struct;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate domobject_derive;
|
extern crate domobject_derive;
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate encoding_rs;
|
extern crate encoding_rs;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
extern crate fnv;
|
extern crate fnv;
|
||||||
|
|
|
@ -37,6 +37,7 @@ constellation = {path = "../constellation"}
|
||||||
debugger = {path = "../debugger"}
|
debugger = {path = "../debugger"}
|
||||||
devtools = {path = "../devtools"}
|
devtools = {path = "../devtools"}
|
||||||
devtools_traits = {path = "../devtools_traits"}
|
devtools_traits = {path = "../devtools_traits"}
|
||||||
|
embedder_traits = {path = "../embedder_traits"}
|
||||||
env_logger = "0.5"
|
env_logger = "0.5"
|
||||||
euclid = "0.17"
|
euclid = "0.17"
|
||||||
gfx = {path = "../gfx"}
|
gfx = {path = "../gfx"}
|
||||||
|
|
|
@ -33,6 +33,7 @@ pub extern crate constellation;
|
||||||
pub extern crate debugger;
|
pub extern crate debugger;
|
||||||
pub extern crate devtools;
|
pub extern crate devtools;
|
||||||
pub extern crate devtools_traits;
|
pub extern crate devtools_traits;
|
||||||
|
pub extern crate embedder_traits;
|
||||||
pub extern crate euclid;
|
pub extern crate euclid;
|
||||||
pub extern crate gfx;
|
pub extern crate gfx;
|
||||||
pub extern crate ipc_channel;
|
pub extern crate ipc_channel;
|
||||||
|
@ -95,7 +96,6 @@ use profile_traits::time;
|
||||||
use script_traits::{ConstellationMsg, SWManagerSenders, ScriptToConstellationChan};
|
use script_traits::{ConstellationMsg, SWManagerSenders, ScriptToConstellationChan};
|
||||||
use servo_config::opts;
|
use servo_config::opts;
|
||||||
use servo_config::prefs::PREFS;
|
use servo_config::prefs::PREFS;
|
||||||
use servo_config::resource_files::resources_dir_path;
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -154,9 +154,6 @@ impl<Window> Servo<Window> where Window: WindowMethods + 'static {
|
||||||
devtools::start_server(port)
|
devtools::start_server(port)
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut resource_path = resources_dir_path().unwrap();
|
|
||||||
resource_path.push("shaders");
|
|
||||||
|
|
||||||
let coordinates = window.get_coordinates();
|
let coordinates = window.get_coordinates();
|
||||||
|
|
||||||
let (mut webrender, webrender_api_sender) = {
|
let (mut webrender, webrender_api_sender) = {
|
||||||
|
@ -181,7 +178,7 @@ impl<Window> Servo<Window> where Window: WindowMethods + 'static {
|
||||||
|
|
||||||
webrender::Renderer::new(window.gl(), render_notifier, webrender::RendererOptions {
|
webrender::Renderer::new(window.gl(), render_notifier, webrender::RendererOptions {
|
||||||
device_pixel_ratio: coordinates.hidpi_factor.get(),
|
device_pixel_ratio: coordinates.hidpi_factor.get(),
|
||||||
resource_override_path: Some(resource_path),
|
resource_override_path: opts.shaders_dir.clone(),
|
||||||
enable_aa: opts.enable_text_antialiasing,
|
enable_aa: opts.enable_text_antialiasing,
|
||||||
debug_flags: debug_flags,
|
debug_flags: debug_flags,
|
||||||
recorder: recorder,
|
recorder: recorder,
|
||||||
|
|
|
@ -39,6 +39,7 @@ bitflags = "1.0"
|
||||||
euclid = "0.17"
|
euclid = "0.17"
|
||||||
gleam = "0.4.34"
|
gleam = "0.4.34"
|
||||||
glutin = "0.13"
|
glutin = "0.13"
|
||||||
|
lazy_static = "1"
|
||||||
libservo = {path = "../../components/servo"}
|
libservo = {path = "../../components/servo"}
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
tinyfiledialogs = "3.0"
|
tinyfiledialogs = "3.0"
|
||||||
|
|
|
@ -25,6 +25,8 @@ extern crate euclid;
|
||||||
#[cfg(target_os = "windows")] extern crate gdi32;
|
#[cfg(target_os = "windows")] extern crate gdi32;
|
||||||
extern crate gleam;
|
extern crate gleam;
|
||||||
extern crate glutin;
|
extern crate glutin;
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
#[macro_use] extern crate lazy_static;
|
||||||
// The window backed by glutin
|
// The window backed by glutin
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
#[cfg(any(target_os = "linux", target_os = "macos"))] extern crate osmesa_sys;
|
#[cfg(any(target_os = "linux", target_os = "macos"))] extern crate osmesa_sys;
|
||||||
|
@ -38,6 +40,7 @@ extern crate winit;
|
||||||
#[cfg(target_os = "windows")] extern crate user32;
|
#[cfg(target_os = "windows")] extern crate user32;
|
||||||
|
|
||||||
mod glutin_app;
|
mod glutin_app;
|
||||||
|
mod resources;
|
||||||
|
|
||||||
use backtrace::Backtrace;
|
use backtrace::Backtrace;
|
||||||
use servo::Servo;
|
use servo::Servo;
|
||||||
|
@ -99,14 +102,16 @@ fn install_crash_handler() {}
|
||||||
fn main() {
|
fn main() {
|
||||||
install_crash_handler();
|
install_crash_handler();
|
||||||
|
|
||||||
|
resources::init();
|
||||||
|
|
||||||
// Parse the command line options and store them globally
|
// Parse the command line options and store them globally
|
||||||
let opts_result = opts::from_cmdline_args(&*args());
|
let opts_result = opts::from_cmdline_args(&*args());
|
||||||
|
|
||||||
let content_process_token = if let ArgumentParsingResult::ContentProcess(token) = opts_result {
|
let content_process_token = if let ArgumentParsingResult::ContentProcess(token) = opts_result {
|
||||||
Some(token)
|
Some(token)
|
||||||
} else {
|
} else {
|
||||||
if opts::get().is_running_problem_test && ::std::env::var("RUST_LOG").is_err() {
|
if opts::get().is_running_problem_test && env::var("RUST_LOG").is_err() {
|
||||||
::std::env::set_var("RUST_LOG", "compositing::constellation");
|
env::set_var("RUST_LOG", "compositing::constellation");
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
|
@ -217,7 +222,7 @@ fn main() {
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
fn setup_logging() {
|
fn setup_logging() {
|
||||||
// Piping logs from stdout/stderr to logcat happens in android_injected_glue.
|
// Piping logs from stdout/stderr to logcat happens in android_injected_glue.
|
||||||
::std::env::set_var("RUST_LOG", "error");
|
env::set_var("RUST_LOG", "error");
|
||||||
|
|
||||||
unsafe { android_injected_glue::ffi::app_dummy() };
|
unsafe { android_injected_glue::ffi::app_dummy() };
|
||||||
}
|
}
|
||||||
|
@ -263,7 +268,6 @@ fn args() -> Vec<String> {
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
fn args() -> Vec<String> {
|
fn args() -> Vec<String> {
|
||||||
use std::env;
|
|
||||||
env::args().collect()
|
env::args().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
112
ports/servo/resources.rs
Normal file
112
ports/servo/resources.rs
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/* 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 servo::embedder_traits::resources::{self, Resource};
|
||||||
|
|
||||||
|
struct ResourceReader;
|
||||||
|
|
||||||
|
fn filename(file: Resource) -> &'static str {
|
||||||
|
match file {
|
||||||
|
Resource::Preferences => "prefs.json",
|
||||||
|
Resource::BluetoothBlocklist => "gatt_blocklist.txt",
|
||||||
|
Resource::DomainList => "public_domains.txt",
|
||||||
|
Resource::HstsPreloadList => "hsts_preload.json",
|
||||||
|
Resource::SSLCertificates => "certs",
|
||||||
|
Resource::BadCertHTML => "badcert.html",
|
||||||
|
Resource::NetErrorHTML => "neterror.html",
|
||||||
|
Resource::UserAgentCSS => "user-agent.css",
|
||||||
|
Resource::ServoCSS => "servo.css",
|
||||||
|
Resource::PresentationalHintsCSS => "presentational-hints.css",
|
||||||
|
Resource::QuirksModeCSS => "quirks-mode.css",
|
||||||
|
Resource::RippyPNG => "rippy.png",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init() {
|
||||||
|
resources::set(Box::new(ResourceReader));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "android"))]
|
||||||
|
mod not_android {
|
||||||
|
use servo::embedder_traits::resources::{self, Resource};
|
||||||
|
use std::env;
|
||||||
|
use std::fs;
|
||||||
|
use std::io;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref CMD_RESOURCE_DIR: Mutex<Option<String>> = Mutex::new(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl resources::ResourceReaderMethods for super::ResourceReader {
|
||||||
|
fn read(&self, file: Resource) -> Vec<u8> {
|
||||||
|
let file = super::filename(file);
|
||||||
|
let mut path = resources_dir_path().expect("Can't find resources directory");
|
||||||
|
path.push(file);
|
||||||
|
fs::read(path).expect("Can't read file")
|
||||||
|
}
|
||||||
|
fn sandbox_access_files_dirs(&self) -> Vec<PathBuf> {
|
||||||
|
vec![resources_dir_path().expect("Can't find resources directory")]
|
||||||
|
}
|
||||||
|
fn sandbox_access_files(&self) -> Vec<PathBuf> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn resources_dir_path() -> io::Result<PathBuf> {
|
||||||
|
// This needs to be called before the process is sandboxed
|
||||||
|
// as we only give permission to read inside the resources directory,
|
||||||
|
// not the permissions the "search" for the resources directory.
|
||||||
|
let mut dir = CMD_RESOURCE_DIR.lock().unwrap();
|
||||||
|
if let Some(ref path) = *dir {
|
||||||
|
return Ok(PathBuf::from(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Find a way to not rely on the executable being
|
||||||
|
// under `<servo source>[/$target_triple]/target/debug`
|
||||||
|
// or `<servo source>[/$target_triple]/target/release`.
|
||||||
|
let mut path = env::current_exe()?;
|
||||||
|
// Follow symlink
|
||||||
|
path = path.canonicalize()?;
|
||||||
|
|
||||||
|
while path.pop() {
|
||||||
|
path.push("resources");
|
||||||
|
if path.is_dir() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
path.pop();
|
||||||
|
// Check for Resources on mac when using a case sensitive filesystem.
|
||||||
|
path.push("Resources");
|
||||||
|
if path.is_dir() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
path.pop();
|
||||||
|
}
|
||||||
|
*dir = Some(path.to_str().unwrap().to_owned());
|
||||||
|
Ok(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
mod android {
|
||||||
|
use android_injected_glue::load_asset;
|
||||||
|
use servo::embedder_traits::resources::{self, Resource};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
impl resources::ResourceReaderMethods for super::ResourceReader {
|
||||||
|
fn read(&self, file: Resource) -> Vec<u8> {
|
||||||
|
let file = super::filename(file);
|
||||||
|
load_asset(file).unwrap_or_else(|_| {
|
||||||
|
panic!("Can't load asset");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
fn sandbox_access_files_dirs(&self) -> Vec<PathBuf> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
fn sandbox_access_files(&self) -> Vec<PathBuf> {
|
||||||
|
vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,6 @@
|
||||||
<title>Certificate error</title>
|
<title>Certificate error</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<img src="chrome://resources/itried.jpg">
|
|
||||||
<p>${reason}</p>
|
<p>${reason}</p>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>about:failure</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<img src="itried.jpg"/>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
|
@ -52,12 +52,6 @@ public class MainActivity extends android.app.NativeActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
try {
|
|
||||||
extractAssets();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
if (intent != null && intent.getAction().equals(Intent.ACTION_VIEW)) {
|
if (intent != null && intent.getAction().equals(Intent.ACTION_VIEW)) {
|
||||||
final String url = intent.getDataString();
|
final String url = intent.getDataString();
|
||||||
|
@ -223,81 +217,10 @@ public class MainActivity extends android.app.NativeActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean needsToExtractAssets(String path) {
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
int version = BuildConfig.VERSION_CODE;
|
|
||||||
|
|
||||||
if (!new File(path).exists()) {
|
|
||||||
// Assets folder doesn't exist, resources need to be copied
|
|
||||||
prefs.edit().putInt(PREF_KEY_RESOURCES_SYNC, version).apply();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version != prefs.getInt(PREF_KEY_RESOURCES_SYNC, -1)) {
|
|
||||||
// Also force a reextract when the version changes and the resources may be updated
|
|
||||||
// This can be improved by generating a hash or version number of the resources
|
|
||||||
// instead of using version code of the app
|
|
||||||
prefs.edit().putInt(PREF_KEY_RESOURCES_SYNC, version).apply();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private File getAppDataDir() {
|
private File getAppDataDir() {
|
||||||
File file = getExternalFilesDir(null);
|
File file = getExternalFilesDir(null);
|
||||||
return file != null ? file : getFilesDir();
|
return file != null ? file : getFilesDir();
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* extracts assets/ in the APK to /sdcard/servo.
|
|
||||||
*/
|
|
||||||
private void extractAssets() throws IOException {
|
|
||||||
String path = getAppDataDir().getAbsolutePath();
|
|
||||||
if (!needsToExtractAssets(path)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZipFile zipFile = null;
|
|
||||||
File targetDir = new File(path);
|
|
||||||
try {
|
|
||||||
zipFile = new ZipFile(this.getApplicationInfo().sourceDir);
|
|
||||||
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements(); ) {
|
|
||||||
ZipEntry entry = e.nextElement();
|
|
||||||
if (entry.isDirectory() || !entry.getName().startsWith("assets/")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
File targetFile = new File(targetDir, entry.getName().substring("assets/".length()));
|
|
||||||
targetFile.getParentFile().mkdirs();
|
|
||||||
byte[] tempBuffer = new byte[(int)entry.getSize()];
|
|
||||||
BufferedInputStream is = null;
|
|
||||||
FileOutputStream os = null;
|
|
||||||
try {
|
|
||||||
is = new BufferedInputStream(zipFile.getInputStream(entry));
|
|
||||||
os = new FileOutputStream(targetFile);
|
|
||||||
is.read(tempBuffer);
|
|
||||||
os.write(tempBuffer);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (is != null) {
|
|
||||||
is.close();
|
|
||||||
}
|
|
||||||
if (os != null) {
|
|
||||||
os.close();
|
|
||||||
}
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.e(LOGTAG, Log.getStackTraceString(ex));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (zipFile != null) {
|
|
||||||
zipFile.close();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LOGTAG, Log.getStackTraceString(e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void set_url(String url) {
|
private void set_url(String url) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -13,6 +13,7 @@ doctest = false
|
||||||
byteorder = "1.0"
|
byteorder = "1.0"
|
||||||
app_units = "0.6"
|
app_units = "0.6"
|
||||||
cssparser = "0.23.0"
|
cssparser = "0.23.0"
|
||||||
|
embedder_traits = {path = "../../../components/embedder_traits"}
|
||||||
euclid = "0.17"
|
euclid = "0.17"
|
||||||
html5ever = "0.22"
|
html5ever = "0.22"
|
||||||
parking_lot = "0.5"
|
parking_lot = "0.5"
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
extern crate app_units;
|
extern crate app_units;
|
||||||
extern crate cssparser;
|
extern crate cssparser;
|
||||||
|
extern crate embedder_traits;
|
||||||
extern crate euclid;
|
extern crate euclid;
|
||||||
#[macro_use] extern crate html5ever;
|
#[macro_use] extern crate html5ever;
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
|
|
|
@ -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 cssparser::{self, SourceLocation};
|
use cssparser::{self, SourceLocation};
|
||||||
|
use embedder_traits::resources::register_resources_for_tests;
|
||||||
use html5ever::{Namespace as NsAtom};
|
use html5ever::{Namespace as NsAtom};
|
||||||
use media_queries::CSSErrorReporterTest;
|
use media_queries::CSSErrorReporterTest;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -321,6 +322,7 @@ impl ParseErrorReporter for TestingErrorReporter {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_report_error_stylesheet() {
|
fn test_report_error_stylesheet() {
|
||||||
|
register_resources_for_tests();
|
||||||
PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true));
|
PREFS.set("layout.viewport.enabled", PrefValue::Boolean(true));
|
||||||
let css = r"
|
let css = r"
|
||||||
div {
|
div {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue