From 06cba46c5545ce2b5271570320e0e22702bc66b1 Mon Sep 17 00:00:00 2001 From: Jose Quintana <1700322+joseluisq@users.noreply.github.com> Date: Sun, 5 Mar 2023 23:33:19 +0100 Subject: [PATCH] fix: compression static auto index.html check missing (#186) it also prevents trying to serve a pre-compressed file variant if the file found was a directory (a folder named as a file) fixes #178 --- src/compression_static.rs | 9 ++++++++- src/static_files.rs | 67 ++++++++++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/compression_static.rs b/src/compression_static.rs index f776249..3b11310 100644 --- a/src/compression_static.rs +++ b/src/compression_static.rs @@ -44,7 +44,14 @@ pub async fn precompressed_variant<'a>( filepath_precomp.display() ); - if let Ok((meta, _)) = file_metadata(&filepath_precomp) { + if let Ok((meta, is_dir)) = file_metadata(&filepath_precomp) { + if is_dir { + tracing::trace!( + "pre-compressed file variant found but it's a directory, skipping" + ); + return None; + } + tracing::trace!("pre-compressed file variant found, serving it directly"); let encoding = if ext == "gz" { "gzip" } else { ext }; diff --git a/src/static_files.rs b/src/static_files.rs index 7c915fb..1096bc5 100644 --- a/src/static_files.rs +++ b/src/static_files.rs @@ -167,17 +167,6 @@ async fn composed_file_metadata<'a>( headers: &'a HeaderMap, compression_static: bool, ) -> Result<(&'a PathBuf, Metadata, bool, Option<(PathBuf, &'a str)>), StatusCode> { - // First pre-compressed variant check for the given file path - let mut tried_precompressed = false; - if compression_static { - tried_precompressed = true; - if let Some((path, meta, ext)) = - compression_static::precompressed_variant(file_path, headers).await - { - return Ok((file_path, meta, false, Some((path, ext)))); - } - } - tracing::trace!("getting metadata for file {}", file_path.display()); match file_metadata(file_path.as_ref()) { @@ -187,7 +176,17 @@ async fn composed_file_metadata<'a>( tracing::debug!("dir: appending an index.html to the directory path"); file_path.push("index.html"); - // If file exists then overwrite the `meta` + // Pre-compressed variant check for the autoindex + if compression_static { + if let Some((path, meta, ext)) = + compression_static::precompressed_variant(file_path, headers).await + { + return Ok((file_path, meta, false, Some((path, ext)))); + } + } + + // Otherwise, just fallback to finding the index.html + // and overwrite the current `meta` // Also noting that it's still a directory request if let Ok(meta_res) = file_metadata(file_path.as_ref()) { (meta, _) = meta_res @@ -203,23 +202,22 @@ async fn composed_file_metadata<'a>( file_path.push("index.html"); } } + } else { + // Fallback pre-compressed variant check for the specific file + if compression_static { + if let Some((path, meta, ext)) = + compression_static::precompressed_variant(file_path, headers).await + { + return Ok((file_path, meta, false, Some((path, ext)))); + } + } } Ok((file_path, meta, is_dir, None)) } Err(err) => { - if err == StatusCode::NOT_FOUND { - // If the file path doesn't exist, we try to find the path suffixed with `.html`. - // For example: `/posts/article` will fallback to `/posts/article.html` - let new_meta: Option; - (file_path, new_meta) = prefix_file_html_metadata(file_path); - if let Some(new_meta) = new_meta { - return Ok((file_path, new_meta, false, None)); - } - } - - // Second pre-compressed variant check for the given file path - if compression_static && !tried_precompressed { + // Pre-compressed variant check for the file not found + if compression_static { if let Some((path, meta, ext)) = compression_static::precompressed_variant(file_path, headers).await { @@ -227,12 +225,31 @@ async fn composed_file_metadata<'a>( } } + // Otherwise, if the file path doesn't exist then + // we try to find the path suffixed with `.html`. + // For example: `/posts/article` will fallback to `/posts/article.html` + let new_meta: Option; + (file_path, new_meta) = prefix_file_html_metadata(file_path); + match new_meta { + Some(new_meta) => return Ok((file_path, new_meta, false, None)), + _ => { + // Last pre-compressed variant check or the prefixed file not found + if compression_static { + if let Some((path, meta, ext)) = + compression_static::precompressed_variant(file_path, headers).await + { + return Ok((file_path, meta, false, Some((path, ext)))); + } + } + } + } + Err(err) } } } -/// Try to find the file system metadata for the given file path. +/// Try to find the file system metadata for the given file path or returns an `Not Found` error. pub fn file_metadata(file_path: &Path) -> Result<(Metadata, bool), StatusCode> { match std::fs::metadata(file_path) { Ok(meta) => { -- libgit2 1.7.2