summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin (Kun) "Kassimo" Qian <kevinkassimo@gmail.com>2018-12-27 15:40:06 -0500
committerRyan Dahl <ry@tinyclouds.org>2018-12-27 20:40:06 +0000
commit73fb98ce70b327d1236b9540f3839a89c5d22ef0 (patch)
treef6d7f1ddee052fd7bd0979f72a59c83fe000a1e0
parent3d9f46a6cfc14d890d9899fdd4df2cc993478cc0 (diff)
Lazily create .mime files only with mismatch/no extension (#1417)
-rw-r--r--src/deno_dir.rs165
-rw-r--r--tests/subdir/mismatch_ext.ts1
-rw-r--r--tests/subdir/no_ext1
-rw-r--r--tests/subdir/unknown_ext.deno1
-rwxr-xr-xtools/http_server.py6
5 files changed, 164 insertions, 10 deletions
diff --git a/src/deno_dir.rs b/src/deno_dir.rs
index b5fd7cb0a..1af5daa3f 100644
--- a/src/deno_dir.rs
+++ b/src/deno_dir.rs
@@ -28,6 +28,16 @@ pub struct CodeFetchOutput {
pub maybe_source_map: Option<Vec<u8>>,
}
+/// Gets corresponding MediaType given extension
+fn extmap(ext: &str) -> msg::MediaType {
+ match ext {
+ "ts" => msg::MediaType::TypeScript,
+ "js" => msg::MediaType::JavaScript,
+ "json" => msg::MediaType::Json,
+ _ => msg::MediaType::Unknown,
+ }
+}
+
pub struct DenoDir {
// Example: /Users/rld/.deno/
pub root: PathBuf,
@@ -156,7 +166,21 @@ impl DenoDir {
None => Ok(()),
}?;
deno_fs::write_file(&p, &source, 0o666)?;
- deno_fs::write_file(&mt, content_type.as_bytes(), 0o666)?;
+ // Remove possibly existing stale .mime file
+ // may not exist. DON'T unwrap
+ let _ = std::fs::remove_file(&media_type_filename);
+ // Create .mime file only when content type different from extension
+ let resolved_content_type = map_content_type(&p, Some(&content_type));
+ let ext = p
+ .extension()
+ .map(|x| x.to_str().unwrap_or(""))
+ .unwrap_or("");
+ let media_type = extmap(&ext);
+ if media_type == msg::MediaType::Unknown
+ || media_type != resolved_content_type
+ {
+ deno_fs::write_file(&mt, content_type.as_bytes(), 0o666)?
+ }
return Ok(Some(CodeFetchOutput {
module_name: module_name.to_string(),
filename: filename.to_string(),
@@ -614,7 +638,7 @@ mod tests {
}
#[test]
- fn test_get_source_code() {
+ fn test_get_source_code_1() {
let (temp_dir, deno_dir) = test_setup();
// http_util::fetch_sync_string requires tokio
tokio_util::init(|| {
@@ -635,10 +659,8 @@ mod tests {
b"export { printHello } from \"./print_hello.ts\";\n";
assert_eq!(r.source_code, expected);
assert_eq!(&(r.media_type), &msg::MediaType::TypeScript);
- assert_eq!(
- fs::read_to_string(&mime_file_name).unwrap(),
- "application/typescript"
- );
+ // Should not create .mime file due to matching ext
+ assert!(fs::read_to_string(&mime_file_name).is_err());
// Modify .mime
let _ = fs::write(&mime_file_name, "text/javascript");
@@ -665,12 +687,68 @@ mod tests {
let expected3: &[u8] =
b"export { printHello } from \"./print_hello.ts\";\n";
assert_eq!(r3.source_code, expected3);
- // Now the .mime file should be overwritten back to TypeScript!
- // (due to http fetch)
+ // Now the old .mime file should have gone! Resolved back to TypeScript
assert_eq!(&(r3.media_type), &msg::MediaType::TypeScript);
+ assert!(fs::read_to_string(&mime_file_name).is_err());
+ });
+ }
+
+ #[test]
+ fn test_get_source_code_2() {
+ let (temp_dir, deno_dir) = test_setup();
+ // http_util::fetch_sync_string requires tokio
+ tokio_util::init(|| {
+ let module_name = "http://localhost:4545/tests/subdir/mismatch_ext.ts";
+ let filename = deno_fs::normalize_path(
+ deno_dir
+ .deps_http
+ .join("localhost_PORT4545/tests/subdir/mismatch_ext.ts")
+ .as_ref(),
+ );
+ let mime_file_name = format!("{}.mime", &filename);
+
+ let result = deno_dir.get_source_code(module_name, &filename);
+ println!("module_name {} filename {}", module_name, filename);
+ assert!(result.is_ok());
+ let r = result.unwrap();
+ let expected: &[u8] = b"export const loaded = true;\n";
+ assert_eq!(r.source_code, expected);
+ // Mismatch ext with content type, create .mime
+ assert_eq!(&(r.media_type), &msg::MediaType::JavaScript);
assert_eq!(
fs::read_to_string(&mime_file_name).unwrap(),
- "application/typescript"
+ "text/javascript"
+ );
+
+ // Modify .mime
+ let _ = fs::write(&mime_file_name, "text/typescript");
+ let result2 = deno_dir.get_source_code(module_name, &filename);
+ assert!(result2.is_ok());
+ let r2 = result2.unwrap();
+ let expected2: &[u8] = b"export const loaded = true;\n";
+ assert_eq!(r2.source_code, expected2);
+ // If get_source_code does not call remote, this should be TypeScript
+ // as we modified before! (we do not overwrite .mime due to no http fetch)
+ assert_eq!(&(r2.media_type), &msg::MediaType::TypeScript);
+ assert_eq!(
+ fs::read_to_string(&mime_file_name).unwrap(),
+ "text/typescript"
+ );
+
+ // Force self.reload
+ let deno_dir = DenoDir::new(true, Some(temp_dir.path().to_path_buf()))
+ .expect("setup fail");
+ let result3 = deno_dir.get_source_code(module_name, &filename);
+ assert!(result3.is_ok());
+ let r3 = result3.unwrap();
+ let expected3: &[u8] = b"export const loaded = true;\n";
+ assert_eq!(r3.source_code, expected3);
+ // Now the old .mime file should be overwritten back to JavaScript!
+ // (due to http fetch)
+ assert_eq!(&(r3.media_type), &msg::MediaType::JavaScript);
+ assert_eq!(
+ fs::read_to_string(&mime_file_name).unwrap(),
+ "text/javascript"
);
});
}
@@ -696,7 +774,8 @@ mod tests {
let r = result.unwrap().unwrap();
assert_eq!(&(r.source_code), b"export const loaded = true;\n");
assert_eq!(&(r.media_type), &msg::MediaType::TypeScript);
- assert_eq!(fs::read_to_string(&mime_file_name).unwrap(), "video/mp2t");
+ // matching ext, no .mime file created
+ assert!(fs::read_to_string(&mime_file_name).is_err());
// Modify .mime, make sure read from local
let _ = fs::write(&mime_file_name, "text/javascript");
@@ -711,6 +790,72 @@ mod tests {
#[test]
fn test_fetch_source_2() {
+ use tokio_util;
+ // http_util::fetch_sync_string requires tokio
+ tokio_util::init(|| {
+ let (_temp_dir, deno_dir) = test_setup();
+ let module_name = "http://localhost:4545/tests/subdir/no_ext";
+ let filename = deno_fs::normalize_path(
+ deno_dir
+ .deps_http
+ .join("localhost_PORT4545/tests/subdir/no_ext")
+ .as_ref(),
+ );
+ let mime_file_name = format!("{}.mime", &filename);
+ let result = deno_dir.fetch_remote_source(module_name, &filename);
+ assert!(result.is_ok());
+ let r = result.unwrap().unwrap();
+ assert_eq!(&(r.source_code), b"export const loaded = true;\n");
+ assert_eq!(&(r.media_type), &msg::MediaType::TypeScript);
+ // no ext, should create .mime file
+ assert_eq!(
+ fs::read_to_string(&mime_file_name).unwrap(),
+ "text/typescript"
+ );
+
+ let module_name_2 = "http://localhost:4545/tests/subdir/mismatch_ext.ts";
+ let filename_2 = deno_fs::normalize_path(
+ deno_dir
+ .deps_http
+ .join("localhost_PORT4545/tests/subdir/mismatch_ext.ts")
+ .as_ref(),
+ );
+ let mime_file_name_2 = format!("{}.mime", &filename_2);
+ let result_2 = deno_dir.fetch_remote_source(module_name_2, &filename_2);
+ assert!(result_2.is_ok());
+ let r2 = result_2.unwrap().unwrap();
+ assert_eq!(&(r2.source_code), b"export const loaded = true;\n");
+ assert_eq!(&(r2.media_type), &msg::MediaType::JavaScript);
+ // mismatch ext, should create .mime file
+ assert_eq!(
+ fs::read_to_string(&mime_file_name_2).unwrap(),
+ "text/javascript"
+ );
+
+ // test unknown extension
+ let module_name_3 = "http://localhost:4545/tests/subdir/unknown_ext.deno";
+ let filename_3 = deno_fs::normalize_path(
+ deno_dir
+ .deps_http
+ .join("localhost_PORT4545/tests/subdir/unknown_ext.deno")
+ .as_ref(),
+ );
+ let mime_file_name_3 = format!("{}.mime", &filename_3);
+ let result_3 = deno_dir.fetch_remote_source(module_name_3, &filename_3);
+ assert!(result_3.is_ok());
+ let r3 = result_3.unwrap().unwrap();
+ assert_eq!(&(r3.source_code), b"export const loaded = true;\n");
+ assert_eq!(&(r3.media_type), &msg::MediaType::TypeScript);
+ // unknown ext, should create .mime file
+ assert_eq!(
+ fs::read_to_string(&mime_file_name_3).unwrap(),
+ "text/typescript"
+ );
+ });
+ }
+
+ #[test]
+ fn test_fetch_source_3() {
// only local, no http_util::fetch_sync_string called
let (_temp_dir, deno_dir) = test_setup();
let cwd = std::env::current_dir().unwrap();
diff --git a/tests/subdir/mismatch_ext.ts b/tests/subdir/mismatch_ext.ts
new file mode 100644
index 000000000..e67d2a017
--- /dev/null
+++ b/tests/subdir/mismatch_ext.ts
@@ -0,0 +1 @@
+export const loaded = true;
diff --git a/tests/subdir/no_ext b/tests/subdir/no_ext
new file mode 100644
index 000000000..e67d2a017
--- /dev/null
+++ b/tests/subdir/no_ext
@@ -0,0 +1 @@
+export const loaded = true;
diff --git a/tests/subdir/unknown_ext.deno b/tests/subdir/unknown_ext.deno
new file mode 100644
index 000000000..e67d2a017
--- /dev/null
+++ b/tests/subdir/unknown_ext.deno
@@ -0,0 +1 @@
+export const loaded = true;
diff --git a/tools/http_server.py b/tools/http_server.py
index 6cf997b86..7c4b1fe25 100755
--- a/tools/http_server.py
+++ b/tools/http_server.py
@@ -58,6 +58,12 @@ class ContentTypeHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
return "application/x-javascript"
if "form_urlencoded" in path:
return "application/x-www-form-urlencoded"
+ if "no_ext" in path:
+ return "text/typescript"
+ if "unknown_ext" in path:
+ return "text/typescript"
+ if "mismatch_ext" in path:
+ return "text/javascript"
return SimpleHTTPServer.SimpleHTTPRequestHandler.guess_type(self, path)