diff options
-rw-r--r-- | components/embedder_traits/resources.rs | 102 | ||||
-rw-r--r-- | ports/gstplugin/resources.rs | 73 | ||||
-rw-r--r-- | ports/servoshell/prefs.rs | 16 | ||||
-rw-r--r-- | ports/servoshell/resources.rs | 68 |
4 files changed, 130 insertions, 129 deletions
diff --git a/components/embedder_traits/resources.rs b/components/embedder_traits/resources.rs index c5b77210d0b..04d3b0a706b 100644 --- a/components/embedder_traits/resources.rs +++ b/components/embedder_traits/resources.rs @@ -16,11 +16,6 @@ pub fn set(reader: Box<dyn ResourceReaderMethods + Sync + Send>) { *RES.write().unwrap() = Some(reader); } -pub fn set_for_tests() { - static ONCE: Once = Once::new(); - ONCE.call_once(|| set(resources_for_tests())); -} - pub fn read_bytes(res: Resource) -> Vec<u8> { RES.read() .unwrap() @@ -66,57 +61,82 @@ pub enum Resource { CrashHTML, } +impl Resource { + pub fn filename(&self) -> &'static str { + match self { + Resource::Preferences => "prefs.json", + Resource::BluetoothBlocklist => "gatt_blocklist.txt", + Resource::DomainList => "public_domains.txt", + Resource::HstsPreloadList => "hsts_preload.json", + 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", + Resource::MediaControlsCSS => "media-controls.css", + Resource::MediaControlsJS => "media-controls.js", + Resource::CrashHTML => "crash.html", + } + } +} + 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>; } +// Can’t #[cfg(test)] the following because it breaks tests in dependent crates. + +pub fn set_for_tests() { + static ONCE: Once = Once::new(); + ONCE.call_once(|| set(resources_for_tests())); +} + +lazy_static::lazy_static! { + static ref CMD_RESOURCE_DIR: std::sync::Mutex<Option<PathBuf>> = std::sync::Mutex::new(None); +} + +fn resources_dir_path_for_tests() -> 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 PathBuf::from(path); + } + + // Try ./resources in the current directory, then each of its ancestors. + let mut path = std::env::current_dir().unwrap(); + loop { + path.push("resources"); + if path.is_dir() { + *dir = Some(path); + return dir.clone().unwrap(); + } + path.pop(); + + if !path.pop() { + panic!("Can't find resources directory") + } + } +} + fn resources_for_tests() -> Box<dyn ResourceReaderMethods + Sync + Send> { - use std::env; - use std::fs::File; - use std::io::Read; struct ResourceReader; impl ResourceReaderMethods for ResourceReader { fn sandbox_access_files(&self) -> Vec<PathBuf> { vec![] } fn sandbox_access_files_dirs(&self) -> Vec<PathBuf> { - vec![] + vec![resources_dir_path_for_tests()] } 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::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", - Resource::MediaControlsCSS => "media-controls.css", - Resource::MediaControlsJS => "media-controls.js", - Resource::CrashHTML => "crash.html", - }; - 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 + let mut path = resources_dir_path_for_tests(); + path.push(file.filename()); + std::fs::read(path).expect("Can't read file") } } Box::new(ResourceReader) diff --git a/ports/gstplugin/resources.rs b/ports/gstplugin/resources.rs index 224efb0d7d3..1dfb8d96cad 100644 --- a/ports/gstplugin/resources.rs +++ b/ports/gstplugin/resources.rs @@ -8,82 +8,73 @@ use std::path::PathBuf; use std::sync::Mutex; -use std::{env, fs, io}; +use std::{env, fs}; -use lazy_static::lazy_static; use servo::embedder_traits::resources::{self, Resource}; -lazy_static! { - static ref CMD_RESOURCE_DIR: Mutex<Option<String>> = Mutex::new(None); +lazy_static::lazy_static! { + static ref CMD_RESOURCE_DIR: Mutex<Option<PathBuf>> = Mutex::new(None); } 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::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", - Resource::MediaControlsCSS => "media-controls.css", - Resource::MediaControlsJS => "media-controls.js", - Resource::CrashHTML => "crash.html", - } -} - pub fn init() { resources::set(Box::new(ResourceReader)); } -fn resources_dir_path() -> io::Result<PathBuf> { +fn resources_dir_path() -> 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)); + return 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 = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - // Follow symlink - path = path.canonicalize()?; - + // Try ./resources and ./Resources relative to the directory containing the + // canonicalised executable path, then each of its ancestors. + let mut path = env::current_exe().unwrap().canonicalize().unwrap(); while path.pop() { path.push("resources"); if path.is_dir() { - break; + *dir = Some(path); + return dir.clone().unwrap(); } path.pop(); + // Check for Resources on mac when using a case sensitive filesystem. path.push("Resources"); if path.is_dir() { - break; + *dir = Some(path); + return dir.clone().unwrap(); } path.pop(); } - *dir = Some(path.to_str().unwrap().to_owned()); - Ok(path) + + // Try ./resources in the current directory, then each of its ancestors. + let mut path = std::env::current_dir().unwrap(); + loop { + path.push("resources"); + if path.is_dir() { + *dir = Some(path); + return dir.clone().unwrap(); + } + path.pop(); + + if !path.pop() { + panic!("Can't find resources directory") + } + } } impl resources::ResourceReaderMethods for ResourceReader { fn read(&self, file: Resource) -> Vec<u8> { - let file = filename(file); - let mut path = resources_dir_path().expect("Can't find resources directory"); - path.push(file); - fs::read(path.clone()).expect(&format!("Can't read file {:?}", path)) + let mut path = resources_dir_path(); + path.push(file.filename()); + 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")] + vec![resources_dir_path()] } fn sandbox_access_files(&self) -> Vec<PathBuf> { vec![] diff --git a/ports/servoshell/prefs.rs b/ports/servoshell/prefs.rs index 0448850794d..325b766d4bb 100644 --- a/ports/servoshell/prefs.rs +++ b/ports/servoshell/prefs.rs @@ -6,10 +6,9 @@ use std::collections::HashMap; use std::fs::File; use std::io::Read; -use getopts::{Matches, Options}; -use servo::config::opts::{self, ArgumentParsingResult}; +use getopts::Matches; +use servo::config::opts; use servo::config::prefs::{self, PrefValue}; -use servo::embedder_traits; use servo::servo_config::basedir; pub fn register_user_prefs(opts_matches: &Matches) { @@ -61,16 +60,15 @@ pub fn register_user_prefs(opts_matches: &Matches) { prefs::add_user_prefs(userprefs); } -// Use for test -#[allow(dead_code)] +#[cfg(test)] fn test_parse_pref(arg: &str) { - embedder_traits::resources::set_for_tests(); - let mut opts = Options::new(); + servo::embedder_traits::resources::set_for_tests(); + let mut opts = getopts::Options::new(); opts.optmulti("", "pref", "", ""); let args = vec!["servo".to_string(), "--pref".to_string(), arg.to_string()]; let matches = match opts::from_cmdline_args(opts, &args) { - ArgumentParsingResult::ContentProcess(m, _) => m, - ArgumentParsingResult::ChromeProcess(m) => m, + opts::ArgumentParsingResult::ContentProcess(m, _) => m, + opts::ArgumentParsingResult::ChromeProcess(m) => m, }; register_user_prefs(&matches); } diff --git a/ports/servoshell/resources.rs b/ports/servoshell/resources.rs index 91ad584c26d..d27a1714969 100644 --- a/ports/servoshell/resources.rs +++ b/ports/servoshell/resources.rs @@ -4,81 +4,73 @@ use std::path::PathBuf; use std::sync::Mutex; -use std::{env, fs, io}; +use std::{env, fs}; use servo::embedder_traits::resources::{self, Resource}; lazy_static::lazy_static! { - static ref CMD_RESOURCE_DIR: Mutex<Option<String>> = Mutex::new(None); + static ref CMD_RESOURCE_DIR: Mutex<Option<PathBuf>> = Mutex::new(None); } 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::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", - Resource::MediaControlsCSS => "media-controls.css", - Resource::MediaControlsJS => "media-controls.js", - Resource::CrashHTML => "crash.html", - } -} - pub fn init() { resources::set(Box::new(ResourceReader)); } -fn resources_dir_path() -> io::Result<PathBuf> { +fn resources_dir_path() -> 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)); + return 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()?; - + // Try ./resources and ./Resources relative to the directory containing the + // canonicalised executable path, then each of its ancestors. + let mut path = env::current_exe().unwrap().canonicalize().unwrap(); while path.pop() { path.push("resources"); if path.is_dir() { - break; + *dir = Some(path); + return dir.clone().unwrap(); } path.pop(); + // Check for Resources on mac when using a case sensitive filesystem. path.push("Resources"); if path.is_dir() { - break; + *dir = Some(path); + return dir.clone().unwrap(); } path.pop(); } - *dir = Some(path.to_str().unwrap().to_owned()); - Ok(path) + + // Try ./resources in the current directory, then each of its ancestors. + let mut path = std::env::current_dir().unwrap(); + loop { + path.push("resources"); + if path.is_dir() { + *dir = Some(path); + return dir.clone().unwrap(); + } + path.pop(); + + if !path.pop() { + panic!("Can't find resources directory") + } + } } impl resources::ResourceReaderMethods for ResourceReader { fn read(&self, file: Resource) -> Vec<u8> { - let file = filename(file); - let mut path = resources_dir_path().expect("Can't find resources directory"); - path.push(file); + let mut path = resources_dir_path(); + path.push(file.filename()); 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")] + vec![resources_dir_path()] } fn sandbox_access_files(&self) -> Vec<PathBuf> { vec![] |