1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

refactor: move redirect handling into deno_graph (#23444)

This commit is contained in:
David Sherret 2024-04-18 21:43:28 -04:00 committed by GitHub
parent 8e77f091ad
commit c497e766f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 377 additions and 263 deletions

View file

@ -48,7 +48,7 @@ deno_core = { version = "0.275.0" }
deno_bench_util = { version = "0.141.0", path = "./bench_util" } deno_bench_util = { version = "0.141.0", path = "./bench_util" }
deno_lockfile = "0.19.0" deno_lockfile = "0.19.0"
deno_media_type = { version = "0.1.3", features = ["module_specifier"] } deno_media_type = { version = "0.1.4", features = ["module_specifier"] }
deno_permissions = { version = "0.7.0", path = "./runtime/permissions" } deno_permissions = { version = "0.7.0", path = "./runtime/permissions" }
deno_runtime = { version = "0.155.0", path = "./runtime" } deno_runtime = { version = "0.155.0", path = "./runtime" }
deno_terminal = "0.1.1" deno_terminal = "0.1.1"

View file

@ -28,7 +28,7 @@ pub async fn resolve_import_map(
let specifier = specifier.clone(); let specifier = specifier.clone();
async move { async move {
let file = file_fetcher let file = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await? .await?
.into_text_decoded()?; .into_text_decoded()?;
Ok(file.source.to_string()) Ok(file.source.to_string())
@ -62,7 +62,7 @@ async fn resolve_import_map_from_specifier(
serde_json::from_str(&data_url_text)? serde_json::from_str(&data_url_text)?
} else { } else {
let file = file_fetcher let file = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await? .await?
.into_text_decoded()?; .into_text_decoded()?;
serde_json::from_str(&file.source)? serde_json::from_str(&file.source)?

55
cli/cache/mod.rs vendored
View file

@ -2,8 +2,10 @@
use crate::args::CacheSetting; use crate::args::CacheSetting;
use crate::errors::get_error_class_name; use crate::errors::get_error_class_name;
use crate::file_fetcher::FetchNoFollowOptions;
use crate::file_fetcher::FetchOptions; use crate::file_fetcher::FetchOptions;
use crate::file_fetcher::FileFetcher; use crate::file_fetcher::FileFetcher;
use crate::file_fetcher::FileOrRedirect;
use crate::npm::CliNpmResolver; use crate::npm::CliNpmResolver;
use crate::util::fs::atomic_write_file; use crate::util::fs::atomic_write_file;
@ -234,29 +236,40 @@ impl Loader for FetchCacher {
LoaderCacheSetting::Only => Some(CacheSetting::Only), LoaderCacheSetting::Only => Some(CacheSetting::Only),
}; };
file_fetcher file_fetcher
.fetch_with_options(FetchOptions { .fetch_no_follow_with_options(FetchNoFollowOptions {
specifier: &specifier, fetch_options: FetchOptions {
permissions, specifier: &specifier,
maybe_accept: None, permissions: &permissions,
maybe_cache_setting: maybe_cache_setting.as_ref(), maybe_accept: None,
maybe_checksum: options.maybe_checksum, maybe_cache_setting: maybe_cache_setting.as_ref(),
},
maybe_checksum: options.maybe_checksum.as_ref(),
}) })
.await .await
.map(|file| { .map(|file_or_redirect| {
let maybe_headers = match file_or_redirect {
match (file.maybe_headers, file_header_overrides.get(&specifier)) { FileOrRedirect::File(file) => {
(Some(headers), Some(overrides)) => { let maybe_headers =
Some(headers.into_iter().chain(overrides.clone()).collect()) match (file.maybe_headers, file_header_overrides.get(&specifier)) {
} (Some(headers), Some(overrides)) => {
(Some(headers), None) => Some(headers), Some(headers.into_iter().chain(overrides.clone()).collect())
(None, Some(overrides)) => Some(overrides.clone()), }
(None, None) => None, (Some(headers), None) => Some(headers),
}; (None, Some(overrides)) => Some(overrides.clone()),
Ok(Some(LoadResponse::Module { (None, None) => None,
specifier: file.specifier, };
maybe_headers, Ok(Some(LoadResponse::Module {
content: file.source, specifier: file.specifier,
})) maybe_headers,
content: file.source,
}))
},
FileOrRedirect::Redirect(redirect_specifier) => {
Ok(Some(LoadResponse::Redirect {
specifier: redirect_specifier,
}))
},
}
}) })
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
if let Some(io_err) = err.downcast_ref::<std::io::Error>() { if let Some(io_err) = err.downcast_ref::<std::io::Error>() {

View file

@ -20,8 +20,6 @@ use deno_core::error::custom_error;
use deno_core::error::generic_error; use deno_core::error::generic_error;
use deno_core::error::uri_error; use deno_core::error::uri_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::futures;
use deno_core::futures::future::FutureExt;
use deno_core::parking_lot::Mutex; use deno_core::parking_lot::Mutex;
use deno_core::url::Url; use deno_core::url::Url;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
@ -34,12 +32,11 @@ use deno_runtime::deno_fetch::reqwest::StatusCode;
use deno_runtime::deno_web::BlobStore; use deno_runtime::deno_web::BlobStore;
use deno_runtime::permissions::PermissionsContainer; use deno_runtime::permissions::PermissionsContainer;
use log::debug; use log::debug;
use std::borrow::Cow;
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
use std::fs; use std::fs;
use std::future::Future;
use std::path::PathBuf; use std::path::PathBuf;
use std::pin::Pin;
use std::sync::Arc; use std::sync::Arc;
use std::time::SystemTime; use std::time::SystemTime;
@ -56,6 +53,12 @@ pub struct TextDecodedFile {
pub source: Arc<str>, pub source: Arc<str>,
} }
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum FileOrRedirect {
File(File),
Redirect(ModuleSpecifier),
}
/// A structure representing a source file. /// A structure representing a source file.
#[derive(Debug, Clone, Eq, PartialEq)] #[derive(Debug, Clone, Eq, PartialEq)]
pub struct File { pub struct File {
@ -145,10 +148,16 @@ fn get_validated_scheme(
pub struct FetchOptions<'a> { pub struct FetchOptions<'a> {
pub specifier: &'a ModuleSpecifier, pub specifier: &'a ModuleSpecifier,
pub permissions: PermissionsContainer, pub permissions: &'a PermissionsContainer,
pub maybe_accept: Option<&'a str>, pub maybe_accept: Option<&'a str>,
pub maybe_cache_setting: Option<&'a CacheSetting>, pub maybe_cache_setting: Option<&'a CacheSetting>,
pub maybe_checksum: Option<LoaderChecksum>, }
pub struct FetchNoFollowOptions<'a> {
pub fetch_options: FetchOptions<'a>,
/// This setting doesn't make sense to provide for `FetchOptions`
/// since the required checksum may change for a redirect.
pub maybe_checksum: Option<&'a LoaderChecksum>,
} }
/// A structure for resolving, fetching and caching source files. /// A structure for resolving, fetching and caching source files.
@ -202,13 +211,34 @@ impl FileFetcher {
pub fn fetch_cached( pub fn fetch_cached(
&self, &self,
specifier: &ModuleSpecifier, specifier: &ModuleSpecifier,
maybe_checksum: Option<LoaderChecksum>,
redirect_limit: i64, redirect_limit: i64,
) -> Result<Option<File>, AnyError> { ) -> Result<Option<File>, AnyError> {
debug!("FileFetcher::fetch_cached - specifier: {}", specifier); let mut specifier = Cow::Borrowed(specifier);
if redirect_limit < 0 { for _ in 0..=redirect_limit {
return Err(custom_error("Http", "Too many redirects.")); match self.fetch_cached_no_follow(&specifier, None)? {
Some(FileOrRedirect::File(file)) => {
return Ok(Some(file));
}
Some(FileOrRedirect::Redirect(redirect_specifier)) => {
specifier = Cow::Owned(redirect_specifier);
}
None => {
return Ok(None);
}
}
} }
Err(custom_error("Http", "Too many redirects."))
}
fn fetch_cached_no_follow(
&self,
specifier: &ModuleSpecifier,
maybe_checksum: Option<&LoaderChecksum>,
) -> Result<Option<FileOrRedirect>, AnyError> {
debug!(
"FileFetcher::fetch_cached_no_follow - specifier: {}",
specifier
);
let cache_key = self.http_cache.cache_item_key(specifier)?; // compute this once let cache_key = self.http_cache.cache_item_key(specifier)?; // compute this once
let Some(headers) = self.http_cache.read_headers(&cache_key)? else { let Some(headers) = self.http_cache.read_headers(&cache_key)? else {
@ -217,7 +247,7 @@ impl FileFetcher {
if let Some(redirect_to) = headers.get("location") { if let Some(redirect_to) = headers.get("location") {
let redirect = let redirect =
deno_core::resolve_import(redirect_to, specifier.as_str())?; deno_core::resolve_import(redirect_to, specifier.as_str())?;
return self.fetch_cached(&redirect, maybe_checksum, redirect_limit - 1); return Ok(Some(FileOrRedirect::Redirect(redirect)));
} }
let Some(bytes) = self.http_cache.read_file_bytes( let Some(bytes) = self.http_cache.read_file_bytes(
&cache_key, &cache_key,
@ -230,11 +260,11 @@ impl FileFetcher {
return Ok(None); return Ok(None);
}; };
Ok(Some(File { Ok(Some(FileOrRedirect::File(File {
specifier: specifier.clone(), specifier: specifier.clone(),
maybe_headers: Some(headers), maybe_headers: Some(headers),
source: Arc::from(bytes), source: Arc::from(bytes),
})) })))
} }
/// Convert a data URL into a file, resulting in an error if the URL is /// Convert a data URL into a file, resulting in an error if the URL is
@ -280,51 +310,33 @@ impl FileFetcher {
}) })
} }
/// Asynchronously fetch remote source file specified by the URL following async fn fetch_remote_no_follow(
/// redirects.
///
/// **Note** this is a recursive method so it can't be "async", but needs to
/// return a `Pin<Box<..>>`.
fn fetch_remote(
&self, &self,
specifier: &ModuleSpecifier, specifier: &ModuleSpecifier,
permissions: PermissionsContainer, maybe_accept: Option<&str>,
redirect_limit: i64,
maybe_accept: Option<String>,
cache_setting: &CacheSetting, cache_setting: &CacheSetting,
maybe_checksum: Option<LoaderChecksum>, maybe_checksum: Option<&LoaderChecksum>,
) -> Pin<Box<dyn Future<Output = Result<File, AnyError>> + Send>> { ) -> Result<FileOrRedirect, AnyError> {
debug!("FileFetcher::fetch_remote() - specifier: {}", specifier); debug!(
if redirect_limit < 0 { "FileFetcher::fetch_remote_no_follow - specifier: {}",
return futures::future::err(custom_error("Http", "Too many redirects.")) specifier
.boxed(); );
}
if let Err(err) = permissions.check_specifier(specifier) {
return futures::future::err(err).boxed();
}
if self.should_use_cache(specifier, cache_setting) { if self.should_use_cache(specifier, cache_setting) {
match self.fetch_cached(specifier, maybe_checksum.clone(), redirect_limit) if let Some(file_or_redirect) =
self.fetch_cached_no_follow(specifier, maybe_checksum)?
{ {
Ok(Some(file)) => { return Ok(file_or_redirect);
return futures::future::ok(file).boxed();
}
Ok(None) => {}
Err(err) => {
return futures::future::err(err).boxed();
}
} }
} }
if *cache_setting == CacheSetting::Only { if *cache_setting == CacheSetting::Only {
return futures::future::err(custom_error( return Err(custom_error(
"NotCached", "NotCached",
format!( format!(
"Specifier not found in cache: \"{specifier}\", --cached-only is specified." "Specifier not found in cache: \"{specifier}\", --cached-only is specified."
), ),
)) ));
.boxed();
} }
let mut maybe_progress_guard = None; let mut maybe_progress_guard = None;
@ -346,12 +358,6 @@ impl FileFetcher {
.and_then(|key| self.http_cache.read_headers(&key).ok().flatten()) .and_then(|key| self.http_cache.read_headers(&key).ok().flatten())
.and_then(|headers| headers.get("etag").cloned()); .and_then(|headers| headers.get("etag").cloned());
let maybe_auth_token = self.auth_tokens.get(specifier); let maybe_auth_token = self.auth_tokens.get(specifier);
let specifier = specifier.clone();
let client = self.http_client.clone();
let file_fetcher = self.clone();
let cache_setting = cache_setting.clone();
// A single pass of fetch either yields code or yields a redirect, server
// error causes a single retry to avoid crashing hard on intermittent failures.
async fn handle_request_or_server_error( async fn handle_request_or_server_error(
retried: &mut bool, retried: &mut bool,
@ -372,90 +378,75 @@ impl FileFetcher {
} }
} }
async move { let mut maybe_etag = maybe_etag;
let mut maybe_etag = maybe_etag; let mut retried = false; // retry intermittent failures
let mut retried = false; let result = loop {
let result = loop { let result = match fetch_no_follow(
let result = match fetch_once( &self.http_client,
&client, FetchOnceArgs {
FetchOnceArgs { url: specifier.clone(),
url: specifier.clone(), maybe_accept: maybe_accept.map(ToOwned::to_owned),
maybe_accept: maybe_accept.clone(), maybe_etag: maybe_etag.clone(),
maybe_etag: maybe_etag.clone(), maybe_auth_token: maybe_auth_token.clone(),
maybe_auth_token: maybe_auth_token.clone(), maybe_progress_guard: maybe_progress_guard.as_ref(),
maybe_progress_guard: maybe_progress_guard.as_ref(), },
}, )
) .await?
.await? {
{ FetchOnceResult::NotModified => {
FetchOnceResult::NotModified => { let file_or_redirect =
let file = file_fetcher self.fetch_cached_no_follow(specifier, maybe_checksum)?;
.fetch_cached(&specifier, maybe_checksum.clone(), 10)?; match file_or_redirect {
match file { Some(file_or_redirect) => Ok(file_or_redirect),
Some(file) => Ok(file), None => {
None => { // Someone may have deleted the body from the cache since
// Someone may have deleted the body from the cache since // it's currently stored in a separate file from the headers,
// it's currently stored in a separate file from the headers, // so delete the etag and try again
// so delete the etag and try again if maybe_etag.is_some() {
if maybe_etag.is_some() { debug!("Cache body not found. Trying again without etag.");
debug!("Cache body not found. Trying again without etag."); maybe_etag = None;
maybe_etag = None; continue;
continue; } else {
} else { // should never happen
// should never happen bail!("Your deno cache directory is in an unrecoverable state. Please delete it and try again.")
bail!("Your deno cache directory is in an unrecoverable state. Please delete it and try again.")
}
} }
} }
} }
FetchOnceResult::Redirect(redirect_url, headers) => { }
file_fetcher.http_cache.set(&specifier, headers, &[])?; FetchOnceResult::Redirect(redirect_url, headers) => {
file_fetcher self.http_cache.set(specifier, headers, &[])?;
.fetch_remote( Ok(FileOrRedirect::Redirect(redirect_url))
&redirect_url, }
permissions, FetchOnceResult::Code(bytes, headers) => {
redirect_limit - 1, self.http_cache.set(specifier, headers.clone(), &bytes)?;
maybe_accept, if let Some(checksum) = &maybe_checksum {
&cache_setting, checksum.check_source(&bytes)?;
maybe_checksum,
)
.await
} }
FetchOnceResult::Code(bytes, headers) => { Ok(FileOrRedirect::File(File {
file_fetcher specifier: specifier.clone(),
.http_cache maybe_headers: Some(headers),
.set(&specifier, headers.clone(), &bytes)?; source: Arc::from(bytes),
if let Some(checksum) = &maybe_checksum { }))
checksum.check_source(&bytes)?; }
} FetchOnceResult::RequestError(err) => {
Ok(File { handle_request_or_server_error(&mut retried, specifier, err).await?;
specifier, continue;
maybe_headers: Some(headers), }
source: Arc::from(bytes), FetchOnceResult::ServerError(status) => {
}) handle_request_or_server_error(
} &mut retried,
FetchOnceResult::RequestError(err) => { specifier,
handle_request_or_server_error(&mut retried, &specifier, err) status.to_string(),
.await?; )
continue; .await?;
} continue;
FetchOnceResult::ServerError(status) => { }
handle_request_or_server_error(
&mut retried,
&specifier,
status.to_string(),
)
.await?;
continue;
}
};
break result;
}; };
break result;
};
drop(maybe_progress_guard); drop(maybe_progress_guard);
result result
}
.boxed()
} }
/// Returns if the cache should be used for a given specifier. /// Returns if the cache should be used for a given specifier.
@ -508,7 +499,7 @@ impl FileFetcher {
pub async fn fetch( pub async fn fetch(
&self, &self,
specifier: &ModuleSpecifier, specifier: &ModuleSpecifier,
permissions: PermissionsContainer, permissions: &PermissionsContainer,
) -> Result<File, AnyError> { ) -> Result<File, AnyError> {
self self
.fetch_with_options(FetchOptions { .fetch_with_options(FetchOptions {
@ -516,7 +507,6 @@ impl FileFetcher {
permissions, permissions,
maybe_accept: None, maybe_accept: None,
maybe_cache_setting: None, maybe_cache_setting: None,
maybe_checksum: None,
}) })
.await .await
} }
@ -525,20 +515,68 @@ impl FileFetcher {
&self, &self,
options: FetchOptions<'_>, options: FetchOptions<'_>,
) -> Result<File, AnyError> { ) -> Result<File, AnyError> {
self.fetch_with_options_and_max_redirect(options, 10).await
}
async fn fetch_with_options_and_max_redirect(
&self,
options: FetchOptions<'_>,
max_redirect: usize,
) -> Result<File, AnyError> {
let mut specifier = Cow::Borrowed(options.specifier);
for _ in 0..=max_redirect {
match self
.fetch_no_follow_with_options(FetchNoFollowOptions {
fetch_options: FetchOptions {
specifier: &specifier,
permissions: options.permissions,
maybe_accept: options.maybe_accept,
maybe_cache_setting: options.maybe_cache_setting,
},
maybe_checksum: None,
})
.await?
{
FileOrRedirect::File(file) => {
return Ok(file);
}
FileOrRedirect::Redirect(redirect_specifier) => {
specifier = Cow::Owned(redirect_specifier);
}
}
}
Err(custom_error("Http", "Too many redirects."))
}
/// Fetches without following redirects.
pub async fn fetch_no_follow_with_options(
&self,
options: FetchNoFollowOptions<'_>,
) -> Result<FileOrRedirect, AnyError> {
let maybe_checksum = options.maybe_checksum;
let options = options.fetch_options;
let specifier = options.specifier; let specifier = options.specifier;
debug!("FileFetcher::fetch() - specifier: {}", specifier); // note: this debug output is used by the tests
debug!(
"FileFetcher::fetch_no_follow_with_options - specifier: {}",
specifier
);
let scheme = get_validated_scheme(specifier)?; let scheme = get_validated_scheme(specifier)?;
options.permissions.check_specifier(specifier)?; options.permissions.check_specifier(specifier)?;
if let Some(file) = self.memory_files.get(specifier) { if let Some(file) = self.memory_files.get(specifier) {
Ok(file) Ok(FileOrRedirect::File(file))
} else if scheme == "file" { } else if scheme == "file" {
// we do not in memory cache files, as this would prevent files on the // we do not in memory cache files, as this would prevent files on the
// disk changing effecting things like workers and dynamic imports. // disk changing effecting things like workers and dynamic imports.
fetch_local(specifier) fetch_local(specifier).map(FileOrRedirect::File)
} else if scheme == "data" { } else if scheme == "data" {
self.fetch_data_url(specifier) self.fetch_data_url(specifier).map(FileOrRedirect::File)
} else if scheme == "blob" { } else if scheme == "blob" {
self.fetch_blob_url(specifier).await self
.fetch_blob_url(specifier)
.await
.map(FileOrRedirect::File)
} else if !self.allow_remote { } else if !self.allow_remote {
Err(custom_error( Err(custom_error(
"NoRemote", "NoRemote",
@ -546,13 +584,11 @@ impl FileFetcher {
)) ))
} else { } else {
self self
.fetch_remote( .fetch_remote_no_follow(
specifier, specifier,
options.permissions, options.maybe_accept,
10,
options.maybe_accept.map(String::from),
options.maybe_cache_setting.unwrap_or(&self.cache_setting), options.maybe_cache_setting.unwrap_or(&self.cache_setting),
options.maybe_checksum, maybe_checksum,
) )
.await .await
} }
@ -605,7 +641,7 @@ struct FetchOnceArgs<'a> {
/// yields Code(ResultPayload). /// yields Code(ResultPayload).
/// If redirect occurs, does not follow and /// If redirect occurs, does not follow and
/// yields Redirect(url). /// yields Redirect(url).
async fn fetch_once<'a>( async fn fetch_no_follow<'a>(
http_client: &HttpClient, http_client: &HttpClient,
args: FetchOnceArgs<'a>, args: FetchOnceArgs<'a>,
) -> Result<FetchOnceResult, AnyError> { ) -> Result<FetchOnceResult, AnyError> {
@ -746,25 +782,26 @@ mod tests {
async fn test_fetch(specifier: &ModuleSpecifier) -> (File, FileFetcher) { async fn test_fetch(specifier: &ModuleSpecifier) -> (File, FileFetcher) {
let (file_fetcher, _) = setup(CacheSetting::ReloadAll, None); let (file_fetcher, _) = setup(CacheSetting::ReloadAll, None);
let result = file_fetcher let result = file_fetcher
.fetch(specifier, PermissionsContainer::allow_all()) .fetch(specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
(result.unwrap(), file_fetcher) (result.unwrap(), file_fetcher)
} }
async fn test_fetch_remote( async fn test_fetch_options_remote(
specifier: &ModuleSpecifier, specifier: &ModuleSpecifier,
) -> (File, HashMap<String, String>) { ) -> (File, HashMap<String, String>) {
let _http_server_guard = test_util::http_server(); let _http_server_guard = test_util::http_server();
let (file_fetcher, _) = setup(CacheSetting::ReloadAll, None); let (file_fetcher, _) = setup(CacheSetting::ReloadAll, None);
let result: Result<File, AnyError> = file_fetcher let result: Result<File, AnyError> = file_fetcher
.fetch_remote( .fetch_with_options_and_max_redirect(
specifier, FetchOptions {
PermissionsContainer::allow_all(), specifier,
permissions: &PermissionsContainer::allow_all(),
maybe_accept: None,
maybe_cache_setting: Some(&file_fetcher.cache_setting),
},
1, 1,
None,
&file_fetcher.cache_setting,
None,
) )
.await; .await;
let cache_key = file_fetcher.http_cache.cache_item_key(specifier).unwrap(); let cache_key = file_fetcher.http_cache.cache_item_key(specifier).unwrap();
@ -788,7 +825,7 @@ mod tests {
) { ) {
let url_str = format!("http://127.0.0.1:4545/encoding/{fixture}"); let url_str = format!("http://127.0.0.1:4545/encoding/{fixture}");
let specifier = resolve_url(&url_str).unwrap(); let specifier = resolve_url(&url_str).unwrap();
let (file, headers) = test_fetch_remote(&specifier).await; let (file, headers) = test_fetch_options_remote(&specifier).await;
let (media_type, maybe_charset) = let (media_type, maybe_charset) =
deno_graph::source::resolve_media_type_and_charset_from_headers( deno_graph::source::resolve_media_type_and_charset_from_headers(
&specifier, &specifier,
@ -857,7 +894,7 @@ mod tests {
file_fetcher.insert_memory_files(file.clone()); file_fetcher.insert_memory_files(file.clone());
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let result_file = result.unwrap(); let result_file = result.unwrap();
@ -870,7 +907,7 @@ mod tests {
let specifier = resolve_url("data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo=").unwrap(); let specifier = resolve_url("data:application/typescript;base64,ZXhwb3J0IGNvbnN0IGEgPSAiYSI7CgpleHBvcnQgZW51bSBBIHsKICBBLAogIEIsCiAgQywKfQo=").unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap().into_text_decoded().unwrap(); let file = result.unwrap().into_text_decoded().unwrap();
@ -901,7 +938,7 @@ mod tests {
); );
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap().into_text_decoded().unwrap(); let file = result.unwrap().into_text_decoded().unwrap();
@ -923,7 +960,7 @@ mod tests {
ModuleSpecifier::parse("http://localhost:4545/subdir/mod2.ts").unwrap(); ModuleSpecifier::parse("http://localhost:4545/subdir/mod2.ts").unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap().into_text_decoded().unwrap(); let file = result.unwrap().into_text_decoded().unwrap();
@ -943,7 +980,7 @@ mod tests {
.unwrap(); .unwrap();
let result = file_fetcher_01 let result = file_fetcher_01
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap().into_text_decoded().unwrap(); let file = result.unwrap().into_text_decoded().unwrap();
@ -969,7 +1006,7 @@ mod tests {
.unwrap(); .unwrap();
let result = file_fetcher_02 let result = file_fetcher_02
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap().into_text_decoded().unwrap(); let file = result.unwrap().into_text_decoded().unwrap();
@ -994,7 +1031,7 @@ mod tests {
None, None,
); );
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap().into_text_decoded().unwrap(); let file = result.unwrap().into_text_decoded().unwrap();
@ -1027,7 +1064,7 @@ mod tests {
); );
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let cache_key = let cache_key =
@ -1063,7 +1100,7 @@ mod tests {
None, None,
); );
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
@ -1102,7 +1139,7 @@ mod tests {
.unwrap(); .unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap(); let file = result.unwrap();
@ -1143,7 +1180,7 @@ mod tests {
.unwrap(); .unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap(); let file = result.unwrap();
@ -1203,7 +1240,7 @@ mod tests {
); );
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
@ -1242,7 +1279,7 @@ mod tests {
None, None,
); );
let result = file_fetcher let result = file_fetcher
.fetch(&redirected_specifier, PermissionsContainer::allow_all()) .fetch(&redirected_specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
@ -1280,33 +1317,35 @@ mod tests {
.unwrap(); .unwrap();
let result = file_fetcher let result = file_fetcher
.fetch_remote( .fetch_with_options_and_max_redirect(
&specifier, FetchOptions {
PermissionsContainer::allow_all(), specifier: &specifier,
permissions: &PermissionsContainer::allow_all(),
maybe_accept: None,
maybe_cache_setting: Some(&file_fetcher.cache_setting),
},
2, 2,
None,
&file_fetcher.cache_setting,
None,
) )
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let result = file_fetcher let result = file_fetcher
.fetch_remote( .fetch_with_options_and_max_redirect(
&specifier, FetchOptions {
PermissionsContainer::allow_all(), specifier: &specifier,
permissions: &PermissionsContainer::allow_all(),
maybe_accept: None,
maybe_cache_setting: Some(&file_fetcher.cache_setting),
},
1, 1,
None,
&file_fetcher.cache_setting,
None,
) )
.await; .await;
assert!(result.is_err()); assert!(result.is_err());
let result = file_fetcher.fetch_cached(&specifier, None, 2); let result = file_fetcher.fetch_cached(&specifier, 2);
assert!(result.is_ok()); assert!(result.is_ok());
let result = file_fetcher.fetch_cached(&specifier, None, 1); let result = file_fetcher.fetch_cached(&specifier, 1);
assert!(result.is_err()); assert!(result.is_err());
} }
@ -1323,7 +1362,7 @@ mod tests {
.unwrap(); .unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap(); let file = result.unwrap();
@ -1369,7 +1408,7 @@ mod tests {
resolve_url("http://localhost:4545/run/002_hello.ts").unwrap(); resolve_url("http://localhost:4545/run/002_hello.ts").unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_err()); assert!(result.is_err());
let err = result.unwrap_err(); let err = result.unwrap_err();
@ -1402,7 +1441,7 @@ mod tests {
resolve_url("http://localhost:4545/run/002_hello.ts").unwrap(); resolve_url("http://localhost:4545/run/002_hello.ts").unwrap();
let result = file_fetcher_01 let result = file_fetcher_01
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_err()); assert!(result.is_err());
let err = result.unwrap_err(); let err = result.unwrap_err();
@ -1410,12 +1449,12 @@ mod tests {
assert_eq!(get_custom_error_class(&err), Some("NotCached")); assert_eq!(get_custom_error_class(&err), Some("NotCached"));
let result = file_fetcher_02 let result = file_fetcher_02
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let result = file_fetcher_01 let result = file_fetcher_01
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
} }
@ -1427,7 +1466,7 @@ mod tests {
let specifier = ModuleSpecifier::from_file_path(&fixture_path).unwrap(); let specifier = ModuleSpecifier::from_file_path(&fixture_path).unwrap();
fs::write(fixture_path.clone(), r#"console.log("hello deno");"#).unwrap(); fs::write(fixture_path.clone(), r#"console.log("hello deno");"#).unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap().into_text_decoded().unwrap(); let file = result.unwrap().into_text_decoded().unwrap();
@ -1435,7 +1474,7 @@ mod tests {
fs::write(fixture_path, r#"console.log("goodbye deno");"#).unwrap(); fs::write(fixture_path, r#"console.log("goodbye deno");"#).unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap().into_text_decoded().unwrap(); let file = result.unwrap().into_text_decoded().unwrap();
@ -1451,7 +1490,7 @@ mod tests {
let specifier = let specifier =
ModuleSpecifier::parse("http://localhost:4545/dynamic").unwrap(); ModuleSpecifier::parse("http://localhost:4545/dynamic").unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap(); let file = result.unwrap();
@ -1460,7 +1499,7 @@ mod tests {
let (file_fetcher, _) = let (file_fetcher, _) =
setup(CacheSetting::RespectHeaders, Some(temp_dir.clone())); setup(CacheSetting::RespectHeaders, Some(temp_dir.clone()));
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap(); let file = result.unwrap();
@ -1478,7 +1517,7 @@ mod tests {
let specifier = let specifier =
ModuleSpecifier::parse("http://localhost:4545/dynamic_cache").unwrap(); ModuleSpecifier::parse("http://localhost:4545/dynamic_cache").unwrap();
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap(); let file = result.unwrap();
@ -1487,7 +1526,7 @@ mod tests {
let (file_fetcher, _) = let (file_fetcher, _) =
setup(CacheSetting::RespectHeaders, Some(temp_dir.clone())); setup(CacheSetting::RespectHeaders, Some(temp_dir.clone()));
let result = file_fetcher let result = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await; .await;
assert!(result.is_ok()); assert!(result.is_ok());
let file = result.unwrap(); let file = result.unwrap();
@ -1551,7 +1590,7 @@ mod tests {
// Relies on external http server. See target/debug/test_server // Relies on external http server. See target/debug/test_server
let url = Url::parse("http://127.0.0.1:4545/assets/fixture.json").unwrap(); let url = Url::parse("http://127.0.0.1:4545/assets/fixture.json").unwrap();
let client = create_test_client(); let client = create_test_client();
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -1579,7 +1618,7 @@ mod tests {
let url = Url::parse("http://127.0.0.1:4545/run/import_compression/gziped") let url = Url::parse("http://127.0.0.1:4545/run/import_compression/gziped")
.unwrap(); .unwrap();
let client = create_test_client(); let client = create_test_client();
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -1608,7 +1647,7 @@ mod tests {
let _http_server_guard = test_util::http_server(); let _http_server_guard = test_util::http_server();
let url = Url::parse("http://127.0.0.1:4545/etag_script.ts").unwrap(); let url = Url::parse("http://127.0.0.1:4545/etag_script.ts").unwrap();
let client = create_test_client(); let client = create_test_client();
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url: url.clone(), url: url.clone(),
@ -1631,7 +1670,7 @@ mod tests {
panic!(); panic!();
} }
let res = fetch_once( let res = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -1652,7 +1691,7 @@ mod tests {
let url = Url::parse("http://127.0.0.1:4545/run/import_compression/brotli") let url = Url::parse("http://127.0.0.1:4545/run/import_compression/brotli")
.unwrap(); .unwrap();
let client = create_test_client(); let client = create_test_client();
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -1683,7 +1722,7 @@ mod tests {
// Relies on external http server. See target/debug/test_server // Relies on external http server. See target/debug/test_server
let url = Url::parse("http://127.0.0.1:4545/echo_accept").unwrap(); let url = Url::parse("http://127.0.0.1:4545/echo_accept").unwrap();
let client = create_test_client(); let client = create_test_client();
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -1702,7 +1741,7 @@ mod tests {
} }
#[tokio::test] #[tokio::test]
async fn test_fetch_once_with_redirect() { async fn test_fetch_no_follow_with_redirect() {
let _http_server_guard = test_util::http_server(); let _http_server_guard = test_util::http_server();
// Relies on external http server. See target/debug/test_server // Relies on external http server. See target/debug/test_server
let url = Url::parse("http://127.0.0.1:4546/assets/fixture.json").unwrap(); let url = Url::parse("http://127.0.0.1:4546/assets/fixture.json").unwrap();
@ -1710,7 +1749,7 @@ mod tests {
let target_url = let target_url =
Url::parse("http://localhost:4545/assets/fixture.json").unwrap(); Url::parse("http://localhost:4545/assets/fixture.json").unwrap();
let client = create_test_client(); let client = create_test_client();
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -1747,7 +1786,7 @@ mod tests {
) )
.unwrap(), .unwrap(),
); );
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -1796,7 +1835,7 @@ mod tests {
.unwrap(), .unwrap(),
); );
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -1860,7 +1899,7 @@ mod tests {
.unwrap(), .unwrap(),
); );
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -1915,7 +1954,7 @@ mod tests {
) )
.unwrap(), .unwrap(),
); );
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -1958,7 +1997,7 @@ mod tests {
) )
.unwrap(), .unwrap(),
); );
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url: url.clone(), url: url.clone(),
@ -1982,7 +2021,7 @@ mod tests {
panic!(); panic!();
} }
let res = fetch_once( let res = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -2018,7 +2057,7 @@ mod tests {
) )
.unwrap(), .unwrap(),
); );
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -2049,7 +2088,7 @@ mod tests {
let url_str = "http://127.0.0.1:4545/bad_redirect"; let url_str = "http://127.0.0.1:4545/bad_redirect";
let url = Url::parse(url_str).unwrap(); let url = Url::parse(url_str).unwrap();
let client = create_test_client(); let client = create_test_client();
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -2072,7 +2111,7 @@ mod tests {
let url_str = "http://127.0.0.1:4545/server_error"; let url_str = "http://127.0.0.1:4545/server_error";
let url = Url::parse(url_str).unwrap(); let url = Url::parse(url_str).unwrap();
let client = create_test_client(); let client = create_test_client();
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,
@ -2097,7 +2136,7 @@ mod tests {
let url_str = "http://127.0.0.1:9999/"; let url_str = "http://127.0.0.1:9999/";
let url = Url::parse(url_str).unwrap(); let url = Url::parse(url_str).unwrap();
let client = create_test_client(); let client = create_test_client();
let result = fetch_once( let result = fetch_no_follow(
&client, &client,
FetchOnceArgs { FetchOnceArgs {
url, url,

View file

@ -451,17 +451,17 @@ impl ModuleGraphBuilder {
options.roots, options.roots,
loader.as_mut_loader(), loader.as_mut_loader(),
deno_graph::BuildOptions { deno_graph::BuildOptions {
is_dynamic: options.is_dynamic,
jsr_url_provider: &CliJsrUrlProvider,
passthrough_jsr_specifiers: false,
executor: Default::default(),
imports: maybe_imports, imports: maybe_imports,
resolver: Some(graph_resolver), is_dynamic: options.is_dynamic,
passthrough_jsr_specifiers: false,
workspace_members: &workspace_members,
executor: Default::default(),
file_system: &DenoGraphFsAdapter(self.fs.as_ref()), file_system: &DenoGraphFsAdapter(self.fs.as_ref()),
jsr_url_provider: &CliJsrUrlProvider,
npm_resolver: Some(graph_npm_resolver), npm_resolver: Some(graph_npm_resolver),
module_analyzer: &analyzer, module_analyzer: &analyzer,
reporter: maybe_file_watcher_reporter, reporter: maybe_file_watcher_reporter,
workspace_members: &workspace_members, resolver: Some(graph_resolver),
}, },
) )
.await .await

View file

@ -234,7 +234,7 @@ impl JsrFetchResolver {
let meta_url = jsr_url().join(&format!("{}/meta.json", name)).ok()?; let meta_url = jsr_url().join(&format!("{}/meta.json", name)).ok()?;
let file = self let file = self
.file_fetcher .file_fetcher
.fetch(&meta_url, PermissionsContainer::allow_all()) .fetch(&meta_url, &PermissionsContainer::allow_all())
.await .await
.ok()?; .ok()?;
serde_json::from_slice::<JsrPackageInfo>(&file.source).ok() serde_json::from_slice::<JsrPackageInfo>(&file.source).ok()
@ -257,7 +257,7 @@ impl JsrFetchResolver {
.ok()?; .ok()?;
let file = self let file = self
.file_fetcher .file_fetcher
.fetch(&meta_url, PermissionsContainer::allow_all()) .fetch(&meta_url, &PermissionsContainer::allow_all())
.await .await
.ok()?; .ok()?;
partial_jsr_package_version_info_from_slice(&file.source).ok() partial_jsr_package_version_info_from_slice(&file.source).ok()

View file

@ -1393,7 +1393,7 @@ impl ConfigData {
if import_map_value.is_none() { if import_map_value.is_none() {
if let Some(file_fetcher) = file_fetcher { if let Some(file_fetcher) = file_fetcher {
let fetch_result = file_fetcher let fetch_result = file_fetcher
.fetch(specifier, PermissionsContainer::allow_all()) .fetch(specifier, &PermissionsContainer::allow_all())
.await; .await;
let value_result = fetch_result.and_then(|f| { let value_result = fetch_result.and_then(|f| {
serde_json::from_slice::<Value>(&f.source).map_err(|e| e.into()) serde_json::from_slice::<Value>(&f.source).map_err(|e| e.into())

View file

@ -51,7 +51,7 @@ impl PackageSearchApi for CliJsrSearchApi {
search_url.query_pairs_mut().append_pair("query", query); search_url.query_pairs_mut().append_pair("query", query);
let file = self let file = self
.file_fetcher .file_fetcher
.fetch(&search_url, PermissionsContainer::allow_all()) .fetch(&search_url, &PermissionsContainer::allow_all())
.await? .await?
.into_text_decoded()?; .into_text_decoded()?;
let names = Arc::new(parse_jsr_search_response(&file.source)?); let names = Arc::new(parse_jsr_search_response(&file.source)?);

View file

@ -48,7 +48,7 @@ impl PackageSearchApi for CliNpmSearchApi {
.append_pair("text", &format!("{} boost-exact:false", query)); .append_pair("text", &format!("{} boost-exact:false", query));
let file = self let file = self
.file_fetcher .file_fetcher
.fetch(&search_url, PermissionsContainer::allow_all()) .fetch(&search_url, &PermissionsContainer::allow_all())
.await? .await?
.into_text_decoded()?; .into_text_decoded()?;
let names = Arc::new(parse_npm_search_response(&file.source)?); let names = Arc::new(parse_npm_search_response(&file.source)?);

View file

@ -512,10 +512,9 @@ impl ModuleRegistry {
.file_fetcher .file_fetcher
.fetch_with_options(FetchOptions { .fetch_with_options(FetchOptions {
specifier, specifier,
permissions: PermissionsContainer::allow_all(), permissions: &PermissionsContainer::allow_all(),
maybe_accept: Some("application/vnd.deno.reg.v2+json, application/vnd.deno.reg.v1+json;q=0.9, application/json;q=0.8"), maybe_accept: Some("application/vnd.deno.reg.v2+json, application/vnd.deno.reg.v1+json;q=0.9, application/json;q=0.8"),
maybe_cache_setting: None, maybe_cache_setting: None,
maybe_checksum: None,
}) })
.await; .await;
// if there is an error fetching, we will cache an empty file, so that // if there is an error fetching, we will cache an empty file, so that
@ -609,7 +608,7 @@ impl ModuleRegistry {
.ok()?; .ok()?;
let file = self let file = self
.file_fetcher .file_fetcher
.fetch(&endpoint, PermissionsContainer::allow_all()) .fetch(&endpoint, &PermissionsContainer::allow_all())
.await .await
.ok()? .ok()?
.into_text_decoded() .into_text_decoded()
@ -975,7 +974,7 @@ impl ModuleRegistry {
let specifier = Url::parse(url).ok()?; let specifier = Url::parse(url).ok()?;
let file = self let file = self
.file_fetcher .file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await .await
.ok()? .ok()?
.into_text_decoded() .into_text_decoded()
@ -1034,7 +1033,7 @@ impl ModuleRegistry {
let specifier = ModuleSpecifier::parse(url).ok()?; let specifier = ModuleSpecifier::parse(url).ok()?;
let file = self let file = self
.file_fetcher .file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await .await
.map_err(|err| { .map_err(|err| {
error!( error!(
@ -1072,7 +1071,7 @@ impl ModuleRegistry {
.ok()?; .ok()?;
let file = self let file = self
.file_fetcher .file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await .await
.map_err(|err| { .map_err(|err| {
error!( error!(

View file

@ -142,7 +142,7 @@ impl NpmFetchResolver {
let info_url = npm_registry_url().join(name).ok()?; let info_url = npm_registry_url().join(name).ok()?;
let file = self let file = self
.file_fetcher .file_fetcher
.fetch(&info_url, PermissionsContainer::allow_all()) .fetch(&info_url, &PermissionsContainer::allow_all())
.await .await
.ok()?; .ok()?;
serde_json::from_slice::<NpmPackageInfo>(&file.source).ok() serde_json::from_slice::<NpmPackageInfo>(&file.source).ok()

View file

@ -529,7 +529,7 @@ pub async fn cover_files(
file_fetcher.get_source(&module_specifier) file_fetcher.get_source(&module_specifier)
} else { } else {
file_fetcher file_fetcher
.fetch_cached(&module_specifier, None, 10) .fetch_cached(&module_specifier, 10)
.with_context(|| { .with_context(|| {
format!("Failed to fetch \"{module_specifier}\" from cache.") format!("Failed to fetch \"{module_specifier}\" from cache.")
})? })?

View file

@ -54,17 +54,17 @@ async fn generate_doc_nodes_for_builtin_types(
vec![source_file_specifier.clone()], vec![source_file_specifier.clone()],
&loader, &loader,
deno_graph::BuildOptions { deno_graph::BuildOptions {
module_analyzer: analyzer,
file_system: &NullFileSystem,
is_dynamic: false,
imports: Vec::new(), imports: Vec::new(),
executor: Default::default(), is_dynamic: false,
jsr_url_provider: Default::default(),
passthrough_jsr_specifiers: false, passthrough_jsr_specifiers: false,
workspace_members: &[],
executor: Default::default(),
file_system: &NullFileSystem,
jsr_url_provider: Default::default(),
module_analyzer: analyzer,
npm_resolver: None, npm_resolver: None,
reporter: None, reporter: None,
resolver: None, resolver: None,
workspace_members: &[],
}, },
) )
.await; .await;

View file

@ -145,7 +145,7 @@ async fn read_eval_file(
deno_core::resolve_url_or_path(eval_file, cli_options.initial_cwd())?; deno_core::resolve_url_or_path(eval_file, cli_options.initial_cwd())?;
let file = file_fetcher let file = file_fetcher
.fetch(&specifier, PermissionsContainer::allow_all()) .fetch(&specifier, &PermissionsContainer::allow_all())
.await?; .await?;
Ok(file.into_text_decoded()?.source) Ok(file.into_text_decoded()?.source)

View file

@ -1277,7 +1277,7 @@ async fn fetch_inline_files(
for specifier in specifiers { for specifier in specifiers {
let fetch_permissions = PermissionsContainer::allow_all(); let fetch_permissions = PermissionsContainer::allow_all();
let file = file_fetcher let file = file_fetcher
.fetch(&specifier, fetch_permissions) .fetch(&specifier, &fetch_permissions)
.await? .await?
.into_text_decoded()?; .into_text_decoded()?;
@ -1688,7 +1688,7 @@ async fn fetch_specifiers_with_test_mode(
for (specifier, mode) in &mut specifiers_with_mode { for (specifier, mode) in &mut specifiers_with_mode {
let file = file_fetcher let file = file_fetcher
.fetch(specifier, PermissionsContainer::allow_all()) .fetch(specifier, &PermissionsContainer::allow_all())
.await?; .await?;
let (media_type, _) = file.resolve_media_type_and_charset(); let (media_type, _) = file.resolve_media_type_and_charset();

View file

@ -116,7 +116,13 @@ impl Loader for TestLoader {
specifier: &ModuleSpecifier, specifier: &ModuleSpecifier,
_options: deno_graph::source::LoadOptions, _options: deno_graph::source::LoadOptions,
) -> LoadFuture { ) -> LoadFuture {
let specifier = self.redirects.get(specifier).unwrap_or(specifier); if let Some(redirect) = self.redirects.get(specifier) {
return Box::pin(futures::future::ready(Ok(Some(
LoadResponse::Redirect {
specifier: redirect.clone(),
},
))));
}
let result = self.files.get(specifier).map(|result| match result { let result = self.files.get(specifier).map(|result| match result {
Ok(result) => Ok(LoadResponse::Module { Ok(result) => Ok(LoadResponse::Module {
specifier: specifier.clone(), specifier: specifier.clone(),

View file

@ -280,7 +280,7 @@ fn conditionally_loads_type_graph() {
.new_command() .new_command()
.args("bench --reload -L debug run/type_directives_js_main.js") .args("bench --reload -L debug run/type_directives_js_main.js")
.run(); .run();
output.assert_matches_text("[WILDCARD] - FileFetcher::fetch() - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]"); output.assert_matches_text("[WILDCARD] - FileFetcher::fetch_no_follow_with_options - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]");
let output = context let output = context
.new_command() .new_command()
.args("bench --reload -L debug --no-check run/type_directives_js_main.js") .args("bench --reload -L debug --no-check run/type_directives_js_main.js")

View file

@ -177,5 +177,5 @@ fn loads_type_graph() {
.new_command() .new_command()
.args("cache --reload -L debug run/type_directives_js_main.js") .args("cache --reload -L debug run/type_directives_js_main.js")
.run(); .run();
output.assert_matches_text("[WILDCARD] - FileFetcher::fetch() - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]"); output.assert_matches_text("[WILDCARD] - FileFetcher::fetch_no_follow_with_options - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]");
} }

View file

@ -1686,7 +1686,7 @@ fn type_directives_js_main() {
.new_command() .new_command()
.args("run --reload -L debug --check run/type_directives_js_main.js") .args("run --reload -L debug --check run/type_directives_js_main.js")
.run(); .run();
output.assert_matches_text("[WILDCARD] - FileFetcher::fetch() - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]"); output.assert_matches_text("[WILDCARD] - FileFetcher::fetch_no_follow_with_options - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]");
let output = context let output = context
.new_command() .new_command()
.args("run --reload -L debug run/type_directives_js_main.js") .args("run --reload -L debug run/type_directives_js_main.js")

View file

@ -668,7 +668,7 @@ fn conditionally_loads_type_graph() {
.new_command() .new_command()
.args("test --reload -L debug run/type_directives_js_main.js") .args("test --reload -L debug run/type_directives_js_main.js")
.run(); .run();
output.assert_matches_text("[WILDCARD] - FileFetcher::fetch() - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]"); output.assert_matches_text("[WILDCARD] - FileFetcher::fetch_no_follow_with_options - specifier: file:///[WILDCARD]/subdir/type_reference.d.ts[WILDCARD]");
let output = context let output = context
.new_command() .new_command()
.args("test --reload -L debug --no-check run/type_directives_js_main.js") .args("test --reload -L debug --no-check run/type_directives_js_main.js")

View file

@ -0,0 +1,4 @@
{
"args": "info --json main.ts",
"output": "main.out"
}

View file

@ -0,0 +1,51 @@
Download http://localhost:4548/subdir/redirects/redirect1.js
Download http://localhost:4546/subdir/redirects/redirect1.js
Download http://localhost:4545/subdir/redirects/redirect1.js
{
"roots": [
"file:///[WILDLINE]/multiple_redirects/main.ts"
],
"modules": [
{
"kind": "esm",
"dependencies": [
{
"specifier": "http://localhost:4548/subdir/redirects/redirect1.js",
"code": {
"specifier": "http://localhost:4548/subdir/redirects/redirect1.js",
"span": {
"start": {
"line": 0,
"character": 22
},
"end": {
"line": 0,
"character": 75
}
}
}
}
],
"local": "[WILDLINE]main.ts",
"emit": null,
"map": null,
"size": 97,
"mediaType": "TypeScript",
"specifier": "file:///[WILDLINE]/multiple_redirects/main.ts"
},
{
"kind": "esm",
"local": "[WILDLINE]",
"emit": null,
"map": null,
"size": 27,
"mediaType": "JavaScript",
"specifier": "http://localhost:4545/subdir/redirects/redirect1.js"
}
],
"redirects": {
"http://localhost:4546/subdir/redirects/redirect1.js": "http://localhost:4545/subdir/redirects/redirect1.js",
"http://localhost:4548/subdir/redirects/redirect1.js": "http://localhost:4546/subdir/redirects/redirect1.js"
},
"npmPackages": {}
}

View file

@ -0,0 +1,2 @@
import { value } from "http://localhost:4548/subdir/redirects/redirect1.js";
console.log(value);