diff --git a/Cargo.lock b/Cargo.lock index c7e4e84..c6f6353 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -549,7 +549,7 @@ dependencies = [ [[package]] name = "datatrash" -version = "2.4.2" +version = "2.5.0" dependencies = [ "actix-files", "actix-governor", diff --git a/Cargo.toml b/Cargo.toml index e885163..cf5a755 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "datatrash" -version = "2.4.2" +version = "2.5.0" authors = ["neri"] edition = "2021" diff --git a/init-db.sql b/init-db.sql index a26699f..f594794 100644 --- a/init-db.sql +++ b/init-db.sql @@ -14,3 +14,4 @@ ALTER TABLE files ADD COLUMN IF NOT EXISTS content_type varchar(255) not null GENERATED ALWAYS AS (CASE WHEN kind = 'text' THEN 'text/plain' ELSE 'application/octet-stream' END) STORED; ALTER TABLE files ALTER COLUMN content_type DROP EXPRESSION IF EXISTS; ALTER TABLE files DROP COLUMN IF EXISTS kind; +ALTER TABLE files ALTER COLUMN file_name DROP NOT NULL; diff --git a/snippet/file_name.html.snippet b/snippet/file_name.html.snippet new file mode 100644 index 0000000..074c5b4 --- /dev/null +++ b/snippet/file_name.html.snippet @@ -0,0 +1 @@ +

{file_name}

\ No newline at end of file diff --git a/src/download.rs b/src/download.rs index ba30b95..f020c64 100644 --- a/src/download.rs +++ b/src/download.rs @@ -36,10 +36,14 @@ pub async fn download( let path = config.files_dir.join(&file_id); let mime = Mime::from_str(&content_type).unwrap_or(APPLICATION_OCTET_STREAM); + let computed_file_name = file_name.clone().unwrap_or_else(|| { + let extension = mime_relations::get_extension(&mime).unwrap_or("txt"); + format!("{file_id}.{extension}") + }); let mut response = match get_view_type(&req, &mime, &path, delete).await { - ViewType::Raw => build_file_response(false, &file_name, path, mime, &req), - ViewType::Download => build_file_response(true, &file_name, path, mime, &req), - ViewType::Html => build_html_response(&path, &config, &req).await, + ViewType::Raw => build_file_response(false, &computed_file_name, path, mime, &req), + ViewType::Download => build_file_response(true, &computed_file_name, path, mime, &req), + ViewType::Html => build_html_response(file_name.as_deref(), &path, &config, &req).await, }?; insert_cache_headers(&mut response, valid_till); @@ -59,7 +63,7 @@ pub async fn download( async fn load_file_info( id: &str, db: &web::Data>, -) -> Result<(String, String, OffsetDateTime, String, bool), Error> { +) -> Result<(String, Option, OffsetDateTime, String, bool), Error> { sqlx::query_as( "SELECT file_id, file_name, valid_till, content_type, delete_on_download from files WHERE file_id = $1", ) @@ -118,6 +122,7 @@ async fn get_file_size(file_path: &Path) -> u64 { } async fn build_html_response( + file_name: Option<&str>, path: &Path, config: &Config, req: &HttpRequest, @@ -126,7 +131,7 @@ async fn build_html_response( log::error!("file could not be read {:?}", file_err); error::ErrorInternalServerError("this file should be here but could not be found") })?; - let html_view = template::build_html_view_template(&content, req, config); + let html_view = template::build_html_view_template(&content, file_name, req, config); Ok(HttpResponse::Ok() .content_type(TEXT_HTML.to_string()) .body(html_view)) diff --git a/src/template.rs b/src/template.rs index b0b4791..28b8fc5 100644 --- a/src/template.rs +++ b/src/template.rs @@ -11,6 +11,7 @@ const INDEX_HTML: &str = include_str!("../template/index.html"); const AUTH_HIDE_JS: &str = include_str!("../template/auth-hide.js"); const AUTH_SNIPPET_HTML: &str = include_str!("../snippet/auth.html.snippet"); const MAX_SIZE_SNIPPET_HTML: &str = include_str!("../snippet/max_size.html.snippet"); +const FILE_NAME_SNIPPET_HTML: &str = include_str!("../snippet/file_name.html.snippet"); const ABUSE_SNIPPET_HTML: &str = include_str!("../snippet/abuse.html.snippet"); @@ -46,15 +47,26 @@ pub fn get_file_url(req: &HttpRequest, id: &str, name: Option<&str>) -> String { } } -pub fn build_html_view_template(content: &str, req: &HttpRequest, config: &Config) -> String { - let encoded = htmlescape::encode_minimal(content); +pub fn build_html_view_template( + content: &str, + file_name: Option<&str>, + req: &HttpRequest, + config: &Config, +) -> String { + let encoded_content = htmlescape::encode_minimal(content); + let name_snippet = file_name + .map(htmlescape::encode_minimal) + .map(|name| FILE_NAME_SNIPPET_HTML.replace("{file_name}", &name)) + .unwrap_or_default(); let html = if !content.trim().contains(['\n', '\r']) && Url::from_str(content.trim()).is_ok() { - let attribute_encoded = htmlescape::encode_attribute(content); + let attribute_encoded_content = htmlescape::encode_attribute(content); URL_VIEW_HTML - .replace("{link_content}", &encoded) - .replace("{link_attribute}", &attribute_encoded) + .replace("{link_content}", &encoded_content) + .replace("{link_attribute}", &attribute_encoded_content) } else { - TEXT_VIEW_HTML.replace("{text}", &encoded) + TEXT_VIEW_HTML + .replace("{file_name}", &name_snippet) + .replace("{text}", &encoded_content) }; insert_abuse_template(html, Some(req), config) } diff --git a/src/upload.rs b/src/upload.rs index 1551791..670b472 100644 --- a/src/upload.rs +++ b/src/upload.rs @@ -2,7 +2,7 @@ use std::io::ErrorKind; use crate::config::Config; use crate::multipart::UploadConfig; -use crate::{mime_relations, multipart, template}; +use crate::{multipart, template}; use actix_files::NamedFile; use actix_multipart::Multipart; use actix_web::http::header::LOCATION; @@ -39,12 +39,7 @@ pub async fn upload( })?; let upload_config = multipart::parse_multipart(payload, &file_path, &config).await?; - let file_name = upload_config.original_name.clone().unwrap_or_else(|| { - format!( - "{file_id}.{}", - mime_relations::get_extension(&upload_config.content_type).unwrap_or("txt") - ) - }); + let file_name = upload_config.original_name.clone(); insert_file_metadata(&file_id, file_name, &file_path, &upload_config, db).await?; @@ -67,7 +62,7 @@ pub async fn upload( async fn insert_file_metadata( file_id: &String, - file_name: String, + file_name: Option, file_path: &Path, upload_config: &UploadConfig, db: web::Data>, @@ -77,7 +72,7 @@ async fn insert_file_metadata( VALUES ($1, $2, $3, $4, $5)", ) .bind(file_id) - .bind(&file_name) + .bind(file_name) .bind(&upload_config.content_type.to_string()) .bind(upload_config.valid_till) .bind(upload_config.delete_on_download) diff --git a/static/index.css b/static/index.css index cfe61dd..37cc0df 100644 --- a/static/index.css +++ b/static/index.css @@ -108,11 +108,11 @@ a:focus-within { textarea { width: 100%; - height: 30vh; + height: 60vh; } -h1 + textarea { - height: 60vh; +form > textarea { + height: 30vh; } .hidden { diff --git a/template/text-view.html b/template/text-view.html index 9ce626c..6ff0c55 100644 --- a/template/text-view.html +++ b/template/text-view.html @@ -17,6 +17,7 @@

datatrash

+ {file_name}
herunterladen