summaryrefslogtreecommitdiff
path: root/cli/file_fetcher.rs
diff options
context:
space:
mode:
authorNayeem Rahman <muhammed.9939@gmail.com>2019-12-03 22:48:53 +0000
committerRy Dahl <ry@tinyclouds.org>2019-12-03 17:48:53 -0500
commit91da410fc3bfde76c3c8930c6f8bfd4d5f9b974e (patch)
tree30e8345ddba04915fc9417d0855a0ca08feb41ac /cli/file_fetcher.rs
parentee013102ff4ce75c1068b6e771ed120fc32a849d (diff)
feat: Add --no-remote, rename --no-fetch to --cached-only (#3417)
Diffstat (limited to 'cli/file_fetcher.rs')
-rw-r--r--cli/file_fetcher.rs135
1 files changed, 93 insertions, 42 deletions
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index b156e98fd..5c68b3386 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -74,7 +74,8 @@ pub struct SourceFileFetcher {
source_file_cache: SourceFileCache,
cache_blacklist: Vec<String>,
use_disk_cache: bool,
- no_remote_fetch: bool,
+ no_remote: bool,
+ cached_only: bool,
}
impl SourceFileFetcher {
@@ -83,7 +84,8 @@ impl SourceFileFetcher {
progress: Progress,
use_disk_cache: bool,
cache_blacklist: Vec<String>,
- no_remote_fetch: bool,
+ no_remote: bool,
+ cached_only: bool,
) -> std::io::Result<Self> {
let file_fetcher = Self {
deps_cache,
@@ -91,7 +93,8 @@ impl SourceFileFetcher {
source_file_cache: SourceFileCache::default(),
cache_blacklist,
use_disk_cache,
- no_remote_fetch,
+ no_remote,
+ cached_only,
};
Ok(file_fetcher)
@@ -123,10 +126,10 @@ impl SourceFileFetcher {
// If file is not in memory cache check if it can be found
// in local cache - which effectively means trying to fetch
- // using "--no-fetch" flag. We can safely block on this
+ // using "--cached-only" flag. We can safely block on this
// future, because it doesn't do any asynchronous action
// it that path.
- let fut = self.get_source_file_async(specifier.as_url(), true, true);
+ let fut = self.get_source_file_async(specifier.as_url(), true, false, true);
futures::executor::block_on(fut).ok()
}
@@ -152,21 +155,31 @@ impl SourceFileFetcher {
.get_source_file_async(
&module_url,
self.use_disk_cache,
- self.no_remote_fetch,
+ self.no_remote,
+ self.cached_only,
)
.then(move |result| {
let mut out = match result.map_err(|err| {
- if err.kind() == ErrorKind::NotFound {
- let msg = if let Some(referrer) = maybe_referrer {
- format!(
- "Cannot resolve module \"{}\" from \"{}\"",
- module_url.to_string(),
- referrer
- )
- } else {
- format!("Cannot resolve module \"{}\"", module_url.to_string())
- };
+ let err_kind = err.kind();
+ let referrer_suffix = if let Some(referrer) = maybe_referrer {
+ format!(" from \"{}\"", referrer)
+ } else {
+ "".to_owned()
+ };
+ if err_kind == ErrorKind::NotFound {
+ let msg = format!(
+ "Cannot resolve module \"{}\"{}",
+ module_url.to_string(),
+ referrer_suffix
+ );
DenoError::new(ErrorKind::NotFound, msg).into()
+ } else if err_kind == ErrorKind::PermissionDenied {
+ let msg = format!(
+ "Cannot find module \"{}\"{} in cache, --cached-only is specified",
+ module_url.to_string(),
+ referrer_suffix
+ );
+ DenoError::new(ErrorKind::PermissionDenied, msg).into()
} else {
err
}
@@ -196,13 +209,16 @@ impl SourceFileFetcher {
///
/// If `use_disk_cache` is true then remote files are fetched from disk cache.
///
- /// If `no_remote_fetch` is true then if remote file is not found it disk
- /// cache this method will fail.
+ /// If `no_remote` is true then this method will fail for remote files.
+ ///
+ /// If `cached_only` is true then this method will fail for remote files
+ /// not already cached.
fn get_source_file_async(
self: &Self,
module_url: &Url,
use_disk_cache: bool,
- no_remote_fetch: bool,
+ no_remote: bool,
+ cached_only: bool,
) -> impl Future<Output = Result<SourceFile, ErrBox>> {
let url_scheme = module_url.scheme();
let is_local_file = url_scheme == "file";
@@ -224,11 +240,25 @@ impl SourceFileFetcher {
}
}
+ // The file is remote, fail if `no_remote` is true.
+ if no_remote {
+ return Either::Left(futures::future::err(
+ std::io::Error::new(
+ std::io::ErrorKind::NotFound,
+ format!(
+ "Not allowed to get remote file '{}'",
+ module_url.to_string()
+ ),
+ )
+ .into(),
+ ));
+ }
+
// Fetch remote file and cache on-disk for subsequent access
Either::Right(self.fetch_remote_source_async(
&module_url,
use_disk_cache,
- no_remote_fetch,
+ cached_only,
10,
))
}
@@ -327,7 +357,7 @@ impl SourceFileFetcher {
self: &Self,
module_url: &Url,
use_disk_cache: bool,
- no_remote_fetch: bool,
+ cached_only: bool,
redirect_limit: i64,
) -> Pin<Box<SourceFileFuture>> {
if redirect_limit < 0 {
@@ -352,11 +382,11 @@ impl SourceFileFetcher {
}
// If file wasn't found in cache check if we can fetch it
- if no_remote_fetch {
+ if cached_only {
// We can't fetch remote file - bail out
return futures::future::err(
std::io::Error::new(
- std::io::ErrorKind::NotFound,
+ std::io::ErrorKind::PermissionDenied,
format!(
"cannot find remote file '{}' in cache",
module_url.to_string()
@@ -391,7 +421,7 @@ impl SourceFileFetcher {
Either::Left(dir.fetch_remote_source_async(
&new_module_url,
use_disk_cache,
- no_remote_fetch,
+ cached_only,
redirect_limit - 1,
))
}
@@ -690,6 +720,7 @@ mod tests {
true,
vec![],
false,
+ false,
)
.expect("setup fail")
}
@@ -843,7 +874,7 @@ mod tests {
let headers_file_name_3 = headers_file_name.clone();
let fut = fetcher
- .get_source_file_async(&module_url, true, false)
+ .get_source_file_async(&module_url, true, false, false)
.then(move |result| {
assert!(result.is_ok());
let r = result.unwrap();
@@ -860,7 +891,7 @@ mod tests {
&headers_file_name_1,
"{ \"mime_type\": \"text/javascript\" }",
);
- fetcher_1.get_source_file_async(&module_url, true, false)
+ fetcher_1.get_source_file_async(&module_url, true, false, false)
})
.then(move |result2| {
assert!(result2.is_ok());
@@ -886,7 +917,7 @@ mod tests {
Some("application/json".to_owned()),
None,
);
- fetcher_2.get_source_file_async(&module_url_1, true, false)
+ fetcher_2.get_source_file_async(&module_url_1, true, false, false)
})
.then(move |result3| {
assert!(result3.is_ok());
@@ -905,7 +936,7 @@ mod tests {
// let's create fresh instance of DenoDir (simulating another freshh Deno process)
// and don't use cache
let fetcher = setup_file_fetcher(temp_dir.path());
- fetcher.get_source_file_async(&module_url_2, false, false)
+ fetcher.get_source_file_async(&module_url_2, false, false, false)
})
.then(move |result4| {
assert!(result4.is_ok());
@@ -940,7 +971,7 @@ mod tests {
);
let fut = fetcher
- .get_source_file_async(&module_url, true, false)
+ .get_source_file_async(&module_url, true, false, false)
.then(move |result| {
assert!(result.is_ok());
let r = result.unwrap();
@@ -962,7 +993,7 @@ mod tests {
Some("text/typescript".to_owned()),
None,
);
- fetcher.get_source_file_async(&module_url, true, false)
+ fetcher.get_source_file_async(&module_url, true, false, false)
})
.then(move |result2| {
assert!(result2.is_ok());
@@ -977,7 +1008,7 @@ mod tests {
// let's create fresh instance of DenoDir (simulating another freshh Deno process)
// and don't use cache
let fetcher = setup_file_fetcher(temp_dir.path());
- fetcher.get_source_file_async(&module_url_1, false, false)
+ fetcher.get_source_file_async(&module_url_1, false, false, false)
})
.then(move |result3| {
assert!(result3.is_ok());
@@ -1077,7 +1108,7 @@ mod tests {
// Test basic follow and headers recording
let fut = fetcher
- .get_source_file_async(&redirect_module_url, true, false)
+ .get_source_file_async(&redirect_module_url, true, false, false)
.then(move |result| {
assert!(result.is_ok());
let mod_meta = result.unwrap();
@@ -1138,7 +1169,7 @@ mod tests {
// Test double redirects and headers recording
let fut = fetcher
- .get_source_file_async(&double_redirect_url, true, false)
+ .get_source_file_async(&double_redirect_url, true, false, false)
.then(move |result| {
assert!(result.is_ok());
let mod_meta = result.unwrap();
@@ -1196,7 +1227,7 @@ mod tests {
// Test that redirect target is not downloaded twice for different redirect source.
let fut = fetcher
- .get_source_file_async(&double_redirect_url, true, false)
+ .get_source_file_async(&double_redirect_url, true, false, false)
.then(move |result| {
assert!(result.is_ok());
let result = fs::File::open(&target_path);
@@ -1210,7 +1241,7 @@ mod tests {
// shouldn't be downloaded again. It can be verified using source header file creation
// timestamp (should be the same as after first `get_source_file`)
fetcher
- .get_source_file_async(&redirect_url, true, false)
+ .get_source_file_async(&redirect_url, true, false, false)
.map(move |r| (r, file_modified))
})
.then(move |(result, file_modified)| {
@@ -1257,7 +1288,27 @@ mod tests {
}
#[test]
- fn test_get_source_code_no_fetch() {
+ fn test_get_source_no_remote() {
+ let http_server_guard = crate::test_util::http_server();
+ let (_temp_dir, fetcher) = test_setup();
+ let module_url =
+ Url::parse("http://localhost:4545/tests/002_hello.ts").unwrap();
+ // Remote modules are not allowed
+ let fut = fetcher
+ .get_source_file_async(&module_url, true, true, false)
+ .then(move |result| {
+ assert!(result.is_err());
+ let err = result.err().unwrap();
+ assert_eq!(err.kind(), ErrorKind::NotFound);
+ futures::future::ok(())
+ });
+
+ tokio_util::run(fut);
+ drop(http_server_guard);
+ }
+
+ #[test]
+ fn test_get_source_cached_only() {
let http_server_guard = crate::test_util::http_server();
let (_temp_dir, fetcher) = test_setup();
let fetcher_1 = fetcher.clone();
@@ -1266,21 +1317,21 @@ mod tests {
Url::parse("http://localhost:4545/tests/002_hello.ts").unwrap();
let module_url_1 = module_url.clone();
let module_url_2 = module_url.clone();
- // file hasn't been cached before and remote downloads are not allowed
+ // file hasn't been cached before
let fut = fetcher
- .get_source_file_async(&module_url, true, true)
+ .get_source_file_async(&module_url, true, false, true)
.then(move |result| {
assert!(result.is_err());
let err = result.err().unwrap();
- assert_eq!(err.kind(), ErrorKind::NotFound);
+ assert_eq!(err.kind(), ErrorKind::PermissionDenied);
// download and cache file
- fetcher_1.get_source_file_async(&module_url_1, true, false)
+ fetcher_1.get_source_file_async(&module_url_1, true, false, false)
})
.then(move |result| {
assert!(result.is_ok());
- // module is already cached, should be ok even with `no_remote_fetch`
- fetcher_2.get_source_file_async(&module_url_2, true, true)
+ // module is already cached, should be ok even with `cached_only`
+ fetcher_2.get_source_file_async(&module_url_2, true, false, true)
})
.then(move |result| {
assert!(result.is_ok());