fix: quit the server should the deleter ever panic

This commit is contained in:
neri 2023-02-10 23:01:56 +01:00
parent 9aa0fff2e2
commit 95c867eb38
4 changed files with 34 additions and 29 deletions

18
Cargo.lock generated
View File

@ -424,7 +424,7 @@ dependencies = [
[[package]] [[package]]
name = "datatrash" name = "datatrash"
version = "2.1.0" version = "2.1.1"
dependencies = [ dependencies = [
"actix-files", "actix-files",
"actix-governor", "actix-governor",
@ -1354,9 +1354,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.92" version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7434af0dc1cbd59268aa98b4c22c131c0584d2232f6fb166efb993e2832e896a" checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -1684,9 +1684,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.7.4" version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" checksum = "bc6a3b08b64e6dfad376fa2432c7b1f01522e37a623c3050bc95db2d3ff21583"
dependencies = [ dependencies = [
"bytes", "bytes",
"futures-core", "futures-core",
@ -2034,9 +2034,9 @@ dependencies = [
[[package]] [[package]]
name = "zstd-safe" name = "zstd-safe"
version = "6.0.3+zstd.1.5.2" version = "6.0.4+zstd.1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68e4a3f57d13d0ab7e478665c60f35e2a613dcd527851c2c7287ce5c787e134a" checksum = "7afb4b54b8910cf5447638cb54bf4e8a65cbedd783af98b98c62ffe91f185543"
dependencies = [ dependencies = [
"libc", "libc",
"zstd-sys", "zstd-sys",
@ -2044,9 +2044,9 @@ dependencies = [
[[package]] [[package]]
name = "zstd-sys" name = "zstd-sys"
version = "2.0.6+zstd.1.5.2" version = "2.0.7+zstd.1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68a3f9792c0c3dc6c165840a75f47ae1f4da402c2d006881129579f6597e801b" checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5"
dependencies = [ dependencies = [
"cc", "cc",
"libc", "libc",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "datatrash" name = "datatrash"
version = "2.1.0" version = "2.1.1"
authors = ["neri"] authors = ["neri"]
edition = "2021" edition = "2021"

View File

@ -43,7 +43,7 @@ pub async fn download(
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), ViewType::Raw => build_file_response(false, &file_name, path, mime, &req),
ViewType::Download => build_file_response(true, &file_name, path, mime, &req), ViewType::Download => build_file_response(true, &file_name, path, mime, &req),
ViewType::Html => build_text_response(&path).await, ViewType::Html => build_html_response(&path).await,
}?; }?;
insert_cache_headers(&mut response, valid_till); insert_cache_headers(&mut response, valid_till);
@ -121,7 +121,7 @@ async fn get_file_size(file_path: &Path) -> u64 {
.unwrap_or(0) .unwrap_or(0)
} }
async fn build_text_response(path: &Path) -> Result<HttpResponse, Error> { async fn build_html_response(path: &Path) -> Result<HttpResponse, Error> {
let content = fs::read_to_string(path).await.map_err(|file_err| { let content = fs::read_to_string(path).await.map_err(|file_err| {
log::error!("file could not be read {:?}", file_err); log::error!("file could not be read {:?}", file_err);
error::ErrorInternalServerError("this file should be here but could not be found") error::ErrorInternalServerError("this file should be here but could not be found")
@ -168,6 +168,18 @@ fn build_file_response(
Ok(response) Ok(response)
} }
fn get_disposition_params(filename: &str) -> Vec<DispositionParam> {
let mut parameters = vec![DispositionParam::Filename(filename.to_owned())];
if !filename.is_ascii() {
parameters.push(DispositionParam::FilenameExt(ExtendedValue {
charset: Charset::Ext(String::from("UTF-8")),
language_tag: None,
value: filename.to_owned().into_bytes(),
}));
}
parameters
}
fn append_security_headers(response: &mut HttpResponse, req: &HttpRequest, download: bool) { fn append_security_headers(response: &mut HttpResponse, req: &HttpRequest, download: bool) {
// if the browser is trying to fetch this resource in a secure context pretend the reponse is // if the browser is trying to fetch this resource in a secure context pretend the reponse is
// just binary data so it won't be executed // just binary data so it won't be executed
@ -188,18 +200,6 @@ fn append_security_headers(response: &mut HttpResponse, req: &HttpRequest, downl
.append(VARY, HeaderValue::from_static("sec-fetch-mode")); .append(VARY, HeaderValue::from_static("sec-fetch-mode"));
} }
fn get_disposition_params(filename: &str) -> Vec<DispositionParam> {
let mut parameters = vec![DispositionParam::Filename(filename.to_owned())];
if !filename.is_ascii() {
parameters.push(DispositionParam::FilenameExt(ExtendedValue {
charset: Charset::Ext(String::from("UTF-8")),
language_tag: None,
value: filename.to_owned().into_bytes(),
}));
}
parameters
}
fn insert_cache_headers(response: &mut HttpResponse, valid_till: OffsetDateTime) { fn insert_cache_headers(response: &mut HttpResponse, valid_till: OffsetDateTime) {
if response.status().is_success() { if response.status().is_success() {
let valid_duration = valid_till - OffsetDateTime::now_utc(); let valid_duration = valid_till - OffsetDateTime::now_utc();

View File

@ -20,7 +20,7 @@ use actix_web::{
use env_logger::Env; use env_logger::Env;
use sqlx::postgres::PgPool; use sqlx::postgres::PgPool;
use std::env; use std::env;
use tokio::{sync::mpsc::channel, task}; use tokio::sync::mpsc::channel;
const DEFAULT_CSP: (HeaderName, &str) = ( const DEFAULT_CSP: (HeaderName, &str) = (
CONTENT_SECURITY_POLICY, CONTENT_SECURITY_POLICY,
@ -47,7 +47,7 @@ async fn main() -> std::io::Result<()> {
let expiry_watch_sender = web::Data::new(sender); let expiry_watch_sender = web::Data::new(sender);
let bind_address = env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0:8000".to_owned()); let bind_address = env::var("BIND_ADDRESS").unwrap_or_else(|_| "0.0.0.0:8000".to_owned());
task::spawn(deleter::delete_old_files( let deleter = tokio::spawn(deleter::delete_old_files(
receiver, receiver,
pool, pool,
config.files_dir.clone(), config.files_dir.clone(),
@ -66,7 +66,7 @@ async fn main() -> std::io::Result<()> {
.finish() .finish()
.unwrap(); .unwrap();
HttpServer::new({ let http_server = HttpServer::new({
move || { move || {
let app = App::new() let app = App::new()
.wrap(Logger::new(r#"%{r}a "%r" =%s %bbytes %Tsec"#)) .wrap(Logger::new(r#"%{r}a "%r" =%s %bbytes %Tsec"#))
@ -110,6 +110,11 @@ async fn main() -> std::io::Result<()> {
} }
}) })
.bind(bind_address)? .bind(bind_address)?
.run() .run();
.await
// exit when http_server exits OR when deleter panics
tokio::select! {
result = http_server => result,
_ = deleter => panic!("deleter never returns")
}
} }