cargo fmt
This commit is contained in:
parent
e05886aac5
commit
446c0f0264
|
@ -11,7 +11,7 @@ use rand::{
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::skip_serializing_none;
|
use serde_with::skip_serializing_none;
|
||||||
use serde_with::{serde_as, PickFirst, FromInto};
|
use serde_with::{serde_as, FromInto, PickFirst};
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
fs::File,
|
fs::File,
|
||||||
|
|
|
@ -290,30 +290,37 @@ impl Uploader {
|
||||||
.write(true)
|
.write(true)
|
||||||
.create_new(true)
|
.create_new(true)
|
||||||
.open(&storage_path)?;
|
.open(&storage_path)?;
|
||||||
let (writer, name, size, modtime, contents): (Box<dyn Write>, _, _, _, _) = if files.len() > 1 {
|
let (writer, name, size, modtime, contents): (Box<dyn Write>, _, _, _, _) =
|
||||||
info!("Wrapping in zipfile generator");
|
if files.len() > 1 {
|
||||||
let now = OffsetDateTime::now_utc();
|
info!("Wrapping in zipfile generator");
|
||||||
let collection_name =
|
let now = OffsetDateTime::now_utc();
|
||||||
collection_name.map(|f| sanitise(&f, 4)).unwrap_or_else(|| {
|
let collection_name =
|
||||||
super::APP_NAME.to_owned() + &now.format(FILENAME_DATE_FORMAT).unwrap()
|
collection_name.map(|f| sanitise(&f, 4)).unwrap_or_else(|| {
|
||||||
});
|
super::APP_NAME.to_owned()
|
||||||
let file_set = FileSet {
|
+ &now.format(FILENAME_DATE_FORMAT).unwrap()
|
||||||
files,
|
});
|
||||||
directory_name: Some(collection_name.clone()),
|
let file_set = FileSet {
|
||||||
|
files,
|
||||||
|
directory_name: Some(collection_name.clone()),
|
||||||
|
};
|
||||||
|
let zip_writer = super::zip::ZipGenerator::new(file_set.clone(), writer);
|
||||||
|
let size = zip_writer.total_size();
|
||||||
|
(
|
||||||
|
Box::new(zip_writer),
|
||||||
|
collection_name + ".zip",
|
||||||
|
size,
|
||||||
|
now,
|
||||||
|
Some(file_set),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
Box::new(writer),
|
||||||
|
files[0].name.clone(),
|
||||||
|
files[0].size,
|
||||||
|
files[0].modtime,
|
||||||
|
None,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
let zip_writer =
|
|
||||||
super::zip::ZipGenerator::new(file_set.clone(), writer);
|
|
||||||
let size = zip_writer.total_size();
|
|
||||||
(Box::new(zip_writer), collection_name + ".zip", size, now, Some(file_set))
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
Box::new(writer),
|
|
||||||
files[0].name.clone(),
|
|
||||||
files[0].size,
|
|
||||||
files[0].modtime,
|
|
||||||
None
|
|
||||||
)
|
|
||||||
};
|
|
||||||
self.writer = Some(writer);
|
self.writer = Some(writer);
|
||||||
let stored_file = StoredFile {
|
let stored_file = StoredFile {
|
||||||
name,
|
name,
|
||||||
|
|
63
src/zip.rs
63
src/zip.rs
|
@ -37,16 +37,20 @@ pub struct FileSet {
|
||||||
|
|
||||||
impl From<Vec<UploadedFile>> for FileSet {
|
impl From<Vec<UploadedFile>> for FileSet {
|
||||||
fn from(files: Vec<UploadedFile>) -> Self {
|
fn from(files: Vec<UploadedFile>) -> Self {
|
||||||
Self { files, directory_name: None }
|
Self {
|
||||||
|
files,
|
||||||
|
directory_name: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn full_file_name_len(file: &UploadedFile, directory_name: &Option<String>) -> u64 {
|
fn full_file_name_len(file: &UploadedFile, directory_name: &Option<String>) -> u64 {
|
||||||
file.name.len() as u64 + if let Some(d) = directory_name {
|
file.name.len() as u64
|
||||||
d.len() as u64 + 1
|
+ if let Some(d) = directory_name {
|
||||||
} else {
|
d.len() as u64 + 1
|
||||||
0
|
} else {
|
||||||
}
|
0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_entry_size(file: &UploadedFile, directory_name: &Option<String>) -> u64 {
|
fn file_entry_size(file: &UploadedFile, directory_name: &Option<String>) -> u64 {
|
||||||
|
@ -55,7 +59,11 @@ fn file_entry_size(file: &UploadedFile, directory_name: &Option<String>) -> u64
|
||||||
|
|
||||||
fn file_entries_size(files: &FileSet, bound: Option<usize>) -> u64 {
|
fn file_entries_size(files: &FileSet, bound: Option<usize>) -> u64 {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
let fs = if let Some(n) = bound { &files.files[..n] } else { &files.files };
|
let fs = if let Some(n) = bound {
|
||||||
|
&files.files[..n]
|
||||||
|
} else {
|
||||||
|
&files.files
|
||||||
|
};
|
||||||
for file in fs.iter() {
|
for file in fs.iter() {
|
||||||
total += file_entry_size(file, &files.directory_name)
|
total += file_entry_size(file, &files.directory_name)
|
||||||
}
|
}
|
||||||
|
@ -72,7 +80,8 @@ pub fn file_data_offsets(files: &FileSet) -> Vec<u64> {
|
||||||
let mut offsets = Vec::new();
|
let mut offsets = Vec::new();
|
||||||
let mut offset: u64 = 0;
|
let mut offset: u64 = 0;
|
||||||
for file in files.files.iter() {
|
for file in files.files.iter() {
|
||||||
offset += LOCAL_HEADER_SIZE_MINUS_FILENAME + full_file_name_len(file, &files.directory_name);
|
offset +=
|
||||||
|
LOCAL_HEADER_SIZE_MINUS_FILENAME + full_file_name_len(file, &files.directory_name);
|
||||||
offsets.push(offset);
|
offsets.push(offset);
|
||||||
offset += file.size + DATA_DESCRIPTOR_SIZE;
|
offset += file.size + DATA_DESCRIPTOR_SIZE;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +91,8 @@ pub fn file_data_offsets(files: &FileSet) -> Vec<u64> {
|
||||||
fn central_directory_size(files: &FileSet) -> u64 {
|
fn central_directory_size(files: &FileSet) -> u64 {
|
||||||
let mut total = 0;
|
let mut total = 0;
|
||||||
for file in files.files.iter() {
|
for file in files.files.iter() {
|
||||||
total += CENTRAL_DIRECTORY_HEADER_SIZE_MINUS_FILENAME + full_file_name_len(file, &files.directory_name);
|
total += CENTRAL_DIRECTORY_HEADER_SIZE_MINUS_FILENAME
|
||||||
|
+ full_file_name_len(file, &files.directory_name);
|
||||||
}
|
}
|
||||||
total
|
total
|
||||||
}
|
}
|
||||||
|
@ -185,7 +195,12 @@ impl UploadedFile {
|
||||||
header
|
header
|
||||||
}
|
}
|
||||||
|
|
||||||
fn central_directory_header(&self, directory_name: &Option<String>, local_header_offset: u64, hash: u32) -> Vec<u8> {
|
fn central_directory_header(
|
||||||
|
&self,
|
||||||
|
directory_name: &Option<String>,
|
||||||
|
local_header_offset: u64,
|
||||||
|
hash: u32,
|
||||||
|
) -> Vec<u8> {
|
||||||
let mut header = vec![
|
let mut header = vec![
|
||||||
0x50, 0x4b, 0x01, 0x02, // Central directory file header signature
|
0x50, 0x4b, 0x01, 0x02, // Central directory file header signature
|
||||||
45, 3, // Made by a Unix system supporting version 4.5
|
45, 3, // Made by a Unix system supporting version 4.5
|
||||||
|
@ -286,13 +301,16 @@ impl<W: Write> ZipGenerator<W> {
|
||||||
|
|
||||||
fn start_new_file(&mut self) {
|
fn start_new_file(&mut self) {
|
||||||
let mut offset = file_entries_size(&self.files, Some(self.file_index));
|
let mut offset = file_entries_size(&self.files, Some(self.file_index));
|
||||||
while self.file_index < self.files.files.len() && self.files.files[self.file_index].size == 0 {
|
while self.file_index < self.files.files.len()
|
||||||
|
&& self.files.files[self.file_index].size == 0
|
||||||
|
{
|
||||||
debug!(
|
debug!(
|
||||||
"Empty file entry in zipfile: {}",
|
"Empty file entry in zipfile: {}",
|
||||||
self.files.files[self.file_index].name
|
self.files.files[self.file_index].name
|
||||||
);
|
);
|
||||||
self.hashes.push(EMPTY_STRING_CRC32);
|
self.hashes.push(EMPTY_STRING_CRC32);
|
||||||
let mut local_header = self.files.files[self.file_index].local_header(&self.files.directory_name, offset);
|
let mut local_header =
|
||||||
|
self.files.files[self.file_index].local_header(&self.files.directory_name, offset);
|
||||||
let mut data_descriptor =
|
let mut data_descriptor =
|
||||||
self.files.files[self.file_index].data_descriptor(EMPTY_STRING_CRC32);
|
self.files.files[self.file_index].data_descriptor(EMPTY_STRING_CRC32);
|
||||||
offset += local_header.len() as u64 + data_descriptor.len() as u64;
|
offset += local_header.len() as u64 + data_descriptor.len() as u64;
|
||||||
|
@ -306,8 +324,10 @@ impl<W: Write> ZipGenerator<W> {
|
||||||
self.files.files[self.file_index].name
|
self.files.files[self.file_index].name
|
||||||
);
|
);
|
||||||
self.byte_index = 0;
|
self.byte_index = 0;
|
||||||
self.pending_metadata
|
self.pending_metadata.append(
|
||||||
.append(&mut self.files.files[self.file_index].local_header(&self.files.directory_name, offset));
|
&mut self.files.files[self.file_index]
|
||||||
|
.local_header(&self.files.directory_name, offset),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
self.finish_zipfile();
|
self.finish_zipfile();
|
||||||
}
|
}
|
||||||
|
@ -322,7 +342,11 @@ impl<W: Write> ZipGenerator<W> {
|
||||||
file.name, self.hashes[i]
|
file.name, self.hashes[i]
|
||||||
);
|
);
|
||||||
self.pending_metadata
|
self.pending_metadata
|
||||||
.append(&mut file.central_directory_header(&self.files.directory_name, offset, self.hashes[i]));
|
.append(&mut file.central_directory_header(
|
||||||
|
&self.files.directory_name,
|
||||||
|
offset,
|
||||||
|
self.hashes[i],
|
||||||
|
));
|
||||||
offset += file_entry_size(file, &self.files.directory_name);
|
offset += file_entry_size(file, &self.files.directory_name);
|
||||||
}
|
}
|
||||||
debug!("Writing end of central directory");
|
debug!("Writing end of central directory");
|
||||||
|
@ -383,8 +407,13 @@ mod tests {
|
||||||
fn test_no_files() {
|
fn test_no_files() {
|
||||||
let mut output: Vec<u8> = vec![];
|
let mut output: Vec<u8> = vec![];
|
||||||
{
|
{
|
||||||
let mut zipgen =
|
let mut zipgen = ZipGenerator::new(
|
||||||
ZipGenerator::new(FileSet { files: vec![], directory_name: "test".to_owned() }, Box::new(std::io::Cursor::new(&mut output)));
|
FileSet {
|
||||||
|
files: vec![],
|
||||||
|
directory_name: "test".to_owned(),
|
||||||
|
},
|
||||||
|
Box::new(std::io::Cursor::new(&mut output)),
|
||||||
|
);
|
||||||
zipgen.write_all(&[]).unwrap();
|
zipgen.write_all(&[]).unwrap();
|
||||||
zipgen.flush().unwrap();
|
zipgen.flush().unwrap();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue