use headers::{ContentCoding, HeaderMap, HeaderValue};
use std::{
ffi::OsStr,
fs::Metadata,
path::{Path, PathBuf},
};
use crate::{compression, static_files::file_metadata};
pub async fn precompressed_variant<'a>(
file_path: &Path,
headers: &'a HeaderMap<HeaderValue>,
) -> Option<(PathBuf, Metadata, &'a str)> {
let mut precompressed = None;
tracing::trace!(
"preparing pre-compressed file path variant of {}",
file_path.display()
);
let precomp_ext = match compression::get_prefered_encoding(headers) {
Some(ContentCoding::GZIP | ContentCoding::DEFLATE) => Some("gz"),
Some(ContentCoding::BROTLI) => Some("br"),
_ => None,
};
if precomp_ext.is_none() {
tracing::trace!("preferred encoding based on the file extension was not determined");
}
if let Some(ext) = precomp_ext {
let filename = file_path.file_name().and_then(OsStr::to_str);
if let Some(filename) = filename {
let precomp_file_name = [filename, ".", ext].concat();
let filepath_precomp = file_path.with_file_name(precomp_file_name);
tracing::trace!(
"getting metadata for pre-compressed file variant {}",
filepath_precomp.display()
);
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 };
precompressed = Some((filepath_precomp, meta, encoding));
}
}
}
precompressed
}