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
Diff
src/compression_static.rs | 9 +++++-
src/static_files.rs | 67 ++++++++++++++++++++++++++++++------------------
2 files changed, 50 insertions(+), 26 deletions(-)
@@ -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 };
@@ -167,17 +167,6 @@ async fn composed_file_metadata<'a>(
headers: &'a HeaderMap<HeaderValue>,
compression_static: bool,
) -> Result<(&'a PathBuf, Metadata, bool, Option<(PathBuf, &'a str)>), StatusCode> {
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 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))));
}
}
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 {
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 {
let new_meta: Option<Metadata>;
(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));
}
}
if compression_static && !tried_precompressed {
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>(
}
}
let new_meta: Option<Metadata>;
(file_path, new_meta) = prefix_file_html_metadata(file_path);
match new_meta {
Some(new_meta) => return Ok((file_path, new_meta, false, None)),
_ => {
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)
}
}
}
pub fn file_metadata(file_path: &Path) -> Result<(Metadata, bool), StatusCode> {
match std::fs::metadata(file_path) {
Ok(meta) => {