ttl parsing

This commit is contained in:
Paul Zinselmeyer 2023-10-20 15:24:38 +02:00
parent 5af5bb3e95
commit 9daacaf406
3 changed files with 61 additions and 10 deletions

47
Cargo.lock generated
View file

@ -76,6 +76,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "arrayvec"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
[[package]] [[package]]
name = "async-trait" name = "async-trait"
version = "0.1.74" version = "0.1.74"
@ -243,6 +249,7 @@ dependencies = [
"bytes", "bytes",
"chacha20", "chacha20",
"dotenvy", "dotenvy",
"duration-str",
"env_logger", "env_logger",
"futures-util", "futures-util",
"hex", "hex",
@ -529,6 +536,20 @@ version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
name = "duration-str"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e172e85f305d6a442b250bf40667ffcb91a24f52c9a1ca59e2fa991ac9b7790"
dependencies = [
"chrono",
"nom",
"rust_decimal",
"serde",
"thiserror",
"time",
]
[[package]] [[package]]
name = "dyn-clone" name = "dyn-clone"
version = "1.0.14" version = "1.0.14"
@ -1154,6 +1175,12 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.7.1" version = "0.7.1"
@ -1192,6 +1219,16 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]] [[package]]
name = "num-bigint" name = "num-bigint"
version = "0.4.4" version = "0.4.4"
@ -1728,6 +1765,16 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "rust_decimal"
version = "1.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c4216490d5a413bc6d10fa4742bd7d4955941d062c0ef873141d6b0e7b30fd"
dependencies = [
"arrayvec",
"num-traits",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.23" version = "0.1.23"

View file

@ -12,6 +12,7 @@ futures-util = "0.3"
axum = {version="0.6", features=["macros", "headers", "multipart"]} axum = {version="0.6", features=["macros", "headers", "multipart"]}
serde = "1.0" serde = "1.0"
toml = "0.8" toml = "0.8"
duration-str = "0.7.0"
render = { git="https://github.com/render-rs/render.rs" } render = { git="https://github.com/render-rs/render.rs" }
thiserror = "1.0" thiserror = "1.0"
rand = "0.8" rand = "0.8"

View file

@ -1,9 +1,10 @@
#![deny(clippy::unwrap_used)] #![deny(clippy::unwrap_used)]
use duration_str::{deserialize_option_duration, parse_std};
use std::{ use std::{
borrow::Borrow, borrow::Borrow,
env, env,
str::FromStr, str::FromStr,
time::{SystemTime, UNIX_EPOCH}, time::{Duration, SystemTime, UNIX_EPOCH},
}; };
use axum::{ use axum::{
@ -196,7 +197,8 @@ async fn get_index(
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct PostQuery { pub struct PostQuery {
ttl: Option<u64>, #[serde(deserialize_with = "deserialize_option_duration")]
ttl: Option<Duration>,
} }
async fn post_item( async fn post_item(
@ -226,7 +228,7 @@ async fn post_item(
let mut etag_hasher = Sha3_256::new(); let mut etag_hasher = Sha3_256::new();
let mut size: u64 = 0; let mut size: u64 = 0;
let mut ttl = params.ttl.unwrap_or(24 * 3600); let mut ttl = params.ttl.unwrap_or(Duration::from_secs(24 * 3600));
match data { match data {
MultipartOrStream::Stream(mut stream) => { MultipartOrStream::Stream(mut stream) => {
@ -267,7 +269,7 @@ async fn post_item(
} }
if field.name().unwrap_or_default() == "ttl" { if field.name().unwrap_or_default() == "ttl" {
if let Some(mp_ttl) = if let Some(mp_ttl) =
field.text().await.ok().and_then(|x| x.parse::<u64>().ok()) field.text().await.ok().and_then(|x| parse_std(x).ok())
{ {
ttl = mp_ttl; ttl = mp_ttl;
} }
@ -277,16 +279,17 @@ async fn post_item(
} }
writer.flush().await?; writer.flush().await?;
let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs(); if let Some(expires_at) = SystemTime::now()
let expires_at = match u64::MAX - ttl > now { .duration_since(UNIX_EPOCH)?
true => now + ttl, .checked_add(ttl)
false => u64::MAX, .map(|x| x.as_secs())
}; {
metadata.expires_at = expires_at;
}
metadata.etag = Some(hex::encode(etag_hasher.finalize())); metadata.etag = Some(hex::encode(etag_hasher.finalize()));
metadata.size = Some(size); metadata.size = Some(size);
metadata.expires_at = expires_at;
metadata.to_file(&metadata_path).await?; metadata.to_file(&metadata_path).await?;
app_state app_state