diff --git a/src/main.rs b/src/main.rs index c0a0294..f7a4711 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use actix_files::{Files, NamedFile}; use actix_multipart::Multipart; use actix_web::{ error, - http::header::{ContentDisposition, DispositionParam, DispositionType}, + http::header::{ContentDisposition, DispositionParam, DispositionType, ACCEPT}, middleware, web::{self, Bytes}, App, Error, FromRequest, HttpRequest, HttpResponse, HttpServer, @@ -24,16 +24,23 @@ use sqlx::{ }; use std::env; +const INDEX_HTML: &str = include_str!("../template/index.html"); const UPLOAD_HTML: &str = include_str!("../template/upload.html"); const VIEW_HTML: &str = include_str!("../template/view.html"); -async fn index() -> Result { - Ok(NamedFile::open("./static/index.html") - .map_err(|_| error::ErrorNotFound(""))? - .disable_content_disposition()) +async fn index(req: web::HttpRequest) -> Result { + let upload_url = format!("{}/upload", get_host_url(&req)); + let index_html = INDEX_HTML.replace("{upload_url}", upload_url.as_str()); + Ok(HttpResponse::Ok() + .content_type("text/html") + .body(index_html)) } +// multipart data +// required: either 'file' or 'text' +// optional: 'keep_for' default to 30 minutes async fn upload( + req: web::HttpRequest, payload: Multipart, db: web::Data, expiry_watch_sender: web::Data>, @@ -88,24 +95,34 @@ async fn upload( expiry_watch_sender.send(()).await; let redirect = if kind == FileKind::BINARY && original_name.is_some() { - format!("/upload/{}/{}", file_id, original_name.unwrap()) + format!("/upload/{}/{}", file_id, original_name.as_ref().unwrap()) } else { format!("/upload/{}", file_id) }; + + let url = get_file_url(&req, &file_id, original_name.as_deref()); Ok(HttpResponse::SeeOther() .header("location", redirect) - .finish()) + .body(format!("{}\n", url))) +} + +fn get_host_url(req: &web::HttpRequest) -> String { + let conn = req.connection_info(); + format!("{}://{}", conn.scheme(), conn.host()) +} + +fn get_file_url(req: &web::HttpRequest, id: &str, name: Option<&str>) -> String { + if let Some(name) = name { + format!("{}/file/{}/{}", get_host_url(req), id, name) + } else { + format!("{}/file/{}", get_host_url(req), id) + } } async fn uploaded(req: web::HttpRequest) -> Result { let id = req.match_info().query("id"); let name = req.match_info().get("name"); - let conn = req.connection_info(); - let url = if let Some(name) = name { - format!("{}://{}/file/{}/{}", conn.scheme(), conn.host(), id, name) - } else { - format!("{}://{}/file/{}", conn.scheme(), conn.host(), id) - }; + let url = get_file_url(&req, id, name); let upload_html = UPLOAD_HTML.replace("{url}", url.as_str()); Ok(HttpResponse::Ok() .content_type("text/html") diff --git a/src/multipart.rs b/src/multipart.rs index f83bc54..5103f9b 100644 --- a/src/multipart.rs +++ b/src/multipart.rs @@ -11,17 +11,17 @@ pub(crate) async fn parse_multipart( filename: &Path, ) -> Result<(Option, DateTime, FileKind), error::Error> { let mut original_name: Option = None; - let mut timeout: Option = None; + let mut keep_for: Option = None; let mut kind: Option = None; while let Ok(Some(field)) = payload.try_next().await { let name = get_field_name(&field)?; let name = name.as_str(); match name { - "validity_secs" => { - timeout = Some(parse_string(name, field).await?); + "keep_for" => { + keep_for = Some(parse_string(name, field).await?); } - "content" => { + "file" => { let file_original_name = get_original_filename(&field); if file_original_name == None || file_original_name.as_deref() == Some("") { continue; @@ -35,7 +35,7 @@ pub(crate) async fn parse_multipart( .await .map_err(|_| error::ErrorInternalServerError("could not write file"))?; } - "text_content" => { + "text" => { if original_name.is_some() { continue; } @@ -58,12 +58,11 @@ pub(crate) async fn parse_multipart( } } - let validity_secs = timeout - .ok_or_else(|| error::ErrorBadRequest("field validity_secs not set"))? - .parse() - .map_err(|e| { - error::ErrorBadRequest(format!("field validity_secs is not a number: {}", e)) - })?; + let validity_secs = keep_for + .map(|timeout| timeout.parse()) + .transpose() + .map_err(|e| error::ErrorBadRequest(format!("field validity_secs is not a number: {}", e)))? + .unwrap_or(1800); // default to 30 minutes let max_validity_secs = Duration::days(31).num_seconds(); if validity_secs > max_validity_secs { return Err(error::ErrorBadRequest(format!( diff --git a/static/copy.js b/static/copy.js new file mode 100644 index 0000000..6604c47 --- /dev/null +++ b/static/copy.js @@ -0,0 +1,16 @@ +const button = document.getElementById("copy"); +button.onclick = () => { + if (!navigator.clipboard) { + button.innerText = "nicht unterstützt"; + return; + } + const content = document.getElementsByClassName("copy-content")[0]; + navigator.clipboard.writeText(content.textContent).then( + (_) => { + button.innerText = "kopiert!"; + }, + (_) => { + button.innerText = "nicht unterstützt"; + } + ); +}; diff --git a/static/index.css b/static/index.css index 0ac5067..51c5fd8 100644 --- a/static/index.css +++ b/static/index.css @@ -71,3 +71,7 @@ a.button:visited { .button.main:hover { background-color: forestgreen; } + +.usage { + margin-top: 2em; +} diff --git a/static/index.html b/template/index.html similarity index 66% rename from static/index.html rename to template/index.html index aa1ecec..02016d7 100644 --- a/static/index.html +++ b/template/index.html @@ -12,20 +12,15 @@

datatrash

-
- +
+
-
-
- - +
+ +
+
+
+file upload
+  curl -F 'file=@yourfile.rs' {upload_url}
+text upload
+  curl -F 'text=your text' {upload_url}
+including time
+  curl -F 'text=your text' -F 'keep_for=1800' {upload_url}
+        
+
diff --git a/template/upload.html b/template/upload.html index f73c179..4ef9612 100644 --- a/template/upload.html +++ b/template/upload.html @@ -11,27 +11,10 @@

datatrash

datei-link: - - {url} - + {url}

- + - + diff --git a/template/view.html b/template/view.html index 2ec3fe3..dfeb3a6 100644 --- a/template/view.html +++ b/template/view.html @@ -9,26 +9,13 @@

datatrash

- +
herunterladen - +
- +