mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Let protocol handlers decide if they are fetchable (#33573)
This adds a 'is_fetchable()' method on the ProtocolHandler trait that is then used in the fetch code. The 'data:' protocol handler is updated to return true instead of hardcoding the scheme comparison, as well as the 'urlinfo:' handler since it's just a testing one. Signed-off-by: webbeef <me@webbeef.org>
This commit is contained in:
parent
5d269a9036
commit
f57ae60056
4 changed files with 34 additions and 5 deletions
|
@ -274,10 +274,12 @@ pub async fn main_fetch(
|
||||||
|
|
||||||
// Step 12.
|
// Step 12.
|
||||||
|
|
||||||
|
let current_url = request.current_url();
|
||||||
|
let current_scheme = current_url.scheme();
|
||||||
|
|
||||||
let mut response = match response {
|
let mut response = match response {
|
||||||
Some(res) => res,
|
Some(res) => res,
|
||||||
None => {
|
None => {
|
||||||
let current_url = request.current_url();
|
|
||||||
let same_origin = if let Origin::Origin(ref origin) = request.origin {
|
let same_origin = if let Origin::Origin(ref origin) = request.origin {
|
||||||
*origin == current_url.origin()
|
*origin == current_url.origin()
|
||||||
} else {
|
} else {
|
||||||
|
@ -285,8 +287,8 @@ pub async fn main_fetch(
|
||||||
};
|
};
|
||||||
|
|
||||||
if (same_origin && !cors_flag) ||
|
if (same_origin && !cors_flag) ||
|
||||||
current_url.scheme() == "data" ||
|
current_scheme == "chrome" ||
|
||||||
current_url.scheme() == "chrome" ||
|
context.protocols.is_fetchable(current_scheme) ||
|
||||||
matches!(
|
matches!(
|
||||||
request.mode,
|
request.mode,
|
||||||
RequestMode::Navigate | RequestMode::WebSocket { .. }
|
RequestMode::Navigate | RequestMode::WebSocket { .. }
|
||||||
|
@ -312,7 +314,7 @@ pub async fn main_fetch(
|
||||||
// Substep 3. Return the result of running scheme fetch given fetchParams.
|
// Substep 3. Return the result of running scheme fetch given fetchParams.
|
||||||
scheme_fetch(request, cache, target, done_chan, context).await
|
scheme_fetch(request, cache, target, done_chan, context).await
|
||||||
}
|
}
|
||||||
} else if !matches!(current_url.scheme(), "http" | "https") {
|
} else if !matches!(current_scheme, "http" | "https") {
|
||||||
Response::network_error(NetworkError::Internal("Non-http scheme".into()))
|
Response::network_error(NetworkError::Internal("Non-http scheme".into()))
|
||||||
} else if request.use_cors_preflight ||
|
} else if request.use_cors_preflight ||
|
||||||
(request.unsafe_request &&
|
(request.unsafe_request &&
|
||||||
|
@ -494,7 +496,7 @@ pub async fn main_fetch(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 21.
|
// Step 21.
|
||||||
if request.body.is_some() && matches!(request.current_url().scheme(), "http" | "https") {
|
if request.body.is_some() && matches!(current_scheme, "http" | "https") {
|
||||||
// XXXManishearth: We actually should be calling process_request
|
// XXXManishearth: We actually should be calling process_request
|
||||||
// in http_network_fetch. However, we can't yet follow the request
|
// in http_network_fetch. However, we can't yet follow the request
|
||||||
// upload progress, so I'm keeping it here for now and pretending
|
// upload progress, so I'm keeping it here for now and pretending
|
||||||
|
|
|
@ -54,4 +54,8 @@ impl ProtocolHandler for DataProtocolHander {
|
||||||
|
|
||||||
Box::pin(std::future::ready(response))
|
Box::pin(std::future::ready(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_fetchable(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,24 @@ use file::FileProtocolHander;
|
||||||
static FORBIDDEN_SCHEMES: [&str; 4] = ["http", "https", "chrome", "about"];
|
static FORBIDDEN_SCHEMES: [&str; 4] = ["http", "https", "chrome", "about"];
|
||||||
|
|
||||||
pub trait ProtocolHandler: Send + Sync {
|
pub trait ProtocolHandler: Send + Sync {
|
||||||
|
/// Triggers the load of a resource for this protocol and returns a future
|
||||||
|
/// that will produce a Response. Even if the protocol is not backed by a
|
||||||
|
/// http endpoint, it is recommended to a least provide:
|
||||||
|
/// - A relevant status code.
|
||||||
|
/// - A Content Type.
|
||||||
fn load(
|
fn load(
|
||||||
&self,
|
&self,
|
||||||
request: &mut Request,
|
request: &mut Request,
|
||||||
done_chan: &mut DoneChannel,
|
done_chan: &mut DoneChannel,
|
||||||
context: &FetchContext,
|
context: &FetchContext,
|
||||||
) -> Pin<Box<dyn Future<Output = Response> + Send>>;
|
) -> Pin<Box<dyn Future<Output = Response> + Send>>;
|
||||||
|
|
||||||
|
/// Specify if resources served by that protocol can be retrieved
|
||||||
|
/// with `fetch()` without no-cors mode to allow the caller direct
|
||||||
|
/// access to the resource content.
|
||||||
|
fn is_fetchable(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -80,6 +92,13 @@ impl ProtocolRegistry {
|
||||||
self.handlers.entry(scheme).or_insert(handler);
|
self.handlers.entry(scheme).or_insert(handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_fetchable(&self, scheme: &str) -> bool {
|
||||||
|
self.handlers
|
||||||
|
.get(scheme)
|
||||||
|
.map(|handler| handler.is_fetchable())
|
||||||
|
.unwrap_or(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn range_not_satisfiable_error(response: &mut Response) {
|
pub fn range_not_satisfiable_error(response: &mut Response) {
|
||||||
|
|
|
@ -43,4 +43,8 @@ impl ProtocolHandler for UrlInfoProtocolHander {
|
||||||
|
|
||||||
Box::pin(std::future::ready(response))
|
Box::pin(std::future::ready(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_fetchable(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue