summaryrefslogtreecommitdiff
path: root/cli/file_fetcher.rs
diff options
context:
space:
mode:
authorhaturau <135221985+haturatu@users.noreply.github.com>2024-11-20 01:20:47 +0900
committerGitHub <noreply@github.com>2024-11-20 01:20:47 +0900
commit85719a67e59c7aa45bead26e4942d7df8b1b42d4 (patch)
treeface0aecaac53e93ce2f23b53c48859bcf1a36ec /cli/file_fetcher.rs
parent67697bc2e4a62a9670699fd18ad0dd8efc5bd955 (diff)
parent186b52731c6bb326c4d32905c5e732d082e83465 (diff)
Merge branch 'denoland:main' into main
Diffstat (limited to 'cli/file_fetcher.rs')
-rw-r--r--cli/file_fetcher.rs45
1 files changed, 42 insertions, 3 deletions
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index 69daf1495..640f83c35 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -24,6 +24,7 @@ use deno_graph::source::LoaderChecksum;
use deno_path_util::url_to_file_path;
use deno_runtime::deno_permissions::PermissionsContainer;
use deno_runtime::deno_web::BlobStore;
+use http::header;
use log::debug;
use std::borrow::Cow;
use std::collections::HashMap;
@@ -163,8 +164,19 @@ fn get_validated_scheme(
) -> Result<String, AnyError> {
let scheme = specifier.scheme();
if !SUPPORTED_SCHEMES.contains(&scheme) {
+ // NOTE(bartlomieju): this message list additional `npm` and `jsr` schemes, but they should actually be handled
+ // before `file_fetcher.rs` APIs are even hit.
+ let mut all_supported_schemes = SUPPORTED_SCHEMES.to_vec();
+ all_supported_schemes.extend_from_slice(&["npm", "jsr"]);
+ all_supported_schemes.sort();
+ let scheme_list = all_supported_schemes
+ .iter()
+ .map(|scheme| format!(" - \"{}\"", scheme))
+ .collect::<Vec<_>>()
+ .join("\n");
Err(generic_error(format!(
- "Unsupported scheme \"{scheme}\" for module \"{specifier}\". Supported schemes: {SUPPORTED_SCHEMES:#?}"
+ "Unsupported scheme \"{scheme}\" for module \"{specifier}\". Supported schemes:\n{}",
+ scheme_list
)))
} else {
Ok(scheme.to_string())
@@ -181,6 +193,7 @@ pub enum FetchPermissionsOptionRef<'a> {
pub struct FetchOptions<'a> {
pub specifier: &'a ModuleSpecifier,
pub permissions: FetchPermissionsOptionRef<'a>,
+ pub maybe_auth: Option<(header::HeaderName, header::HeaderValue)>,
pub maybe_accept: Option<&'a str>,
pub maybe_cache_setting: Option<&'a CacheSetting>,
}
@@ -333,7 +346,7 @@ impl FileFetcher {
)
})?;
- let bytes = blob.read_all().await?;
+ let bytes = blob.read_all().await;
let headers =
HashMap::from([("content-type".to_string(), blob.media_type.clone())]);
@@ -350,6 +363,7 @@ impl FileFetcher {
maybe_accept: Option<&str>,
cache_setting: &CacheSetting,
maybe_checksum: Option<&LoaderChecksum>,
+ maybe_auth: Option<(header::HeaderName, header::HeaderValue)>,
) -> Result<FileOrRedirect, AnyError> {
debug!(
"FileFetcher::fetch_remote_no_follow - specifier: {}",
@@ -442,6 +456,7 @@ impl FileFetcher {
.as_ref()
.map(|(_, etag)| etag.clone()),
maybe_auth_token: maybe_auth_token.clone(),
+ maybe_auth: maybe_auth.clone(),
maybe_progress_guard: maybe_progress_guard.as_ref(),
})
.await?
@@ -538,7 +553,18 @@ impl FileFetcher {
specifier: &ModuleSpecifier,
) -> Result<File, AnyError> {
self
- .fetch_inner(specifier, FetchPermissionsOptionRef::AllowAll)
+ .fetch_inner(specifier, None, FetchPermissionsOptionRef::AllowAll)
+ .await
+ }
+
+ #[inline(always)]
+ pub async fn fetch_bypass_permissions_with_maybe_auth(
+ &self,
+ specifier: &ModuleSpecifier,
+ maybe_auth: Option<(header::HeaderName, header::HeaderValue)>,
+ ) -> Result<File, AnyError> {
+ self
+ .fetch_inner(specifier, maybe_auth, FetchPermissionsOptionRef::AllowAll)
.await
}
@@ -552,6 +578,7 @@ impl FileFetcher {
self
.fetch_inner(
specifier,
+ None,
FetchPermissionsOptionRef::StaticContainer(permissions),
)
.await
@@ -560,12 +587,14 @@ impl FileFetcher {
async fn fetch_inner(
&self,
specifier: &ModuleSpecifier,
+ maybe_auth: Option<(header::HeaderName, header::HeaderValue)>,
permissions: FetchPermissionsOptionRef<'_>,
) -> Result<File, AnyError> {
self
.fetch_with_options(FetchOptions {
specifier,
permissions,
+ maybe_auth,
maybe_accept: None,
maybe_cache_setting: None,
})
@@ -585,12 +614,14 @@ impl FileFetcher {
max_redirect: usize,
) -> Result<File, AnyError> {
let mut specifier = Cow::Borrowed(options.specifier);
+ let mut maybe_auth = options.maybe_auth.clone();
for _ in 0..=max_redirect {
match self
.fetch_no_follow_with_options(FetchNoFollowOptions {
fetch_options: FetchOptions {
specifier: &specifier,
permissions: options.permissions,
+ maybe_auth: maybe_auth.clone(),
maybe_accept: options.maybe_accept,
maybe_cache_setting: options.maybe_cache_setting,
},
@@ -602,6 +633,10 @@ impl FileFetcher {
return Ok(file);
}
FileOrRedirect::Redirect(redirect_specifier) => {
+ // If we were redirected to another origin, don't send the auth header anymore.
+ if redirect_specifier.origin() != specifier.origin() {
+ maybe_auth = None;
+ }
specifier = Cow::Owned(redirect_specifier);
}
}
@@ -666,6 +701,7 @@ impl FileFetcher {
options.maybe_accept,
options.maybe_cache_setting.unwrap_or(&self.cache_setting),
maybe_checksum,
+ options.maybe_auth,
)
.await
}
@@ -756,6 +792,7 @@ mod tests {
FetchOptions {
specifier,
permissions: FetchPermissionsOptionRef::AllowAll,
+ maybe_auth: None,
maybe_accept: None,
maybe_cache_setting: Some(&file_fetcher.cache_setting),
},
@@ -1255,6 +1292,7 @@ mod tests {
FetchOptions {
specifier: &specifier,
permissions: FetchPermissionsOptionRef::AllowAll,
+ maybe_auth: None,
maybe_accept: None,
maybe_cache_setting: Some(&file_fetcher.cache_setting),
},
@@ -1268,6 +1306,7 @@ mod tests {
FetchOptions {
specifier: &specifier,
permissions: FetchPermissionsOptionRef::AllowAll,
+ maybe_auth: None,
maybe_accept: None,
maybe_cache_setting: Some(&file_fetcher.cache_setting),
},