feat: faster mime parents, fix clippy and fmt

This commit is contained in:
neri 2024-12-13 16:33:10 +01:00
parent 6362f3bd0b
commit 2ffd9393eb
7 changed files with 26 additions and 20 deletions

View File

@ -36,7 +36,10 @@ pub async fn find_by_id(
.await .await
} }
pub async fn create(file_info: &FileInfo, db: &sqlx::Pool<sqlx::Postgres>) -> Result<(), sqlx::Error> { pub async fn create(
file_info: &FileInfo,
db: &sqlx::Pool<sqlx::Postgres>,
) -> Result<(), sqlx::Error> {
sqlx::query( sqlx::query(
"INSERT INTO Files (file_id, file_name, content_type, valid_till, delete_on_download) \ "INSERT INTO Files (file_id, file_name, content_type, valid_till, delete_on_download) \
VALUES ($1, $2, $3, $4, $5)", VALUES ($1, $2, $3, $4, $5)",

View File

@ -13,6 +13,7 @@ mod upload;
use crate::rate_limit::ForwardedPeerIpKeyExtractor; use crate::rate_limit::ForwardedPeerIpKeyExtractor;
use actix_files::Files; use actix_files::Files;
use actix_governor::{Governor, GovernorConfigBuilder}; use actix_governor::{Governor, GovernorConfigBuilder};
use actix_web::middleware::from_fn;
use actix_web::{ use actix_web::{
http::header::{ http::header::{
HeaderName, CROSS_ORIGIN_OPENER_POLICY, PERMISSIONS_POLICY, REFERRER_POLICY, HeaderName, CROSS_ORIGIN_OPENER_POLICY, PERMISSIONS_POLICY, REFERRER_POLICY,
@ -22,7 +23,6 @@ use actix_web::{
web::{self, Data}, web::{self, Data},
App, Error, HttpResponse, HttpServer, App, Error, HttpResponse, HttpServer,
}; };
use actix_web::middleware::from_fn;
use env_logger::Env; use env_logger::Env;
use sqlx::postgres::PgPool; use sqlx::postgres::PgPool;
use std::env; use std::env;

View File

@ -8,7 +8,7 @@ use mime::Mime;
lazy_static! { lazy_static! {
static ref ALIASES: HashMap<Mime, Mime> = load_mime_aliases(); static ref ALIASES: HashMap<Mime, Mime> = load_mime_aliases();
static ref PARENTS: Vec<(Mime, Mime)> = load_mime_parent_relations(); static ref PARENTS: HashMap<Mime, Vec<Mime>> = load_mime_parent_relations();
static ref EXTENSIONS: HashMap<Mime, &'static str> = load_mime_extensions(); static ref EXTENSIONS: HashMap<Mime, &'static str> = load_mime_extensions();
} }
@ -20,14 +20,18 @@ fn load_mime_aliases() -> HashMap<Mime, Mime> {
.collect() .collect()
} }
fn load_mime_parent_relations() -> Vec<(Mime, Mime)> { fn load_mime_parent_relations() -> HashMap<Mime, Vec<Mime>> {
tree_magic_db::subclasses() let mut parents = HashMap::<Mime, Vec<Mime>>::new();
let subclasses = tree_magic_db::subclasses()
.lines() .lines()
.filter_map(|line| line.split_once(' ')) .filter_map(|line| line.split_once(' '))
.filter_map(|(child, parent)| { .filter_map(|(child, parent)| {
Some((Mime::from_str(child).ok()?, Mime::from_str(parent).ok()?)) Some((Mime::from_str(child).ok()?, Mime::from_str(parent).ok()?))
}) });
.collect() for (child, parent) in subclasses {
parents.entry(child).or_default().push(parent);
}
parents
} }
fn load_mime_extensions() -> HashMap<Mime, &'static str> { fn load_mime_extensions() -> HashMap<Mime, &'static str> {
@ -40,25 +44,22 @@ fn load_mime_extensions() -> HashMap<Mime, &'static str> {
.collect() .collect()
} }
pub(crate) fn get_alias(mimetype: Mime) -> Mime { pub fn resolve_alias(mimetype: Mime) -> Mime {
ALIASES.get(&mimetype).cloned().unwrap_or(mimetype) ALIASES.get(&mimetype).cloned().unwrap_or(mimetype)
} }
fn get_mime_parents(mimetype: &Mime) -> Vec<&Mime> { fn get_mime_parents(mimetype: &Mime) -> &[Mime] {
PARENTS PARENTS.get(mimetype).map(Vec::as_slice).unwrap_or(&[])
.iter()
.filter_map(|(child, parent)| (child == mimetype).then_some(parent))
.collect()
} }
pub(crate) fn matches_text(mime: &Mime) -> bool { pub fn matches_text(mime: &Mime) -> bool {
if mime.type_() == mime::TEXT { if mime.type_() == mime::TEXT {
return true; return true;
} }
return get_mime_parents(mime).into_iter().any(matches_text); get_mime_parents(mime).iter().any(matches_text)
} }
pub(crate) fn get_extension(mimetype: &Mime) -> Option<&'static str> { pub fn get_extension(mimetype: &Mime) -> Option<&'static str> {
let mut queue = VecDeque::new(); let mut queue = VecDeque::new();
queue.push_back(mimetype); queue.push_back(mimetype);
while let Some(mime) = queue.pop_front() { while let Some(mime) = queue.pop_front() {

View File

@ -73,7 +73,7 @@ pub(crate) async fn parse_multipart_inner(
(size, first_bytes) = create_file(file_path, field, config.max_file_size).await?; (size, first_bytes) = create_file(file_path, field, config.max_file_size).await?;
content_type = Some( content_type = Some(
mime.filter(|mime| *mime != APPLICATION_OCTET_STREAM) mime.filter(|mime| *mime != APPLICATION_OCTET_STREAM)
.map(mime_relations::get_alias) .map(mime_relations::resolve_alias)
.or_else(|| get_content_type(&first_bytes)) .or_else(|| get_content_type(&first_bytes))
.unwrap_or(APPLICATION_OCTET_STREAM), .unwrap_or(APPLICATION_OCTET_STREAM),
); );

View File

@ -1,10 +1,10 @@
use actix_web::middleware::Next;
use actix_web::{ use actix_web::{
body::MessageBody, body::MessageBody,
dev::{ServiceRequest, ServiceResponse}, dev::{ServiceRequest, ServiceResponse},
http::header::{HeaderValue, CONTENT_SECURITY_POLICY}, http::header::{HeaderValue, CONTENT_SECURITY_POLICY},
Error, HttpMessage, Error, HttpMessage,
}; };
use actix_web::middleware::Next;
use rand::Rng; use rand::Rng;
use std::fmt::Display; use std::fmt::Display;

View File

@ -133,7 +133,9 @@ pub fn insert_abuse_template(html: String, req: Option<&HttpRequest>, config: &C
pub fn insert_script_nonce(req: &HttpRequest, html: String) -> String { pub fn insert_script_nonce(req: &HttpRequest, html: String) -> String {
let extensions = &req.extensions(); let extensions = &req.extensions();
let script_nonce = extensions.get::<ScriptNonce>().expect("script_nonce available"); let script_nonce = extensions
.get::<ScriptNonce>()
.expect("script_nonce available");
html.replace("{script_nonce}", &script_nonce.to_string()) html.replace("{script_nonce}", &script_nonce.to_string())
} }