v0.2.8 file extension update
This commit is contained in:
parent
ea4f2a828c
commit
022512884a
|
@ -224,7 +224,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "breeze"
|
name = "breeze"
|
||||||
version = "0.2.7"
|
version = "0.2.8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"argh",
|
"argh",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "breeze"
|
name = "breeze"
|
||||||
version = "0.2.7"
|
version = "0.2.8"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
@ -240,13 +240,13 @@ impl Engine {
|
||||||
/// Generate a new saved name for an upload.
|
/// Generate a new saved name for an upload.
|
||||||
///
|
///
|
||||||
/// If it picks a name that already exists, it will try again.
|
/// If it picks a name that already exists, it will try again.
|
||||||
pub async fn gen_saved_name(&self, ext: &str) -> String {
|
pub async fn gen_saved_name(&self, ext: Option<String>) -> String {
|
||||||
loop {
|
loop {
|
||||||
// generate a 6-character alphanumeric string
|
// generate a 6-character alphanumeric string
|
||||||
let mut saved_name: String = Alphanumeric.sample_string(&mut rand::thread_rng(), 6);
|
let mut saved_name: String = Alphanumeric.sample_string(&mut rand::thread_rng(), 6);
|
||||||
|
|
||||||
// if we have an extension, add it now
|
// if we have an extension, add it now
|
||||||
if !ext.is_empty() {
|
if let Some(ref ext) = ext {
|
||||||
saved_name.push('.');
|
saved_name.push('.');
|
||||||
saved_name.push_str(ext);
|
saved_name.push_str(ext);
|
||||||
}
|
}
|
||||||
|
@ -389,7 +389,7 @@ impl Engine {
|
||||||
|
|
||||||
pub async fn process(
|
pub async fn process(
|
||||||
&self,
|
&self,
|
||||||
ext: &str,
|
ext: Option<String>,
|
||||||
provided_len: u64,
|
provided_len: u64,
|
||||||
stream: BodyDataStream,
|
stream: BodyDataStream,
|
||||||
lifetime: Option<Duration>,
|
lifetime: Option<Duration>,
|
||||||
|
|
52
src/new.rs
52
src/new.rs
|
@ -1,4 +1,9 @@
|
||||||
use std::{ffi::OsStr, path::PathBuf, sync::Arc, time::Duration};
|
use std::{
|
||||||
|
ffi::OsStr,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
sync::Arc,
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
body::Body,
|
body::Body,
|
||||||
|
@ -32,7 +37,6 @@ pub struct NewRequest {
|
||||||
|
|
||||||
/// The request handler for the /new path.
|
/// The request handler for the /new path.
|
||||||
/// This handles all new uploads.
|
/// This handles all new uploads.
|
||||||
#[axum::debug_handler]
|
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
State(engine): State<Arc<crate::engine::Engine>>,
|
State(engine): State<Arc<crate::engine::Engine>>,
|
||||||
Query(req): Query<NewRequest>,
|
Query(req): Query<NewRequest>,
|
||||||
|
@ -49,11 +53,37 @@ pub async fn new(
|
||||||
return Err(StatusCode::BAD_REQUEST);
|
return Err(StatusCode::BAD_REQUEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
let extension = PathBuf::from(req.name)
|
// -- try to figure out a file extension..
|
||||||
.extension()
|
|
||||||
.and_then(OsStr::to_str)
|
fn extension(pb: &Path) -> Option<String> {
|
||||||
.unwrap_or_default()
|
pb.extension().and_then(OsStr::to_str).map(str::to_string)
|
||||||
.to_string();
|
}
|
||||||
|
|
||||||
|
let pb = PathBuf::from(req.name);
|
||||||
|
let mut ext = extension(&pb);
|
||||||
|
|
||||||
|
// common extensions that usually have a second extension before themselves
|
||||||
|
const ADDITIVE: &[&str] = &["gz", "xz", "bz2", "lz4", "zst"];
|
||||||
|
|
||||||
|
// if the extension is one of those, try to find that second extension
|
||||||
|
if ext
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|ext| ADDITIVE.contains(&ext.as_str()))
|
||||||
|
{
|
||||||
|
// try to parse out another extension
|
||||||
|
let stem = pb.file_stem().unwrap(); // SAFETY: if extension is Some(), this will also be
|
||||||
|
|
||||||
|
if let Some(second_ext) = extension(&PathBuf::from(stem)) {
|
||||||
|
// there is another extension,
|
||||||
|
// try to make sure it's one we want
|
||||||
|
// 4 is enough for most common file extensions
|
||||||
|
// and not many false positives, hopefully
|
||||||
|
if second_ext.len() <= 4 {
|
||||||
|
// seems ok so combine them
|
||||||
|
ext = ext.as_ref().map(|first_ext| second_ext + "." + first_ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// turn body into stream
|
// turn body into stream
|
||||||
let stream = Body::into_data_stream(body);
|
let stream = Body::into_data_stream(body);
|
||||||
|
@ -64,13 +94,7 @@ pub async fn new(
|
||||||
// they don't expect the connection to close before they're done uploading, i think
|
// they don't expect the connection to close before they're done uploading, i think
|
||||||
// so it will just present the user with a "connection closed" error
|
// so it will just present the user with a "connection closed" error
|
||||||
match engine
|
match engine
|
||||||
.process(
|
.process(ext, content_length, stream, req.last_for, req.keep_exif)
|
||||||
&extension,
|
|
||||||
content_length,
|
|
||||||
stream,
|
|
||||||
req.last_for,
|
|
||||||
req.keep_exif,
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(outcome) => match outcome {
|
Ok(outcome) => match outcome {
|
||||||
|
|
|
@ -86,7 +86,6 @@ impl IntoResponse for UploadResponse {
|
||||||
|
|
||||||
/// GET request handler for /p/* path.
|
/// GET request handler for /p/* path.
|
||||||
/// All file views are handled here.
|
/// All file views are handled here.
|
||||||
#[axum::debug_handler]
|
|
||||||
pub async fn view(
|
pub async fn view(
|
||||||
State(engine): State<Arc<crate::engine::Engine>>,
|
State(engine): State<Arc<crate::engine::Engine>>,
|
||||||
Path(original_path): Path<PathBuf>,
|
Path(original_path): Path<PathBuf>,
|
||||||
|
|
Loading…
Reference in New Issue