From ca0fccb01986ec4df5f2cfdf4818cad74d0b27d7 Mon Sep 17 00:00:00 2001 From: blek Date: Fri, 13 Oct 2023 09:44:55 +1000 Subject: [PATCH] delete file after download --- filed/Cargo.lock | 20 ++++++++++++++++++++ filed/Cargo.toml | 2 +- filed/src/files/mod.rs | 29 +++++++++++++++++++++++++++-- filed/src/web/mod.rs | 2 +- filed/src/web/uploaded.rs | 22 ++++++++++++++++++---- 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/filed/Cargo.lock b/filed/Cargo.lock index b2d1ea5..00c3f08 100644 --- a/filed/Cargo.lock +++ b/filed/Cargo.lock @@ -73,6 +73,17 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" +[[package]] +name = "async-trait" +version = "0.1.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -173,7 +184,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" dependencies = [ "bytes", + "futures-core", "memchr", + "pin-project-lite", + "tokio", + "tokio-util", ] [[package]] @@ -891,13 +906,18 @@ version = "0.23.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f49cdc0bb3f412bf8e7d1bd90fe1d9eb10bc5c399ba90973c14662a27b3f8ba" dependencies = [ + "async-trait", + "bytes", "combine", + "futures-util", "itoa", "percent-encoding", + "pin-project-lite", "ryu", "sha1_smol", "socket2 0.4.9", "tokio", + "tokio-util", "url", ] diff --git a/filed/Cargo.toml b/filed/Cargo.toml index deacc7b..936abf2 100644 --- a/filed/Cargo.toml +++ b/filed/Cargo.toml @@ -15,7 +15,7 @@ futures-util = "0.3.28" hex = "0.4.3" log = "0.4.20" num = { version = "0.4.1", features = ["serde"] } -redis = { version = "0.23.3", features = ["tokio"] } +redis = { version = "0.23.3", features = ["tokio", "tokio-comp"] } serde = { version = "1.0.188", features = ["derive"] } serde_json = "1.0.107" sha2 = "0.10.8" diff --git a/filed/src/files/mod.rs b/filed/src/files/mod.rs index 694167b..a392e06 100644 --- a/filed/src/files/mod.rs +++ b/filed/src/files/mod.rs @@ -3,11 +3,12 @@ use std::{sync::Arc, error::Error, ops::Add}; use chrono::{DateTime, Local}; +use redis::AsyncCommands; use sha2::{Sha512, Digest, digest::FixedOutput}; use serde::{Serialize, Deserialize}; -use tokio::fs; +use tokio::{fs, join}; -use crate::env::Env; +use crate::{env::Env, web::state::SharedState}; pub mod lookup; @@ -33,6 +34,30 @@ impl File { self.delete_at < chrono::Local::now() } + pub fn get_redis_key(self: &Self, prefix: String) -> String { + format!( + "{}{}{}", + prefix, + match self.name { + Some(_) => "-name-", + None => "-hash-" + }, + self.clone().name.unwrap_or(self.hash()) + ) + } + + pub async fn delete(self: &Self, state: SharedState) -> Result<(), Box> { + let mut redis = state.redis_cli.get_tokio_connection().await?; + let (r1, r2) = join!( + tokio::fs::remove_file(self.path.clone()), + redis.del::(self.get_redis_key(state.env.redis.prefix)) + ); + + r1?; r2?; + + Ok(()) + } + pub fn comp_hash(self: &Self, other: &Sha512) -> bool { let mut hash = other.clone(); hex::encode(hash.finalize_fixed()) == self.sha512 diff --git a/filed/src/web/mod.rs b/filed/src/web/mod.rs index 7a0b81c..8645279 100644 --- a/filed/src/web/mod.rs +++ b/filed/src/web/mod.rs @@ -11,7 +11,7 @@ use crate::{env::Env, files::lookup::FileManager}; mod pages; mod forms; -mod state; +pub mod state; mod rejection; mod api; mod uploaded; diff --git a/filed/src/web/uploaded.rs b/filed/src/web/uploaded.rs index acaa222..f69c5b2 100644 --- a/filed/src/web/uploaded.rs +++ b/filed/src/web/uploaded.rs @@ -1,14 +1,16 @@ use warp::{Filter, reply::Reply, reject::Rejection}; +use crate::files::DeleteMode; + use super::{state::SharedState, rejection::HttpReject}; -pub async fn uploaded((file, _state): (String, SharedState)) -> Result, Rejection> { +pub async fn uploaded((file, state): (String, SharedState)) -> Result, Rejection> { - let mut file_res = _state.file_mgr.find_by_hash(file.clone()) + let mut file_res = state.file_mgr.find_by_hash(file.clone()) .map_err(|x| warp::reject::custom(HttpReject::StringError(x.to_string())))?; if file_res.is_none() { - file_res = _state.file_mgr.find_by_name(file.clone()) + file_res = state.file_mgr.find_by_name(file.clone()) .map_err(|x| warp::reject::custom(HttpReject::StringError(x.to_string())))?; } @@ -18,11 +20,23 @@ pub async fn uploaded((file, _state): (String, SharedState)) -> Result { + if file_res.expired() { + let _ = file_res.delete(state.clone()).await; + } + }, + DeleteMode::TimeOrDownload => { + let _ = file_res.delete(state.clone()).await; + } + } Ok( Box::new( warp::reply::with_header( - file_res.read_unchecked().await.unwrap(), + data, "Content-Type", file_res.mime ) )