summaryrefslogtreecommitdiff
path: root/cli/file_fetcher.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/file_fetcher.rs')
-rw-r--r--cli/file_fetcher.rs82
1 files changed, 79 insertions, 3 deletions
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index 677fa393b..75c2c608f 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -50,6 +50,10 @@ pub const SUPPORTED_SCHEMES: [&str; 5] =
/// A structure representing a source file.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct File {
+ /// The path to the local version of the source file. For local files this
+ /// will be the direct path to that file. For remote files, it will be the
+ /// path to the file in the HTTP cache.
+ pub local: PathBuf,
/// For remote files, if there was an `X-TypeScript-Type` header, the parsed
/// out value of that header.
pub maybe_types: Option<String>,
@@ -86,12 +90,13 @@ fn fetch_local(specifier: &ModuleSpecifier) -> Result<File, AnyError> {
let local = specifier.to_file_path().map_err(|_| {
uri_error(format!("Invalid file path.\n Specifier: {specifier}"))
})?;
- let bytes = fs::read(local)?;
+ let bytes = fs::read(&local)?;
let charset = text_encoding::detect_charset(&bytes).to_string();
let source = get_source_from_bytes(bytes, Some(charset))?;
let media_type = MediaType::from_specifier(specifier);
Ok(File {
+ local,
maybe_types: None,
media_type,
source: source.into(),
@@ -213,6 +218,13 @@ impl FileFetcher {
bytes: Vec<u8>,
headers: &HashMap<String, String>,
) -> Result<File, AnyError> {
+ let local =
+ self
+ .http_cache
+ .get_cache_filename(specifier)
+ .ok_or_else(|| {
+ generic_error("Cannot convert specifier to cached filename.")
+ })?;
let maybe_content_type = headers.get("content-type");
let (media_type, maybe_charset) =
map_content_type(specifier, maybe_content_type);
@@ -226,6 +238,7 @@ impl FileFetcher {
};
Ok(File {
+ local,
maybe_types,
media_type,
source: source.into(),
@@ -277,12 +290,39 @@ impl FileFetcher {
specifier: &ModuleSpecifier,
) -> Result<File, AnyError> {
debug!("FileFetcher::fetch_data_url() - specifier: {}", specifier);
+ match self.fetch_cached(specifier, 0) {
+ Ok(Some(file)) => return Ok(file),
+ Ok(None) => {}
+ Err(err) => return Err(err),
+ }
+
+ if self.cache_setting == CacheSetting::Only {
+ return Err(custom_error(
+ "NotCached",
+ format!(
+ "Specifier not found in cache: \"{specifier}\", --cached-only is specified."
+ ),
+ ));
+ }
+
let (source, content_type) = get_source_from_data_url(specifier)?;
let (media_type, _) = map_content_type(specifier, Some(&content_type));
+
+ let local =
+ self
+ .http_cache
+ .get_cache_filename(specifier)
+ .ok_or_else(|| {
+ generic_error("Cannot convert specifier to cached filename.")
+ })?;
let mut headers = HashMap::new();
headers.insert("content-type".to_string(), content_type);
+ self
+ .http_cache
+ .set(specifier, headers.clone(), source.as_bytes())?;
Ok(File {
+ local,
maybe_types: None,
media_type,
source: source.into(),
@@ -297,6 +337,21 @@ impl FileFetcher {
specifier: &ModuleSpecifier,
) -> Result<File, AnyError> {
debug!("FileFetcher::fetch_blob_url() - specifier: {}", specifier);
+ match self.fetch_cached(specifier, 0) {
+ Ok(Some(file)) => return Ok(file),
+ Ok(None) => {}
+ Err(err) => return Err(err),
+ }
+
+ if self.cache_setting == CacheSetting::Only {
+ return Err(custom_error(
+ "NotCached",
+ format!(
+ "Specifier not found in cache: \"{specifier}\", --cached-only is specified."
+ ),
+ ));
+ }
+
let blob = {
let blob_store = self.blob_store.borrow();
blob_store
@@ -315,10 +370,22 @@ impl FileFetcher {
let (media_type, maybe_charset) =
map_content_type(specifier, Some(&content_type));
let source = get_source_from_bytes(bytes, maybe_charset)?;
+
+ let local =
+ self
+ .http_cache
+ .get_cache_filename(specifier)
+ .ok_or_else(|| {
+ generic_error("Cannot convert specifier to cached filename.")
+ })?;
let mut headers = HashMap::new();
headers.insert("content-type".to_string(), content_type);
+ self
+ .http_cache
+ .set(specifier, headers.clone(), source.as_bytes())?;
Ok(File {
+ local,
maybe_types: None,
media_type,
source: source.into(),
@@ -495,9 +562,17 @@ impl FileFetcher {
// disk changing effecting things like workers and dynamic imports.
fetch_local(specifier)
} else if scheme == "data" {
- self.fetch_data_url(specifier)
+ let result = self.fetch_data_url(specifier);
+ if let Ok(file) = &result {
+ self.cache.insert(specifier.clone(), file.clone());
+ }
+ result
} else if scheme == "blob" {
- self.fetch_blob_url(specifier).await
+ let result = self.fetch_blob_url(specifier).await;
+ if let Ok(file) = &result {
+ self.cache.insert(specifier.clone(), file.clone());
+ }
+ result
} else if !self.allow_remote {
Err(custom_error(
"NoRemote",
@@ -962,6 +1037,7 @@ mod tests {
ModuleSpecifier::from_file_path(local.as_os_str().to_str().unwrap())
.unwrap();
let file = File {
+ local,
maybe_types: None,
media_type: MediaType::TypeScript,
source: "some source code".into(),