aboutsummaryrefslogtreecommitdiffstats
path: root/components/embedder_traits/resources.rs
blob: c51a50d593753a1bf23bde282ac442f0c3e2cff7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* 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 https://mozilla.org/MPL/2.0/. */

use lazy_static::lazy_static;
use std::path::PathBuf;
use std::sync::{Once, RwLock};

lazy_static! {
    static ref RES: RwLock<Option<Box<dyn ResourceReaderMethods + Sync + Send>>> =
        RwLock::new(None);
}

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()
        .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,
    BadCertHTML,
    NetErrorHTML,
    UserAgentCSS,
    ServoCSS,
    PresentationalHintsCSS,
    QuirksModeCSS,
    RippyPNG,
    MediaControlsCSS,
    MediaControlsJS,
    CrashHTML,
}

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>;
}

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![]
        }
        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
        }
    }
    Box::new(ResourceReader)
}