aboutsummaryrefslogtreecommitdiffstats
path: root/components/net/protocols/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/net/protocols/mod.rs')
-rw-r--r--components/net/protocols/mod.rs59
1 files changed, 50 insertions, 9 deletions
diff --git a/components/net/protocols/mod.rs b/components/net/protocols/mod.rs
index f8b989b9623..6dc58ceab64 100644
--- a/components/net/protocols/mod.rs
+++ b/components/net/protocols/mod.rs
@@ -14,6 +14,7 @@ use log::error;
use net_traits::filemanager_thread::RelativePos;
use net_traits::request::Request;
use net_traits::response::Response;
+use servo_url::ServoUrl;
use crate::fetch::methods::{DoneChannel, FetchContext, RangeRequestBounds};
@@ -47,6 +48,15 @@ pub trait ProtocolHandler: Send + Sync {
fn is_fetchable(&self) -> bool {
false
}
+
+ /// Specify if this custom protocol can be used in a [secure context]
+ ///
+ /// Note: this only works for bypassing mixed content checks right now
+ ///
+ /// [secure context]: https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts
+ fn is_secure(&self) -> bool {
+ false
+ }
}
#[derive(Default)]
@@ -54,27 +64,45 @@ pub struct ProtocolRegistry {
pub(crate) handlers: HashMap<String, Box<dyn ProtocolHandler>>, // Maps scheme -> handler
}
+#[derive(Clone, Copy, Debug)]
+pub enum ProtocolRegisterError {
+ ForbiddenScheme,
+ SchemeAlreadyRegistered,
+}
+
impl ProtocolRegistry {
pub fn with_internal_protocols() -> Self {
let mut registry = Self::default();
- registry.register("data", DataProtocolHander::default());
- registry.register("blob", BlobProtocolHander::default());
- registry.register("file", FileProtocolHander::default());
+ // We just created a new registry, and know that we aren't using
+ // any forbidden schemes, so this should never panic.
+ registry
+ .register("data", DataProtocolHander::default())
+ .expect("Infallible");
+ registry
+ .register("blob", BlobProtocolHander::default())
+ .expect("Infallible");
+ registry
+ .register("file", FileProtocolHander::default())
+ .expect("Infallible");
registry
}
- pub fn register(&mut self, scheme: &str, handler: impl ProtocolHandler + 'static) -> bool {
+ pub fn register(
+ &mut self,
+ scheme: &str,
+ handler: impl ProtocolHandler + 'static,
+ ) -> Result<(), ProtocolRegisterError> {
if FORBIDDEN_SCHEMES.contains(&scheme) {
error!("Protocol handler for '{scheme}' is not allowed to be registered.");
- return false;
+ return Err(ProtocolRegisterError::ForbiddenScheme);
}
if let Entry::Vacant(entry) = self.handlers.entry(scheme.into()) {
entry.insert(Box::new(handler));
- true
+ Ok(())
} else {
error!("Protocol handler for '{scheme}' is already registered.");
- false
+ Err(ProtocolRegisterError::SchemeAlreadyRegistered)
}
}
@@ -96,9 +124,22 @@ impl ProtocolRegistry {
pub fn is_fetchable(&self, scheme: &str) -> bool {
self.handlers
.get(scheme)
- .map(|handler| handler.is_fetchable())
- .unwrap_or(false)
+ .is_some_and(|handler| handler.is_fetchable())
}
+
+ pub fn is_secure(&self, scheme: &str) -> bool {
+ self.handlers
+ .get(scheme)
+ .is_some_and(|handler| handler.is_secure())
+ }
+}
+
+/// Test if the URL is potentially trustworthy or the custom protocol is registered as secure
+pub fn is_url_potentially_trustworthy(
+ protocol_registry: &ProtocolRegistry,
+ url: &ServoUrl,
+) -> bool {
+ url.is_potentially_trustworthy() || protocol_registry.is_secure(url.scheme())
}
pub fn range_not_satisfiable_error(response: &mut Response) {