aboutsummaryrefslogtreecommitdiffstats
path: root/components/embedder_traits/resources.rs
blob: 2f301e213405c2cffe1be6dad27a7d8c88cdcf83 (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
/* 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));
    });
}