From 2e7ffd4f4ca6ba82069290e0a3a70e85a3a79a7b Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Mon, 18 Mar 2024 16:14:38 +0100 Subject: [PATCH] implement content type --- aero-proto/src/dav.rs | 67 +++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/aero-proto/src/dav.rs b/aero-proto/src/dav.rs index b12aea9..252cae8 100644 --- a/aero-proto/src/dav.rs +++ b/aero-proto/src/dav.rs @@ -137,8 +137,6 @@ async fn auth( login: ArcLoginProvider, req: Request, ) -> Result>> { - - tracing::info!("headers: {:?}", req.headers()); let auth_val = match req.headers().get(hyper::header::AUTHORIZATION) { Some(hv) => hv.to_str()?, None => { @@ -210,7 +208,14 @@ async fn router(user: std::sync::Arc, req: Request) -> Result return Ok(Response::builder() .status(200) .header("DAV", "1") + .header("ALLOW", "HEAD,GET,PUT,OPTIONS,DELETE,PROPFIND,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK") .body(text_body(""))?), + "HEAD" | "GET" => { + tracing::warn!("HEAD+GET not correctly implemented"); + return Ok(Response::builder() + .status(200) + .body(text_body(""))?) + }, "PROPFIND" => propfind(user, req, node).await, _ => return Ok(Response::builder() .status(501) @@ -219,22 +224,43 @@ async fn router(user: std::sync::Arc, req: Request) -> Result -/// -/// -const SUPPORTED_PROPNAME: [dav::PropertyRequest; 2] = [ +/// +/// +/// +/// +/// +/// +/// + + +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// + +const ALLPROP: [dav::PropertyRequest; 10] = [ + dav::PropertyRequest::CreationDate, dav::PropertyRequest::DisplayName, + dav::PropertyRequest::GetContentLanguage, + dav::PropertyRequest::GetContentLength, + dav::PropertyRequest::GetContentType, + dav::PropertyRequest::GetEtag, + dav::PropertyRequest::GetLastModified, + dav::PropertyRequest::LockDiscovery, dav::PropertyRequest::ResourceType, + dav::PropertyRequest::SupportedLock, ]; async fn propfind(user: std::sync::Arc, req: Request, node: Box) -> Result>> { let depth = depth(&req); - - /*let supported_propname = vec![ - dav::PropertyRequest::DisplayName, - dav::PropertyRequest::ResourceType, - ];*/ - // A client may choose not to submit a request body. An empty PROPFIND // request body MUST be treated as if it were an 'allprop' request. // @FIXME here we handle any invalid data as an allprop, an empty request is thus correctly @@ -248,9 +274,9 @@ async fn propfind(user: std::sync::Arc, req: Request, node: Box< let propname = match propfind { dav::PropFind::PropName => unreachable!(), - dav::PropFind::AllProp(None) => dav::PropName(SUPPORTED_PROPNAME.to_vec()), + dav::PropFind::AllProp(None) => dav::PropName(ALLPROP.to_vec()), dav::PropFind::AllProp(Some(dav::Include(mut include))) => { - include.extend_from_slice(&SUPPORTED_PROPNAME); + include.extend_from_slice(&ALLPROP); dav::PropName(include) }, dav::PropFind::Prop(inner) => inner, @@ -259,12 +285,6 @@ async fn propfind(user: std::sync::Arc, req: Request, node: Box< serialize(node.multistatus_val(&user, &propname, depth)) } -#[allow(dead_code)] -async fn collections(_user: std::sync::Arc, _req: Request) -> Result>> { - unimplemented!(); -} - - // ---- HTTP DAV Binding use futures::stream::TryStreamExt; @@ -436,12 +456,14 @@ impl DavNode for RootNode { dav::PropName(vec![ dav::PropertyRequest::DisplayName, dav::PropertyRequest::ResourceType, + dav::PropertyRequest::GetContentType, ]) } fn properties(&self, user: &ArcUser, prop: &dav::PropName) -> dav::PropValue { dav::PropValue(prop.0.iter().filter_map(|n| match n { dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName("DAV Root".to_string())), dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![dav::ResourceType::Collection])), + dav::PropertyRequest::GetContentType => Some(dav::Property::GetContentType("httpd/unix-directory".into())), _ => None, }).collect()) } @@ -473,12 +495,14 @@ impl DavNode for HomeNode { dav::PropName(vec![ dav::PropertyRequest::DisplayName, dav::PropertyRequest::ResourceType, + dav::PropertyRequest::GetContentType, ]) } fn properties(&self, user: &ArcUser, prop: &dav::PropName) -> dav::PropValue { dav::PropValue(prop.0.iter().filter_map(|n| match n { dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName(format!("{} home", user.username))), dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![dav::ResourceType::Collection])), + dav::PropertyRequest::GetContentType => Some(dav::Property::GetContentType("httpd/unix-directory".into())), _ => None, }).collect()) } @@ -511,12 +535,14 @@ impl DavNode for CalendarListNode { dav::PropName(vec![ dav::PropertyRequest::DisplayName, dav::PropertyRequest::ResourceType, + dav::PropertyRequest::GetContentType, ]) } fn properties(&self, user: &ArcUser, prop: &dav::PropName) -> dav::PropValue { dav::PropValue(prop.0.iter().filter_map(|n| match n { dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName(format!("{} calendars", user.username))), dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![dav::ResourceType::Collection])), + dav::PropertyRequest::GetContentType => Some(dav::Property::GetContentType("httpd/unix-directory".into())), _ => None, }).collect()) } @@ -554,6 +580,7 @@ impl DavNode for CalendarNode { dav::PropName(vec![ dav::PropertyRequest::DisplayName, dav::PropertyRequest::ResourceType, + dav::PropertyRequest::GetContentType, ]) } fn properties(&self, user: &ArcUser, prop: &dav::PropName) -> dav::PropValue { @@ -563,6 +590,7 @@ impl DavNode for CalendarNode { dav::ResourceType::Collection, dav::ResourceType::Extension(cal::ResourceType::Calendar), ])), + dav::PropertyRequest::GetContentType => Some(dav::Property::GetContentType("httpd/unix-directory".into())), _ => None, }).collect()) } @@ -598,6 +626,7 @@ impl DavNode for EventNode { dav::PropValue(prop.0.iter().filter_map(|n| match n { dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName(format!("{} event", self.event_file))), dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![])), + dav::PropertyRequest::GetContentType => Some(dav::Property::GetContentType("text/calendar".into())), _ => None, }).collect()) }