diff --git a/crates/caldav/src/calendar/methods/get.rs b/crates/caldav/src/calendar/methods/get.rs index eaafdda..2d30422 100644 --- a/crates/caldav/src/calendar/methods/get.rs +++ b/crates/caldav/src/calendar/methods/get.rs @@ -4,7 +4,7 @@ use axum::body::Body; use axum::extract::State; use axum::{extract::Path, response::Response}; use headers::{ContentType, HeaderMapExt}; -use http::{HeaderValue, StatusCode, header}; +use http::{HeaderValue, Method, StatusCode, header}; use ical::generator::{Emitter, IcalCalendarBuilder}; use ical::property::Property; use percent_encoding::{CONTROLS, utf8_percent_encode}; @@ -19,6 +19,7 @@ pub async fn route_get( Path((principal, calendar_id)): Path<(String, String)>, State(CalendarResourceService { cal_store, .. }): State>, user: Principal, + method: Method, ) -> Result { if !user.is_principal(&principal) { return Err(crate::Error::Unauthorized); @@ -96,5 +97,9 @@ pub async fn route_get( )) .unwrap(), ); - Ok(resp.body(Body::new(ical_calendar.generate())).unwrap()) + if matches!(method, Method::HEAD) { + Ok(resp.body(Body::empty()).unwrap()) + } else { + Ok(resp.body(Body::new(ical_calendar.generate())).unwrap()) + } } diff --git a/crates/caldav/src/calendar_object/methods.rs b/crates/caldav/src/calendar_object/methods.rs index 13d6e3e..faa98d2 100644 --- a/crates/caldav/src/calendar_object/methods.rs +++ b/crates/caldav/src/calendar_object/methods.rs @@ -6,7 +6,7 @@ use axum::extract::{Path, State}; use axum::response::{IntoResponse, Response}; use axum_extra::TypedHeader; use headers::{ContentType, ETag, HeaderMapExt, IfNoneMatch}; -use http::{HeaderMap, StatusCode}; +use http::{HeaderMap, Method, StatusCode}; use rustical_ical::CalendarObject; use rustical_store::CalendarStore; use rustical_store::auth::Principal; @@ -22,6 +22,7 @@ pub async fn get_event( }): Path, State(CalendarObjectResourceService { cal_store }): State>, user: Principal, + method: Method, ) -> Result { if !user.is_principal(&principal) { return Err(crate::Error::Unauthorized); @@ -42,7 +43,11 @@ pub async fn get_event( let hdrs = resp.headers_mut().unwrap(); hdrs.typed_insert(ETag::from_str(&event.get_etag()).unwrap()); hdrs.typed_insert(ContentType::from_str("text/calendar").unwrap()); - Ok(resp.body(Body::new(event.get_ics().to_owned())).unwrap()) + if matches!(method, Method::HEAD) { + Ok(resp.body(Body::empty()).unwrap()) + } else { + Ok(resp.body(Body::new(event.get_ics().to_owned())).unwrap()) + } } #[instrument(skip(cal_store))] diff --git a/crates/carddav/src/address_object/methods.rs b/crates/carddav/src/address_object/methods.rs index 4a54f27..a28aeb6 100644 --- a/crates/carddav/src/address_object/methods.rs +++ b/crates/carddav/src/address_object/methods.rs @@ -7,6 +7,7 @@ use axum::extract::{Path, State}; use axum::response::{IntoResponse, Response}; use axum_extra::TypedHeader; use axum_extra::headers::{ContentType, ETag, HeaderMapExt, IfNoneMatch}; +use http::Method; use http::{HeaderMap, StatusCode}; use rustical_dav::privileges::UserPrivilege; use rustical_dav::resource::Resource; @@ -25,6 +26,7 @@ pub async fn get_object( }): Path, State(AddressObjectResourceService { addr_store }): State>, user: Principal, + method: Method, ) -> Result { if !user.is_principal(&principal) { return Err(Error::Unauthorized); @@ -49,7 +51,11 @@ pub async fn get_object( let hdrs = resp.headers_mut().unwrap(); hdrs.typed_insert(ETag::from_str(&object.get_etag()).unwrap()); hdrs.typed_insert(ContentType::from_str("text/vcard").unwrap()); - Ok(resp.body(Body::new(object.get_vcf().to_owned())).unwrap()) + if matches!(method, Method::HEAD) { + Ok(resp.body(Body::empty()).unwrap()) + } else { + Ok(resp.body(Body::new(object.get_vcf().to_owned())).unwrap()) + } } #[instrument(skip(addr_store, body))] diff --git a/crates/carddav/src/addressbook/methods/get.rs b/crates/carddav/src/addressbook/methods/get.rs index 994f506..333e0e7 100644 --- a/crates/carddav/src/addressbook/methods/get.rs +++ b/crates/carddav/src/addressbook/methods/get.rs @@ -5,7 +5,7 @@ use axum::body::Body; use axum::extract::{Path, State}; use axum::response::Response; use axum_extra::headers::{ContentType, HeaderMapExt}; -use http::{HeaderValue, StatusCode, header}; +use http::{HeaderValue, Method, StatusCode, header}; use percent_encoding::{CONTROLS, utf8_percent_encode}; use rustical_dav::privileges::UserPrivilege; use rustical_dav::resource::Resource; @@ -20,6 +20,7 @@ pub async fn route_get( Path((principal, addressbook_id)): Path<(String, String)>, State(AddressbookResourceService { addr_store, .. }): State>, user: Principal, + method: Method, ) -> Result { if !user.is_principal(&principal) { return Err(Error::Unauthorized); @@ -55,5 +56,9 @@ pub async fn route_get( )) .unwrap(), ); - Ok(resp.body(Body::new(vcf)).unwrap()) + if matches!(method, Method::HEAD) { + Ok(resp.body(Body::empty()).unwrap()) + } else { + Ok(resp.body(Body::new(vcf)).unwrap()) + } } diff --git a/crates/dav/src/resource/axum_methods.rs b/crates/dav/src/resource/axum_methods.rs index 6179726..ee01680 100644 --- a/crates/dav/src/resource/axum_methods.rs +++ b/crates/dav/src/resource/axum_methods.rs @@ -18,11 +18,6 @@ pub trait AxumMethods: Sized + Send + Sync + 'static { None } - #[inline] - fn head() -> Option> { - None - } - #[inline] fn post() -> Option> { None @@ -58,8 +53,6 @@ pub trait AxumMethods: Sized + Send + Sync + 'static { } if Self::get().is_some() { allow.push(Method::GET); - } - if Self::head().is_some() { allow.push(Method::HEAD); } if Self::post().is_some() { diff --git a/crates/dav/src/resource/axum_service.rs b/crates/dav/src/resource/axum_service.rs index 5bfa98f..4e602f2 100644 --- a/crates/dav/src/resource/axum_service.rs +++ b/crates/dav/src/resource/axum_service.rs @@ -72,16 +72,11 @@ where return svc(self.resource_service.clone(), req); } } - "GET" => { + "GET" | "HEAD" => { if let Some(svc) = RS::get() { return svc(self.resource_service.clone(), req); } } - "HEAD" => { - if let Some(svc) = RS::head() { - return svc(self.resource_service.clone(), req); - } - } "POST" => { if let Some(svc) = RS::post() { return svc(self.resource_service.clone(), req);