diff --git a/src/config.rs b/src/config.rs index b293f4d..7029129 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,7 @@ use std::env; use std::path::PathBuf; +use std::str::FromStr; use time::ext::NumericalDuration; use time::Duration; use tokio::fs; @@ -25,7 +26,7 @@ pub struct NoAuthLimits { pub large_file_size: u64, } -pub async fn get_config() -> Config { +pub async fn from_env() -> Config { let max_file_size = env::var("UPLOAD_MAX_BYTES") .ok() .and_then(|variable| variable.parse().ok()) @@ -68,15 +69,15 @@ pub async fn get_config() -> Config { fn get_no_auth_limits() -> Option { match ( env::var("AUTH_PASSWORD").ok(), - env_number("NO_AUTH_MAX_TIME"), - env_number("NO_AUTH_LARGE_FILE_MAX_TIME"), + env_number::("NO_AUTH_MAX_TIME"), + env_number::("NO_AUTH_LARGE_FILE_MAX_TIME"), env_number("NO_AUTH_LARGE_FILE_SIZE"), ) { (Some(auth_password), Some(max_time), Some(large_file_max_time), Some(large_file_size)) => { Some(NoAuthLimits { auth_password, - max_time: (max_time as i64).seconds(), - large_file_max_time: (large_file_max_time as i64).seconds(), + max_time: max_time.seconds(), + large_file_max_time: large_file_max_time.seconds(), large_file_size, }) } @@ -87,6 +88,6 @@ fn get_no_auth_limits() -> Option { } } -fn env_number(variable: &str) -> Option { - env::var(variable).ok().and_then(|n| n.parse::().ok()) +fn env_number(variable: &str) -> Option { + env::var(variable).ok().and_then(|n| n.parse::().ok()) } diff --git a/src/db.rs b/src/db.rs index a00359f..8c52de0 100644 --- a/src/db.rs +++ b/src/db.rs @@ -2,7 +2,7 @@ use sqlx::postgres::{PgPool, PgPoolOptions}; use std::env; use time::ext::NumericalStdDuration; -pub async fn setup_db() -> PgPool { +pub async fn setup() -> PgPool { let conn_url = &get_db_url(); log::info!("Using Connection string {}", conn_url); diff --git a/src/download.rs b/src/download.rs index fbb5fb2..a6a8537 100644 --- a/src/download.rs +++ b/src/download.rs @@ -42,8 +42,8 @@ pub async fn download( let mime = Mime::from_str(&content_type).unwrap_or(APPLICATION_OCTET_STREAM); let mut response = match get_view_type(&req, &mime, &path, delete).await { - ViewType::Raw => build_file_response(false, &file_name, path, mime, &req).await, - ViewType::Download => build_file_response(true, &file_name, path, mime, &req).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_text_response(&path).await, }?; @@ -141,7 +141,7 @@ async fn build_text_response(path: &Path) -> Result { .body(html)) } -async fn build_file_response( +fn build_file_response( download: bool, file_name: &str, path: PathBuf, @@ -196,7 +196,7 @@ fn get_disposition_params(filename: &str) -> Vec { charset: Charset::Ext(String::from("UTF-8")), language_tag: None, value: filename.to_owned().into_bytes(), - })) + })); } parameters } @@ -204,7 +204,8 @@ fn get_disposition_params(filename: &str) -> Vec { fn insert_cache_headers(response: &mut HttpResponse, valid_till: OffsetDateTime) { if response.status().is_success() { let valid_duration = valid_till - OffsetDateTime::now_utc(); - let valid_cache_seconds = valid_duration.whole_seconds().clamp(0, u32::MAX as i64) as u32; + let valid_cache_seconds = + valid_duration.whole_seconds().clamp(0, i64::from(u32::MAX)) as u32; response.headers_mut().insert( CACHE_CONTROL, CacheControl(vec![ diff --git a/src/main.rs b/src/main.rs index cc9aa5c..0dc17d3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,8 +37,8 @@ async fn not_found() -> Result { async fn main() -> std::io::Result<()> { env_logger::Builder::from_env(Env::default().default_filter_or("info,sqlx=warn")).init(); - let pool: PgPool = db::setup_db().await; - let config = config::get_config().await; + let pool: PgPool = db::setup().await; + let config = config::from_env().await; let (sender, receiver) = channel(8); log::info!("omnomnom"); diff --git a/src/mime_relations.rs b/src/mime_relations.rs index b5f3051..a20d482 100644 --- a/src/mime_relations.rs +++ b/src/mime_relations.rs @@ -15,16 +15,16 @@ lazy_static! { fn load_mime_aliases() -> HashMap { tree_magic_db::aliases() .lines() - .flat_map(|line| line.split_once(' ')) - .flat_map(|(alias, mime)| Some((Mime::from_str(alias).ok()?, Mime::from_str(mime).ok()?))) + .filter_map(|line| line.split_once(' ')) + .filter_map(|(alias, mime)| Some((Mime::from_str(alias).ok()?, Mime::from_str(mime).ok()?))) .collect() } fn load_mime_parent_relations() -> Vec<(Mime, Mime)> { tree_magic_db::subclasses() .lines() - .flat_map(|line| line.split_once(' ')) - .flat_map(|(child, parent)| { + .filter_map(|line| line.split_once(' ')) + .filter_map(|(child, parent)| { Some((Mime::from_str(child).ok()?, Mime::from_str(parent).ok()?)) }) .collect() @@ -34,11 +34,9 @@ fn load_mime_extensions() -> HashMap { include_str!("../mime.types") .lines() .filter(|line| !line.is_empty() && !line.starts_with('#')) - .map(|line| line.split_whitespace()) - .flat_map(|mut elements| Some((Mime::from_str(elements.next()?).ok()?, elements.next()?))) - .flat_map(|(mime, extension)| { - Some((ALIASES.get(&mime).unwrap_or(&mime).clone(), extension)) - }) + .map(str::split_whitespace) + .filter_map(|mut elements| Some((Mime::from_str(elements.next()?).ok()?, elements.next()?))) + .map(|(mime, extension)| (ALIASES.get(&mime).cloned().unwrap_or(mime), extension)) .collect() } diff --git a/src/multipart.rs b/src/multipart.rs index 0fa4a3e..4092b30 100644 --- a/src/multipart.rs +++ b/src/multipart.rs @@ -32,16 +32,15 @@ pub(crate) async fn parse_multipart( let mut password = None; let mut size = 0; - while let Ok(Some(field)) = payload.try_next().await { - let name = get_field_name(&field)?; - let name = name.as_str(); - match name { + while let Ok(Some(mut field)) = payload.try_next().await { + let name = get_field_name(&field)?.to_owned(); + match name.as_str() { "keep_for" => { - keep_for_seconds = Some(parse_string(name, field).await?); + keep_for_seconds = Some(parse_string(&name, &mut field).await?); } "file" => { let (mime, uploaded_name) = get_file_metadata(&field); - if uploaded_name == None || uploaded_name.as_deref() == Some("") { + if uploaded_name.is_none() || uploaded_name.as_deref() == Some("") { continue; } original_name = uploaded_name; @@ -62,10 +61,10 @@ pub(crate) async fn parse_multipart( content_type = Some(get_content_type(&first_bytes)); } "delete_on_download" => { - delete_on_download = parse_string(name, field).await? != "false"; + delete_on_download = parse_string(&name, &mut field).await? != "false"; } "password" => { - password = Some(parse_string(name, field).await?); + password = Some(parse_string(&name, &mut field).await?); } _ => {} }; @@ -77,8 +76,7 @@ pub(crate) async fn parse_multipart( .map(|k| k.parse()) .transpose() .map_err(|e| error::ErrorBadRequest(format!("field keep_for is not a number: {e}")))? - .map(Duration::seconds) - .unwrap_or(DEFAULT_UPLOAD_DURATION); + .map_or(DEFAULT_UPLOAD_DURATION, Duration::seconds); let valid_till = OffsetDateTime::now_utc() + keep_for; let upload_config = UploadConfig { @@ -88,7 +86,7 @@ pub(crate) async fn parse_multipart( delete_on_download, }; - check_requirements(&upload_config, size, password, &keep_for, config)?; + check_requirements(&upload_config, size, &password, &keep_for, config)?; Ok(upload_config) } @@ -96,7 +94,7 @@ pub(crate) async fn parse_multipart( fn check_requirements( upload_config: &UploadConfig, size: u64, - password: Option, + password: &Option, keep_for: &Duration, config: &config::Config, ) -> Result<(), error::Error> { @@ -127,21 +125,23 @@ fn check_requirements( Ok(()) } -fn get_field_name(field: &Field) -> Result { +fn get_field_name(field: &Field) -> Result<&str, error::Error> { Ok(field .content_disposition() .get_name() - .map(|s| s.to_owned()) .ok_or(error::ParseError::Incomplete)?) } -async fn parse_string(name: &str, field: actix_multipart::Field) -> Result { +async fn parse_string( + name: &str, + field: &mut actix_multipart::Field, +) -> Result { let data = read_content(field).await?; String::from_utf8(data) .map_err(|_| error::ErrorBadRequest(format!("could not parse field {name} as utf-8"))) } -async fn read_content(mut field: actix_multipart::Field) -> Result, error::Error> { +async fn read_content(field: &mut actix_multipart::Field) -> Result, error::Error> { let mut data = Vec::new(); while let Some(chunk) = field.try_next().await.map_err(error::ErrorBadRequest)? { data.extend(chunk); diff --git a/src/template.rs b/src/template.rs index aa02594..25b9edf 100644 --- a/src/template.rs +++ b/src/template.rs @@ -52,7 +52,7 @@ fn build_index_html(config: &Config) -> String { .replace("{max_size_snippet}", MAX_SIZE_SNIPPET_HTML.trim_end()) .replace("{max_size}", &render_file_size(max_file_size)); } else { - html = html.replace("{max_size_snippet}", "") + html = html.replace("{max_size_snippet}", ""); }; html }