implement content type
This commit is contained in:
parent
bb0011dd17
commit
2e7ffd4f4c
1 changed files with 48 additions and 19 deletions
|
@ -137,8 +137,6 @@ async fn auth(
|
||||||
login: ArcLoginProvider,
|
login: ArcLoginProvider,
|
||||||
req: Request<Incoming>,
|
req: Request<Incoming>,
|
||||||
) -> Result<Response<BoxBody<Bytes, std::io::Error>>> {
|
) -> Result<Response<BoxBody<Bytes, std::io::Error>>> {
|
||||||
|
|
||||||
tracing::info!("headers: {:?}", req.headers());
|
|
||||||
let auth_val = match req.headers().get(hyper::header::AUTHORIZATION) {
|
let auth_val = match req.headers().get(hyper::header::AUTHORIZATION) {
|
||||||
Some(hv) => hv.to_str()?,
|
Some(hv) => hv.to_str()?,
|
||||||
None => {
|
None => {
|
||||||
|
@ -210,7 +208,14 @@ async fn router(user: std::sync::Arc<User>, req: Request<Incoming>) -> Result<Re
|
||||||
"OPTIONS" => return Ok(Response::builder()
|
"OPTIONS" => return Ok(Response::builder()
|
||||||
.status(200)
|
.status(200)
|
||||||
.header("DAV", "1")
|
.header("DAV", "1")
|
||||||
|
.header("ALLOW", "HEAD,GET,PUT,OPTIONS,DELETE,PROPFIND,PROPPATCH,MKCOL,COPY,MOVE,LOCK,UNLOCK")
|
||||||
.body(text_body(""))?),
|
.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,
|
"PROPFIND" => propfind(user, req, node).await,
|
||||||
_ => return Ok(Response::builder()
|
_ => return Ok(Response::builder()
|
||||||
.status(501)
|
.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: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:prop></D:propfind>
|
/// <D:getcontenttype/>
|
||||||
const SUPPORTED_PROPNAME: [dav::PropertyRequest<Calendar>; 2] = [
|
/// <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::DisplayName,
|
||||||
|
dav::PropertyRequest::GetContentLanguage,
|
||||||
|
dav::PropertyRequest::GetContentLength,
|
||||||
|
dav::PropertyRequest::GetContentType,
|
||||||
|
dav::PropertyRequest::GetEtag,
|
||||||
|
dav::PropertyRequest::GetLastModified,
|
||||||
|
dav::PropertyRequest::LockDiscovery,
|
||||||
dav::PropertyRequest::ResourceType,
|
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>>> {
|
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 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
|
// 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.
|
// 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
|
// @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 {
|
let propname = match propfind {
|
||||||
dav::PropFind::PropName => unreachable!(),
|
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))) => {
|
dav::PropFind::AllProp(Some(dav::Include(mut include))) => {
|
||||||
include.extend_from_slice(&SUPPORTED_PROPNAME);
|
include.extend_from_slice(&ALLPROP);
|
||||||
dav::PropName(include)
|
dav::PropName(include)
|
||||||
},
|
},
|
||||||
dav::PropFind::Prop(inner) => inner,
|
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))
|
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
|
// ---- HTTP DAV Binding
|
||||||
|
|
||||||
use futures::stream::TryStreamExt;
|
use futures::stream::TryStreamExt;
|
||||||
|
@ -436,12 +456,14 @@ impl DavNode for RootNode {
|
||||||
dav::PropName(vec![
|
dav::PropName(vec![
|
||||||
dav::PropertyRequest::DisplayName,
|
dav::PropertyRequest::DisplayName,
|
||||||
dav::PropertyRequest::ResourceType,
|
dav::PropertyRequest::ResourceType,
|
||||||
|
dav::PropertyRequest::GetContentType,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
fn properties(&self, user: &ArcUser, prop: &dav::PropName<Calendar>) -> dav::PropValue<Calendar> {
|
fn properties(&self, user: &ArcUser, prop: &dav::PropName<Calendar>) -> dav::PropValue<Calendar> {
|
||||||
dav::PropValue(prop.0.iter().filter_map(|n| match n {
|
dav::PropValue(prop.0.iter().filter_map(|n| match n {
|
||||||
dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName("DAV Root".to_string())),
|
dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName("DAV Root".to_string())),
|
||||||
dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![dav::ResourceType::Collection])),
|
dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![dav::ResourceType::Collection])),
|
||||||
|
dav::PropertyRequest::GetContentType => Some(dav::Property::GetContentType("httpd/unix-directory".into())),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).collect())
|
}).collect())
|
||||||
}
|
}
|
||||||
|
@ -473,12 +495,14 @@ impl DavNode for HomeNode {
|
||||||
dav::PropName(vec![
|
dav::PropName(vec![
|
||||||
dav::PropertyRequest::DisplayName,
|
dav::PropertyRequest::DisplayName,
|
||||||
dav::PropertyRequest::ResourceType,
|
dav::PropertyRequest::ResourceType,
|
||||||
|
dav::PropertyRequest::GetContentType,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
fn properties(&self, user: &ArcUser, prop: &dav::PropName<Calendar>) -> dav::PropValue<Calendar> {
|
fn properties(&self, user: &ArcUser, prop: &dav::PropName<Calendar>) -> dav::PropValue<Calendar> {
|
||||||
dav::PropValue(prop.0.iter().filter_map(|n| match n {
|
dav::PropValue(prop.0.iter().filter_map(|n| match n {
|
||||||
dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName(format!("{} home", user.username))),
|
dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName(format!("{} home", user.username))),
|
||||||
dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![dav::ResourceType::Collection])),
|
dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![dav::ResourceType::Collection])),
|
||||||
|
dav::PropertyRequest::GetContentType => Some(dav::Property::GetContentType("httpd/unix-directory".into())),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).collect())
|
}).collect())
|
||||||
}
|
}
|
||||||
|
@ -511,12 +535,14 @@ impl DavNode for CalendarListNode {
|
||||||
dav::PropName(vec![
|
dav::PropName(vec![
|
||||||
dav::PropertyRequest::DisplayName,
|
dav::PropertyRequest::DisplayName,
|
||||||
dav::PropertyRequest::ResourceType,
|
dav::PropertyRequest::ResourceType,
|
||||||
|
dav::PropertyRequest::GetContentType,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
fn properties(&self, user: &ArcUser, prop: &dav::PropName<Calendar>) -> dav::PropValue<Calendar> {
|
fn properties(&self, user: &ArcUser, prop: &dav::PropName<Calendar>) -> dav::PropValue<Calendar> {
|
||||||
dav::PropValue(prop.0.iter().filter_map(|n| match n {
|
dav::PropValue(prop.0.iter().filter_map(|n| match n {
|
||||||
dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName(format!("{} calendars", user.username))),
|
dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName(format!("{} calendars", user.username))),
|
||||||
dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![dav::ResourceType::Collection])),
|
dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![dav::ResourceType::Collection])),
|
||||||
|
dav::PropertyRequest::GetContentType => Some(dav::Property::GetContentType("httpd/unix-directory".into())),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).collect())
|
}).collect())
|
||||||
}
|
}
|
||||||
|
@ -554,6 +580,7 @@ impl DavNode for CalendarNode {
|
||||||
dav::PropName(vec![
|
dav::PropName(vec![
|
||||||
dav::PropertyRequest::DisplayName,
|
dav::PropertyRequest::DisplayName,
|
||||||
dav::PropertyRequest::ResourceType,
|
dav::PropertyRequest::ResourceType,
|
||||||
|
dav::PropertyRequest::GetContentType,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
fn properties(&self, user: &ArcUser, prop: &dav::PropName<Calendar>) -> dav::PropValue<Calendar> {
|
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::Collection,
|
||||||
dav::ResourceType::Extension(cal::ResourceType::Calendar),
|
dav::ResourceType::Extension(cal::ResourceType::Calendar),
|
||||||
])),
|
])),
|
||||||
|
dav::PropertyRequest::GetContentType => Some(dav::Property::GetContentType("httpd/unix-directory".into())),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).collect())
|
}).collect())
|
||||||
}
|
}
|
||||||
|
@ -598,6 +626,7 @@ impl DavNode for EventNode {
|
||||||
dav::PropValue(prop.0.iter().filter_map(|n| match n {
|
dav::PropValue(prop.0.iter().filter_map(|n| match n {
|
||||||
dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName(format!("{} event", self.event_file))),
|
dav::PropertyRequest::DisplayName => Some(dav::Property::DisplayName(format!("{} event", self.event_file))),
|
||||||
dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![])),
|
dav::PropertyRequest::ResourceType => Some(dav::Property::ResourceType(vec![])),
|
||||||
|
dav::PropertyRequest::GetContentType => Some(dav::Property::GetContentType("text/calendar".into())),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).collect())
|
}).collect())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue