use headers::{ContentCoding, HeaderMap, HeaderValue};
use std::{fs::Metadata, path::PathBuf, sync::Arc};
use crate::{
compression,
static_files::{file_metadata, ArcPath},
};
pub async fn precompressed_variant(
file_path: PathBuf,
headers: &HeaderMap<HeaderValue>,
) -> Option<(ArcPath, Metadata, &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 mut filepath_precomp = file_path;
let filename = filepath_precomp.file_name().unwrap().to_str().unwrap();
let precomp_file_name = [filename, ".", ext].concat();
filepath_precomp.set_file_name(precomp_file_name);
tracing::trace!(
"getting metadata for pre-compressed file variant {}",
filepath_precomp.display()
);
if let Ok((meta, _)) = file_metadata(&filepath_precomp).await {
tracing::trace!("pre-compressed file variant found, serving it directly");
let encoding = if ext == "gz" { "gzip" } else { ext };
precompressed = Some((ArcPath(Arc::new(filepath_precomp)), meta, encoding));
}
}
precompressed
}