allow downloading individual files from bundle
This commit is contained in:
parent
43d03869ab
commit
007289ffe5
15 changed files with 499 additions and 69 deletions
61
src/main.rs
61
src/main.rs
|
@ -1,9 +1,10 @@
|
|||
mod download;
|
||||
mod store;
|
||||
mod timestamp;
|
||||
mod upload;
|
||||
mod zip;
|
||||
|
||||
use std::{fmt::Debug, fs::File, path::PathBuf, str::FromStr};
|
||||
use std::{fmt::Debug, path::PathBuf, str::FromStr};
|
||||
|
||||
use actix_files::NamedFile;
|
||||
use actix_web::{
|
||||
|
@ -11,11 +12,12 @@ use actix_web::{
|
|||
HttpServer, Responder,
|
||||
};
|
||||
use actix_web_actors::ws;
|
||||
use askama::Template;
|
||||
use bytesize::ByteSize;
|
||||
use log::{error, warn};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use store::FileStore;
|
||||
use tokio::sync::RwLock;
|
||||
use store::{FileStore, StoredFile};
|
||||
use tokio::{fs::File, sync::RwLock};
|
||||
|
||||
const APP_NAME: &str = "transbeam";
|
||||
|
||||
|
@ -49,9 +51,19 @@ pub fn log_auth_failure(ip_addr: &str) {
|
|||
warn!("Incorrect authentication attempt from {}", ip_addr);
|
||||
}
|
||||
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct DownloadRequest {
|
||||
code: String,
|
||||
download: Option<download::DownloadSelection>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "download.html")]
|
||||
struct DownloadInfo<'a> {
|
||||
file: StoredFile,
|
||||
code: &'a str,
|
||||
available: u64,
|
||||
}
|
||||
|
||||
#[get("/download")]
|
||||
|
@ -62,29 +74,52 @@ async fn handle_download(
|
|||
) -> actix_web::Result<HttpResponse> {
|
||||
let code = &download.code;
|
||||
if !store::is_valid_storage_code(code) {
|
||||
return download_not_found(req, data);
|
||||
return not_found(req, data, true);
|
||||
}
|
||||
let info = data.file_store.read().await.lookup_file(code);
|
||||
if let Some(info) = info {
|
||||
let storage_path = data.config.storage_dir.join(code);
|
||||
let file = File::open(&storage_path)?;
|
||||
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 file = File::open(&storage_path).await?;
|
||||
if let Some(selection) = download.download {
|
||||
if let download::DownloadSelection::One(n) = selection {
|
||||
if let Some(ref files) = info.contents {
|
||||
if n >= files.len() {
|
||||
return not_found(req, data, false);
|
||||
}
|
||||
} else {
|
||||
return not_found(req, data, false);
|
||||
}
|
||||
}
|
||||
Ok(download::DownloadingFile {
|
||||
file,
|
||||
file: file.into_std().await,
|
||||
storage_path,
|
||||
info,
|
||||
selection,
|
||||
}
|
||||
.into_response(&req))
|
||||
.into_response(&req))
|
||||
} else {
|
||||
download_not_found(req, data)
|
||||
Ok(HttpResponse::Ok().body(DownloadInfo {
|
||||
file: info,
|
||||
code,
|
||||
available: file.metadata().await?.len(),
|
||||
}.render().unwrap()))
|
||||
}
|
||||
}
|
||||
|
||||
fn download_not_found(
|
||||
fn not_found(
|
||||
req: HttpRequest,
|
||||
data: web::Data<AppState>,
|
||||
report: bool,
|
||||
) -> actix_web::Result<HttpResponse> {
|
||||
let ip_addr = get_ip_addr(&req, data.config.reverse_proxy);
|
||||
log_auth_failure(&ip_addr);
|
||||
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"))?
|
||||
.set_status_code(StatusCode::NOT_FOUND)
|
||||
.into_response(&req))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue