diff --git a/Cargo.lock b/Cargo.lock index 42fe37c..b71b5b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,6 +127,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2105142db9c6203b9dadc83b0553394589a6cb31b1449a3b46b42f47c3434d0" dependencies = [ "async-compression", + "chrono", "crc32fast", "log", "pin-project", diff --git a/Cargo.toml b/Cargo.toml index 6a3de36..1839bfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ serde = { version = "1", features = ["derive"] } serde_json = "1" futures = "0.3" base64 = "0.21" -async_zip = { version = "0.0.12", default-features = false, features = ["deflate"] } +async_zip = { version = "0.0.12", default-features = false, features = ["deflate", "chrono"] } headers = "0.3" mime_guess = "2.0" if-addrs = "0.10.1" diff --git a/src/server.rs b/src/server.rs index d43b450..f6e712a 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,12 +1,14 @@ use crate::streamer::Streamer; -use crate::utils::{decode_uri, encode_uri, get_file_name, glob, try_get_file_name}; +use crate::utils::{ + decode_uri, encode_uri, get_file_mtime_and_mode, get_file_name, glob, try_get_file_name, +}; use crate::Args; use anyhow::{anyhow, Result}; use walkdir::WalkDir; use xml::escape::escape_str_pcdata; use async_zip::write::ZipFileWriter; -use async_zip::{Compression, ZipEntryBuilder}; +use async_zip::{Compression, ZipDateTime, ZipEntryBuilder}; use chrono::{LocalResult, TimeZone, Utc}; use futures::TryStreamExt; use headers::{ @@ -1286,8 +1288,10 @@ async fn zip_dir( Some(v) => v, None => continue, }; - let builder = - ZipEntryBuilder::new(filename.into(), Compression::Deflate).unix_permissions(0o644); + let (datetime, mode) = get_file_mtime_and_mode(&zip_path).await?; + let builder = ZipEntryBuilder::new(filename.into(), Compression::Deflate) + .unix_permissions(mode) + .last_modification_date(ZipDateTime::from_chrono(&datetime)); let mut file = File::open(&zip_path).await?; let mut file_writer = writer.write_entry_stream(builder).await?; io::copy(&mut file, &mut file_writer).await?; diff --git a/src/utils.rs b/src/utils.rs index bfede94..2948679 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,4 +1,5 @@ use anyhow::{anyhow, Context, Result}; +use chrono::{DateTime, Utc}; use std::{ borrow::Cow, path::Path, @@ -28,6 +29,21 @@ pub fn get_file_name(path: &Path) -> &str { .unwrap_or_default() } +#[cfg(unix)] +pub async fn get_file_mtime_and_mode(path: &Path) -> Result<(DateTime, u16)> { + use std::os::unix::prelude::MetadataExt; + let meta = tokio::fs::metadata(path).await?; + let datetime: DateTime = meta.modified()?.into(); + Ok((datetime, meta.mode() as u16)) +} + +#[cfg(not(unix))] +pub async fn get_file_mtime_and_mode(path: &Path) -> Result<(DateTime, u16)> { + let meta = tokio::fs::metadata(&path).await?; + let datetime: DateTime = meta.modified()?.into(); + Ok((datetime, 0o644)) +} + pub fn try_get_file_name(path: &Path) -> Result<&str> { path.file_name() .and_then(|v| v.to_str())