Initial support for marking custom protocol secure (#36656)

Add initial support for marking custom protocol as secure, this makes it
possible to `fetch` a custom protocol inside secure contexts (e.g.
http://localhost)

Some additional contexts:

- [#embedding > Custom protocol secure
context](https://servo.zulipchat.com/#narrow/channel/437943-embedding/topic/Custom.20protocol.20secure.20context)
-
https://github.com/versotile-org/tauri-runtime-verso/issues/6#issuecomment-2820776128

Testing: use `fetch('urlinfo://abc').then(async (response) =>
console.log(await response.text())).catch(console.log)` in servoshell
with in a secure context (e.g. https://servo.org), and see the response
should not be an error

---------

Signed-off-by: Tony <legendmastertony@gmail.com>
Signed-off-by: Tony <68118705+Legend-Master@users.noreply.github.com>
Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Tony 2025-04-25 18:39:33 +08:00 committed by GitHub
parent cf59aa1948
commit 894fbd003d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 56 additions and 16 deletions

View file

@ -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)]
@ -114,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) {