update download contents as more files become available
This commit is contained in:
parent
007289ffe5
commit
be4decde12
4 changed files with 80 additions and 16 deletions
60
src/main.rs
60
src/main.rs
|
@ -8,7 +8,7 @@ use std::{fmt::Debug, path::PathBuf, str::FromStr};
|
|||
|
||||
use actix_files::NamedFile;
|
||||
use actix_web::{
|
||||
get, http::StatusCode, middleware::Logger, post, web, App, HttpRequest, HttpResponse,
|
||||
error::InternalError, get, http::StatusCode, middleware::Logger, post, web, App, HttpRequest, HttpResponse,
|
||||
HttpServer, Responder,
|
||||
};
|
||||
use actix_web_actors::ws;
|
||||
|
@ -58,21 +58,22 @@ struct DownloadRequest {
|
|||
download: Option<download::DownloadSelection>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[derive(Serialize, Template)]
|
||||
#[template(path = "download.html")]
|
||||
struct DownloadInfo<'a> {
|
||||
struct DownloadInfo {
|
||||
file: StoredFile,
|
||||
code: &'a str,
|
||||
code: String,
|
||||
available: u64,
|
||||
offsets: Option<Vec<u64>>,
|
||||
}
|
||||
|
||||
#[get("/download")]
|
||||
async fn handle_download(
|
||||
req: HttpRequest,
|
||||
download: web::Query<DownloadRequest>,
|
||||
query: web::Query<DownloadRequest>,
|
||||
data: web::Data<AppState>,
|
||||
) -> actix_web::Result<HttpResponse> {
|
||||
let code = &download.code;
|
||||
let code = &query.code;
|
||||
if !store::is_valid_storage_code(code) {
|
||||
return not_found(req, data, true);
|
||||
}
|
||||
|
@ -85,7 +86,7 @@ async fn handle_download(
|
|||
|
||||
let storage_path = data.config.storage_dir.join(code);
|
||||
let file = File::open(&storage_path).await?;
|
||||
if let Some(selection) = download.download {
|
||||
if let Some(selection) = query.download {
|
||||
if let download::DownloadSelection::One(n) = selection {
|
||||
if let Some(ref files) = info.contents {
|
||||
if n >= files.len() {
|
||||
|
@ -103,26 +104,60 @@ async fn handle_download(
|
|||
}
|
||||
.into_response(&req))
|
||||
} else {
|
||||
let offsets = info.contents.as_deref().map(zip::file_data_offsets);
|
||||
Ok(HttpResponse::Ok().body(DownloadInfo {
|
||||
file: info,
|
||||
code,
|
||||
code: code.clone(),
|
||||
available: file.metadata().await?.len(),
|
||||
offsets,
|
||||
}.render().unwrap()))
|
||||
}
|
||||
}
|
||||
|
||||
fn not_found(
|
||||
#[derive(Deserialize)]
|
||||
struct InfoQuery {
|
||||
code: String,
|
||||
}
|
||||
|
||||
#[get("/info")]
|
||||
async fn download_info(
|
||||
req: HttpRequest,
|
||||
query: web::Query<InfoQuery>,
|
||||
data: web::Data<AppState>,
|
||||
) -> actix_web::Result<impl Responder> {
|
||||
let code = &query.code;
|
||||
if !store::is_valid_storage_code(code) {
|
||||
return not_found(req, data, true);
|
||||
}
|
||||
let info = data.file_store.read().await.lookup_file(code);
|
||||
let info = if let Some(i) = info {
|
||||
i
|
||||
} else {
|
||||
return not_found(req, data, true)
|
||||
};
|
||||
|
||||
let storage_path = data.config.storage_dir.join(code);
|
||||
let offsets = info.contents.as_deref().map(zip::file_data_offsets);
|
||||
Ok(web::Json(DownloadInfo {
|
||||
file: info,
|
||||
code: code.clone(),
|
||||
available: File::open(&storage_path).await?.metadata().await?.len(),
|
||||
offsets,
|
||||
}))
|
||||
}
|
||||
|
||||
fn not_found<T>(
|
||||
req: HttpRequest,
|
||||
data: web::Data<AppState>,
|
||||
report: bool,
|
||||
) -> actix_web::Result<HttpResponse> {
|
||||
) -> actix_web::Result<T> {
|
||||
if report {
|
||||
let ip_addr = get_ip_addr(&req, data.config.reverse_proxy);
|
||||
log_auth_failure(&ip_addr);
|
||||
}
|
||||
Ok(NamedFile::open(data.config.static_dir.join("404.html"))?
|
||||
Err(InternalError::from_response("Download not found", NamedFile::open(data.config.static_dir.join("404.html"))?
|
||||
.set_status_code(StatusCode::NOT_FOUND)
|
||||
.into_response(&req))
|
||||
.into_response(&req)).into())
|
||||
}
|
||||
|
||||
#[get("/upload")]
|
||||
|
@ -244,6 +279,7 @@ async fn main() -> std::io::Result<()> {
|
|||
Logger::default()
|
||||
})
|
||||
.service(handle_download)
|
||||
.service(download_info)
|
||||
.service(handle_upload)
|
||||
.service(check_upload_password)
|
||||
.service(upload_limits)
|
||||
|
|
11
src/zip.rs
11
src/zip.rs
|
@ -43,6 +43,17 @@ pub fn file_data_offset(files: &[UploadedFile], idx: usize) -> u64 {
|
|||
+ files[idx].name.len() as u64
|
||||
}
|
||||
|
||||
pub fn file_data_offsets(files: &[UploadedFile]) -> Vec<u64> {
|
||||
let mut offsets = Vec::new();
|
||||
let mut offset: u64 = 0;
|
||||
for file in files.iter() {
|
||||
offset += LOCAL_HEADER_SIZE_MINUS_FILENAME + file.name.len() as u64;
|
||||
offsets.push(offset);
|
||||
offset += file.size + DATA_DESCRIPTOR_SIZE;
|
||||
}
|
||||
offsets
|
||||
}
|
||||
|
||||
fn central_directory_size(files: &[UploadedFile]) -> u64 {
|
||||
let mut total = 0;
|
||||
for file in files.iter() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue