aboutsummaryrefslogtreecommitdiffstats
path: root/components/net/chrome_loader.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/net/chrome_loader.rs')
-rw-r--r--components/net/chrome_loader.rs53
1 files changed, 53 insertions, 0 deletions
diff --git a/components/net/chrome_loader.rs b/components/net/chrome_loader.rs
new file mode 100644
index 00000000000..544e9a64f4a
--- /dev/null
+++ b/components/net/chrome_loader.rs
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use file_loader;
+use mime_classifier::MIMEClassifier;
+use net_traits::{LoadConsumer, LoadData, NetworkError};
+use resource_thread::{CancellationListener, send_error};
+use std::fs::canonicalize;
+use std::sync::Arc;
+use url::Url;
+use url::percent_encoding::percent_decode;
+use util::resource_files::resources_dir_path;
+
+pub fn resolve_chrome_url(url: &Url) -> Result<Url, ()> {
+ assert_eq!(url.scheme(), "chrome");
+ if url.host_str() != Some("resources") {
+ return Err(())
+ }
+ let resources = canonicalize(resources_dir_path())
+ .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(Url::from_file_path(path).unwrap())
+ }
+ _ => Err(())
+ }
+}
+
+pub fn factory(mut load_data: LoadData,
+ start_chan: LoadConsumer,
+ classifier: Arc<MIMEClassifier>,
+ cancel_listener: CancellationListener) {
+ let file_url = match resolve_chrome_url(&load_data.url) {
+ Ok(url) => url,
+ Err(_) => {
+ send_error(load_data.url,
+ NetworkError::Internal("Invalid chrome URL.".to_owned()),
+ start_chan);
+ return;
+ }
+ };
+ load_data.url = file_url;
+ file_loader::factory(load_data, start_chan, classifier, cancel_listener)
+}