forked from neri/datatrash
determine corrext file extension for text uploads
This commit is contained in:
parent
f6628e63da
commit
d7b6d31198
File diff suppressed because it is too large
Load Diff
|
@ -41,8 +41,7 @@ pub async fn download(
|
|||
path.push(&file_id);
|
||||
|
||||
let mime = Mime::from_str(&content_type).unwrap_or(APPLICATION_OCTET_STREAM);
|
||||
let mime = mime_relations::get_alias(&mime);
|
||||
let mut response = match get_view_type(&req, mime, &path, delete).await {
|
||||
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::Html => build_text_response(&path).await,
|
||||
|
@ -146,7 +145,7 @@ async fn build_file_response(
|
|||
download: bool,
|
||||
file_name: &str,
|
||||
path: PathBuf,
|
||||
mime: &Mime,
|
||||
mime: Mime,
|
||||
req: &HttpRequest,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let content_disposition = ContentDisposition {
|
||||
|
@ -162,7 +161,7 @@ async fn build_file_response(
|
|||
log::error!("file could not be read {:?}", file_err);
|
||||
error::ErrorInternalServerError("this file should be here but could not be found")
|
||||
})?
|
||||
.set_content_type(mime.clone())
|
||||
.set_content_type(mime)
|
||||
.set_content_disposition(content_disposition);
|
||||
|
||||
let mut response = file.into_response(req);
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
use std::{collections::HashMap, str::FromStr};
|
||||
use std::{
|
||||
collections::{HashMap, VecDeque},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use mime::Mime;
|
||||
|
||||
lazy_static! {
|
||||
static ref ALIASES: HashMap<Mime, Mime> = get_mime_aliases();
|
||||
static ref PARENTS: Vec<(Mime, Mime)> = get_mime_parent_relations();
|
||||
static ref ALIASES: HashMap<Mime, Mime> = load_mime_aliases();
|
||||
static ref PARENTS: Vec<(Mime, Mime)> = load_mime_parent_relations();
|
||||
static ref EXTENSIONS: HashMap<Mime, &'static str> = load_mime_extensions();
|
||||
}
|
||||
|
||||
fn get_mime_aliases() -> HashMap<Mime, Mime> {
|
||||
fn load_mime_aliases() -> HashMap<Mime, Mime> {
|
||||
tree_magic_db::aliases()
|
||||
.lines()
|
||||
.flat_map(|line| line.split_once(' '))
|
||||
|
@ -16,14 +20,7 @@ fn get_mime_aliases() -> HashMap<Mime, Mime> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn get_alias(mimetype: &Mime) -> &Mime {
|
||||
match ALIASES.get(mimetype) {
|
||||
Some(x) => x,
|
||||
None => mimetype,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mime_parent_relations() -> Vec<(Mime, Mime)> {
|
||||
fn load_mime_parent_relations() -> Vec<(Mime, Mime)> {
|
||||
tree_magic_db::subclasses()
|
||||
.lines()
|
||||
.flat_map(|line| line.split_once(' '))
|
||||
|
@ -33,6 +30,22 @@ fn get_mime_parent_relations() -> Vec<(Mime, Mime)> {
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn load_mime_extensions() -> HashMap<Mime, &'static str> {
|
||||
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))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn get_alias(mimetype: Mime) -> Mime {
|
||||
ALIASES.get(&mimetype).cloned().unwrap_or(mimetype)
|
||||
}
|
||||
|
||||
fn get_mime_parents(mimetype: &Mime) -> Vec<&Mime> {
|
||||
PARENTS
|
||||
.iter()
|
||||
|
@ -46,3 +59,17 @@ pub(crate) fn matches_text(mime: &Mime) -> bool {
|
|||
}
|
||||
return get_mime_parents(mime).into_iter().any(matches_text);
|
||||
}
|
||||
|
||||
pub(crate) fn get_extension(mimetype: &Mime) -> Option<&'static str> {
|
||||
let mut queue = VecDeque::new();
|
||||
queue.push_back(mimetype);
|
||||
dbg!(&*EXTENSIONS);
|
||||
while let Some(mime) = queue.pop_front() {
|
||||
dbg!(mime);
|
||||
match EXTENSIONS.get(mimetype).copied() {
|
||||
Some(ext) => return Some(ext),
|
||||
None => queue.extend(get_mime_parents(mime)),
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::config;
|
||||
use crate::{config, mime_relations};
|
||||
use actix_multipart::{Field, Multipart};
|
||||
use actix_web::{error, http::header::DispositionParam, Error};
|
||||
use futures_util::{StreamExt, TryStreamExt};
|
||||
|
@ -69,6 +69,7 @@ pub(crate) async fn parse_multipart(
|
|||
|
||||
let content_type =
|
||||
content_type.ok_or_else(|| error::ErrorBadRequest("no content type found"))?;
|
||||
let content_type = mime_relations::get_alias(content_type);
|
||||
let keep_for = keep_for_seconds
|
||||
.map(|k| k.parse())
|
||||
.transpose()
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::io::ErrorKind;
|
|||
|
||||
use crate::config::Config;
|
||||
use crate::multipart::UploadConfig;
|
||||
use crate::{multipart, template};
|
||||
use crate::{mime_relations, multipart, template};
|
||||
use actix_files::NamedFile;
|
||||
use actix_multipart::Multipart;
|
||||
use actix_web::http::header::LOCATION;
|
||||
|
@ -64,9 +64,13 @@ pub async fn upload(
|
|||
}
|
||||
};
|
||||
|
||||
let file_name = original_name
|
||||
.clone()
|
||||
.unwrap_or_else(|| format!("{}.txt", file_id));
|
||||
let file_name = original_name.clone().unwrap_or_else(|| {
|
||||
format!(
|
||||
"{}.{}",
|
||||
file_id,
|
||||
mime_relations::get_extension(&content_type).unwrap_or("txt")
|
||||
)
|
||||
});
|
||||
let db_insert = sqlx::query(
|
||||
"INSERT INTO Files (file_id, file_name, content_type, valid_till, delete_on_download) \
|
||||
VALUES ($1, $2, $3, $4, $5)",
|
||||
|
|
Loading…
Reference in New Issue