limit text view to 512KiB, fix deleter sql query

This commit is contained in:
neri 2021-09-12 18:51:14 +02:00
parent dfd3387ac6
commit a065787487
2 changed files with 28 additions and 10 deletions

View File

@ -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) { 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 valid_till: Option<(NaiveDateTime,)> =
let row = rows sqlx::query_as("SELECT MIN(valid_till) as min from files")
.try_next() .fetch_optional(db)
.await .await
.expect("could not fetch expiring files from database") .expect("could not fetch expiring files from database");
.expect("postgres min did not return any row");
let valid_till: Option<NaiveDateTime> = row.get("min");
let next_timeout = match valid_till { 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), None => Duration::days(1),
}; };
let positive_timeout = next_timeout let positive_timeout = next_timeout

View File

@ -17,6 +17,8 @@ use crate::{config::Config, file_kind::FileKind};
const TEXT_VIEW_HTML: &str = include_str!("../template/text-view.html"); const TEXT_VIEW_HTML: &str = include_str!("../template/text-view.html");
const URL_VIEW_HTML: &str = include_str!("../template/url-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( pub async fn download(
req: HttpRequest, req: HttpRequest,
db: web::Data<PgPool>, db: web::Data<PgPool>,
@ -29,8 +31,7 @@ pub async fn download(
let download = delete_on_download || req.query_string().contains("dl"); let download = delete_on_download || req.query_string().contains("dl");
let content_type = get_content_type(&path); let content_type = get_content_type(&path);
let is_text = file_kind == FileKind::Text.to_string() || content_type.type_() == mime::TEXT; let response = if use_text_view(&file_kind, &content_type, &path, download).await {
let response = if is_text && !download {
build_text_response(&path).await build_text_response(&path).await
} else { } else {
build_file_response(download, &file_name, path, content_type, req) 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") .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<HttpResponse, Error> { async fn build_text_response(path: &Path) -> Result<HttpResponse, Error> {
let content = fs::read_to_string(path).await.map_err(|file_err| { let content = fs::read_to_string(path).await.map_err(|file_err| {
log::error!("file could not be read {:?}", file_err); log::error!("file could not be read {:?}", file_err);