Add Content-Length header

This commit is contained in:
2023-07-30 01:38:24 +02:00
parent d99b8a439f
commit e7766c9270
7 changed files with 58 additions and 36 deletions

View File

@@ -96,11 +96,14 @@ pub async fn download_chain<'a>(
if is_zip && book.file_type.to_lowercase() == "html" {
let filename = get_filename_by_book(book, file_type, true, false);
let filename_ascii = get_filename_by_book(book, file_type, true, true);
let data_size: usize = response.headers().get("Content-Length").unwrap().to_str().unwrap().parse().unwrap();
return Some(
DownloadResult::new(
Data::Response(response),
filename,
filename_ascii
filename_ascii,
data_size
)
);
}
@@ -108,19 +111,22 @@ pub async fn download_chain<'a>(
if !is_zip && !final_need_zip && !converting {
let filename = get_filename_by_book(book, &book.file_type, false, false);
let filename_ascii = get_filename_by_book(book, file_type, false, true);
let data_size: usize = response.headers().get("Content-Length").unwrap().to_str().unwrap().parse().unwrap();
return Some(
DownloadResult::new(
Data::Response(response),
filename,
filename_ascii,
data_size,
)
);
};
let unziped_temp_file = {
let (unziped_temp_file, data_size) = {
let temp_file_to_unzip_result = response_to_tempfile(&mut response).await;
let temp_file_to_unzip = match temp_file_to_unzip_result {
Some(v) => v,
Some(v) => v.0,
None => return None,
};
@@ -131,7 +137,7 @@ pub async fn download_chain<'a>(
};
let mut clean_file = if converting {
let (mut clean_file, data_size) = if converting {
match convert_file(unziped_temp_file, file_type.to_string()).await {
Some(mut response) => {
match response_to_tempfile(&mut response).await {
@@ -142,18 +148,20 @@ pub async fn download_chain<'a>(
None => return None,
}
} else {
unziped_temp_file
(unziped_temp_file, data_size)
};
if !final_need_zip {
let t = SpooledTempAsyncRead::new(clean_file);
let filename = get_filename_by_book(book, file_type, false, false);
let filename_ascii = get_filename_by_book(book, file_type, false, true);
return Some(
DownloadResult::new(
Data::SpooledTempAsyncRead(t),
filename,
filename_ascii
filename_ascii,
data_size
)
);
};
@@ -161,15 +169,17 @@ pub async fn download_chain<'a>(
let t_file_type = if file_type == "fb2zip" { "fb2" } else { file_type };
let filename = get_filename_by_book(book, t_file_type, false, false);
match zip(&mut clean_file, filename.as_str()) {
Some(v) => {
let t = SpooledTempAsyncRead::new(v);
Some((t_file, data_size)) => {
let t = SpooledTempAsyncRead::new(t_file);
let filename = get_filename_by_book(book, file_type, true, false);
let filename_ascii = get_filename_by_book(book, file_type, true, true);
Some(
DownloadResult::new(
Data::SpooledTempAsyncRead(t),
filename,
filename_ascii
filename_ascii,
data_size
)
)
},

View File

@@ -15,6 +15,7 @@ pub struct DownloadResult {
pub data: Data,
pub filename: String,
pub filename_ascii: String,
pub data_size: usize,
}
pub fn get_response_async_read(it: Response) -> impl AsyncRead {
@@ -25,8 +26,8 @@ pub fn get_response_async_read(it: Response) -> impl AsyncRead {
}
impl DownloadResult {
pub fn new(data: Data, filename: String, filename_ascii: String) -> Self {
Self { data, filename, filename_ascii }
pub fn new(data: Data, filename: String, filename_ascii: String, data_size: usize) -> Self {
Self { data, filename, filename_ascii, data_size }
}
pub fn get_async_read(self) -> Pin<Box<dyn AsyncRead + Send>> {

View File

@@ -6,9 +6,11 @@ use bytes::Buf;
use std::io::{Seek, SeekFrom, Write};
pub async fn response_to_tempfile(res: &mut Response) -> Option<SpooledTempFile> {
pub async fn response_to_tempfile(res: &mut Response) -> Option<(SpooledTempFile, usize)> {
let mut tmp_file = tempfile::spooled_tempfile(5 * 1024 * 1024);
let mut data_size: usize = 0;
{
loop {
let chunk = res.chunk().await;
@@ -23,6 +25,8 @@ pub async fn response_to_tempfile(res: &mut Response) -> Option<SpooledTempFile>
None => break,
};
data_size += data.len();
match tmp_file.write(data.chunk()) {
Ok(_) => (),
Err(_) => return None,
@@ -32,5 +36,5 @@ pub async fn response_to_tempfile(res: &mut Response) -> Option<SpooledTempFile>
tmp_file.seek(SeekFrom::Start(0)).unwrap();
}
Some(tmp_file)
Some((tmp_file, data_size))
}

View File

@@ -1,10 +1,10 @@
use std::io::{Seek, SeekFrom};
use std::io::Seek;
use tempfile::SpooledTempFile;
use zip::write::FileOptions;
pub fn unzip(tmp_file: SpooledTempFile, file_type: &str) -> Option<SpooledTempFile> {
pub fn unzip(tmp_file: SpooledTempFile, file_type: &str) -> Option<(SpooledTempFile, usize)> {
let mut archive = zip::ZipArchive::new(tmp_file).unwrap();
let file_type_lower = file_type.to_lowercase();
@@ -16,21 +16,21 @@ pub fn unzip(tmp_file: SpooledTempFile, file_type: &str) -> Option<SpooledTempFi
if filename.contains(&file_type_lower) || file.name().to_lowercase() == "elector" {
let mut output_file = tempfile::spooled_tempfile(5 * 1024 * 1024);
match std::io::copy(&mut file, &mut output_file) {
Ok(_) => (),
let size: usize = match std::io::copy(&mut file, &mut output_file) {
Ok(v) => v.try_into().unwrap(),
Err(_) => return None,
};
output_file.seek(SeekFrom::Start(0)).unwrap();
output_file.rewind().unwrap();
return Some(output_file);
return Some((output_file, size));
}
}
None
}
pub fn zip(tmp_file: &mut SpooledTempFile, filename: &str) -> Option<SpooledTempFile> {
pub fn zip(tmp_file: &mut SpooledTempFile, filename: &str) -> Option<(SpooledTempFile, usize)> {
let output_file = tempfile::spooled_tempfile(5 * 1024 * 1024);
let mut archive = zip::ZipWriter::new(output_file);
@@ -54,7 +54,9 @@ pub fn zip(tmp_file: &mut SpooledTempFile, filename: &str) -> Option<SpooledTemp
Err(_) => return None,
};
archive_result.seek(SeekFrom::Start(0)).unwrap();
let data_size: usize = archive_result.stream_position().unwrap().try_into().unwrap();
Some(archive_result)
archive_result.rewind().unwrap();
Some((archive_result, data_size))
}

View File

@@ -40,6 +40,7 @@ pub async fn download(
let filename = data.filename.clone();
let filename_ascii = data.filename_ascii.clone();
let file_size = data.data_size;
let reader = data.get_async_read();
let stream = ReaderStream::new(reader);
@@ -52,6 +53,10 @@ pub async fn download(
header::CONTENT_DISPOSITION,
format!("attachment; filename={filename_ascii}"),
),
(
header::CONTENT_LENGTH,
format!("{file_size}")
),
(
header::HeaderName::from_static("x-filename-b64"),
encoder.encode(filename),