aboutsummaryrefslogtreecommitdiff
path: root/aero-proto
diff options
context:
space:
mode:
authorQuentin Dufour <quentin@deuxfleurs.fr>2024-03-18 16:14:38 +0100
committerQuentin Dufour <quentin@deuxfleurs.fr>2024-03-18 16:14:38 +0100
commit2e7ffd4f4ca6ba82069290e0a3a70e85a3a79a7b (patch)
tree89b9f4daad264c4afee6abf38074d7382f90c22b /aero-proto
parentbb0011dd1745dff888a864d49ec634b7ebee3bfb (diff)
downloadaerogramme-2e7ffd4f4ca6ba82069290e0a3a70e85a3a79a7b.tar.gz
aerogramme-2e7ffd4f4ca6ba82069290e0a3a70e85a3a79a7b.zip
implement content type
Diffstat (limited to 'aero-proto')
-rw-r--r--aero-proto/src/dav.rs67
1 files 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<Incoming>,
) -> Result<Response<BoxBody<Bytes, std::io::Error>>> {
-
- 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<User>, req: Request<Incoming>) -> Result<Re
"OPTIONS" => 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<User>, req: Request<Incoming>) -> Result<Re
}
/// <D:propfind xmlns:D='DAV:' xmlns:A='http://apple.com/ns/ical/'>
-/// <D:prop><D:getcontenttype/><D:resourcetype/><D:displayname/><A:calendar-color/>
-/// </D:prop></D:propfind>
-const SUPPORTED_PROPNAME: [dav::PropertyRequest<Calendar>; 2] = [
+/// <D:prop>
+/// <D:getcontenttype/>
+/// <D:resourcetype/>
+/// <D:displayname/>
+/// <A:calendar-color/>
+/// </D:prop>
+/// </D:propfind>
+
+
+/// <D:propfind xmlns:D='DAV:' xmlns:A='http://apple.com/ns/ical/' xmlns:C='urn:ietf:params:xml:ns:caldav'>
+/// <D:prop>
+/// <D:resourcetype/>
+/// <D:owner/>
+/// <D:displayname/>
+/// <D:current-user-principal/>
+/// <D:current-user-privilege-set/>
+/// <A:calendar-color/>
+/// <C:calendar-home-set/>
+/// </D:prop>
+/// </D:propfind>
+
+const ALLPROP: [dav::PropertyRequest<Calendar>; 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<User>, req: Request<Incoming>, node: Box<dyn DavNode>) -> Result<Response<BoxBody<Bytes, std::io::Error>>> {
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<User>, req: Request<Incoming>, 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<User>, req: Request<Incoming>, node: Box<
serialize(node.multistatus_val(&user, &propname, depth))
}
-#[allow(dead_code)]
-async fn collections(_user: std::sync::Arc<User>, _req: Request<impl hyper::body::Body>) -> Result<Response<Full<Bytes>>> {
- 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<Calendar>) -> dav::PropValue<Calendar> {
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<Calendar>) -> dav::PropValue<Calendar> {
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<Calendar>) -> dav::PropValue<Calendar> {
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<Calendar>) -> dav::PropValue<Calendar> {
@@ -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())
}