From a065787487772649898f961f230b64881f1c7091 Mon Sep 17 00:00:00 2001 From: neri Date: Sun, 12 Sep 2021 18:51:14 +0200 Subject: [PATCH] limit text view to 512KiB, fix deleter sql query --- src/deleter.rs | 14 ++++++-------- src/download.rs | 24 ++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/deleter.rs b/src/deleter.rs index 2a26bd2..39e3ed0 100644 --- a/src/deleter.rs +++ b/src/deleter.rs @@ -54,15 +54,13 @@ async fn delete_content(file_id: &str, files_dir: &Path) -> Result<(), std::io:: } async fn wait_for_file_expiry(receiver: &Receiver<()>, db: &PgPool) { - let mut rows = sqlx::query("SELECT MIN(valid_till) as min from files").fetch(db); - let row = rows - .try_next() - .await - .expect("could not fetch expiring files from database") - .expect("postgres min did not return any row"); - let valid_till: Option = row.get("min"); + let valid_till: Option<(NaiveDateTime,)> = + sqlx::query_as("SELECT MIN(valid_till) as min from files") + .fetch_optional(db) + .await + .expect("could not fetch expiring files from database"); let next_timeout = match valid_till { - Some(valid_till) => valid_till.signed_duration_since(Local::now().naive_local()), + Some((valid_till,)) => valid_till.signed_duration_since(Local::now().naive_local()), None => Duration::days(1), }; let positive_timeout = next_timeout diff --git a/src/download.rs b/src/download.rs index da72bfe..002b35d 100644 --- a/src/download.rs +++ b/src/download.rs @@ -17,6 +17,8 @@ use crate::{config::Config, file_kind::FileKind}; const TEXT_VIEW_HTML: &str = include_str!("../template/text-view.html"); const URL_VIEW_HTML: &str = include_str!("../template/url-view.html"); +const TEXT_VIEW_SIZE_LIMIT: u64 = 512 * 1024; // 512KiB + pub async fn download( req: HttpRequest, db: web::Data, @@ -29,8 +31,7 @@ pub async fn download( let download = delete_on_download || req.query_string().contains("dl"); let content_type = get_content_type(&path); - let is_text = file_kind == FileKind::Text.to_string() || content_type.type_() == mime::TEXT; - let response = if is_text && !download { + let response = if use_text_view(&file_kind, &content_type, &path, download).await { build_text_response(&path).await } else { build_file_response(download, &file_name, path, content_type, req) @@ -71,6 +72,25 @@ fn get_content_type(path: &Path) -> Mime { .expect("tree_magic_mini should not produce invalid mime") } +async fn use_text_view( + file_kind: &str, + content_type: &Mime, + file_path: &Path, + download: bool, +) -> bool { + let is_text = + FileKind::from_str(file_kind) == Ok(FileKind::Text) || content_type.type_() == mime::TEXT; + let is_not_large = get_file_size(file_path).await < TEXT_VIEW_SIZE_LIMIT; + is_text && is_not_large && !download +} + +async fn get_file_size(file_path: &Path) -> u64 { + fs::metadata(file_path) + .await + .map(|metadata| metadata.len()) + .unwrap_or(0) +} + async fn build_text_response(path: &Path) -> Result { let content = fs::read_to_string(path).await.map_err(|file_err| { log::error!("file could not be read {:?}", file_err);