From cd0ebc574a32a8e031e62bbd2b32e489efed4943 Mon Sep 17 00:00:00 2001 From: Lennart <18233294+lennart-k@users.noreply.github.com> Date: Sun, 20 Apr 2025 17:47:11 +0200 Subject: [PATCH] rustical_dav: Add Overwrite header --- .../src/{depth_header.rs => header/depth.rs} | 0 crates/dav/src/header/mod.rs | 5 ++ crates/dav/src/header/overwrite.rs | 59 +++++++++++++++++++ crates/dav/src/lib.rs | 2 +- crates/dav/src/resource/methods/propfind.rs | 2 +- 5 files changed, 66 insertions(+), 2 deletions(-) rename crates/dav/src/{depth_header.rs => header/depth.rs} (100%) create mode 100644 crates/dav/src/header/mod.rs create mode 100644 crates/dav/src/header/overwrite.rs diff --git a/crates/dav/src/depth_header.rs b/crates/dav/src/header/depth.rs similarity index 100% rename from crates/dav/src/depth_header.rs rename to crates/dav/src/header/depth.rs diff --git a/crates/dav/src/header/mod.rs b/crates/dav/src/header/mod.rs new file mode 100644 index 0000000..9bfbfdd --- /dev/null +++ b/crates/dav/src/header/mod.rs @@ -0,0 +1,5 @@ +mod depth; +mod overwrite; + +pub use depth::{Depth, InvalidDepthHeader}; +pub use overwrite::{InvalidOverwriteHeader, Overwrite}; diff --git a/crates/dav/src/header/overwrite.rs b/crates/dav/src/header/overwrite.rs new file mode 100644 index 0000000..e893700 --- /dev/null +++ b/crates/dav/src/header/overwrite.rs @@ -0,0 +1,59 @@ +use actix_web::{FromRequest, HttpRequest, ResponseError, http::StatusCode}; +use futures_util::future::{Ready, err, ok}; +use thiserror::Error; + +#[derive(Error, Debug)] +#[error("Invalid Overwrite header")] +pub struct InvalidOverwriteHeader; + +impl ResponseError for InvalidOverwriteHeader { + fn status_code(&self) -> actix_web::http::StatusCode { + StatusCode::BAD_REQUEST + } +} + +#[derive(Debug, PartialEq, Default)] +pub enum Overwrite { + #[default] + T, + F, +} + +impl Overwrite { + pub fn is_true(&self) -> bool { + matches!(self, Self::T) + } +} + +impl TryFrom<&[u8]> for Overwrite { + type Error = InvalidOverwriteHeader; + + fn try_from(value: &[u8]) -> Result { + match value { + b"T" => Ok(Overwrite::T), + b"F" => Ok(Overwrite::F), + _ => Err(InvalidOverwriteHeader), + } + } +} + +impl FromRequest for Overwrite { + type Error = InvalidOverwriteHeader; + type Future = Ready>; + + fn extract(req: &HttpRequest) -> Self::Future { + if let Some(overwrite_header) = req.headers().get("Overwrite") { + match overwrite_header.as_bytes().try_into() { + Ok(depth) => ok(depth), + Err(e) => err(e), + } + } else { + // default depth + ok(Overwrite::F) + } + } + + fn from_request(req: &HttpRequest, _payload: &mut actix_web::dev::Payload) -> Self::Future { + Self::extract(req) + } +} diff --git a/crates/dav/src/lib.rs b/crates/dav/src/lib.rs index b76eab9..a85b864 100644 --- a/crates/dav/src/lib.rs +++ b/crates/dav/src/lib.rs @@ -1,6 +1,6 @@ -pub mod depth_header; pub mod error; pub mod extensions; +pub mod header; pub mod namespace; pub mod privileges; pub mod resource; diff --git a/crates/dav/src/resource/methods/propfind.rs b/crates/dav/src/resource/methods/propfind.rs index 67c1f07..bc5e9d7 100644 --- a/crates/dav/src/resource/methods/propfind.rs +++ b/crates/dav/src/resource/methods/propfind.rs @@ -1,5 +1,5 @@ use crate::Error; -use crate::depth_header::Depth; +use crate::header::Depth; use crate::privileges::UserPrivilege; use crate::resource::Resource; use crate::resource::ResourceService;