use headers::HeaderMapExt;
use http::{Request, Response};
use crate::body::Body;
use crate::util::{dav_method, DavMethod};
use crate::DavResult;
impl crate::DavInner {
pub(crate) async fn handle_options(&self, req: &Request<()>) -> DavResult<Response<Body>> {
let mut res = Response::new(Body::empty());
let h = res.headers_mut();
let dav = "1,2,3,sabredav-partialupdate";
h.insert("DAV", dav.parse().unwrap());
h.insert("MS-Author-Via", "DAV".parse().unwrap());
h.typed_insert(headers::ContentLength(0));
let method = dav_method(req.method()).unwrap_or(DavMethod::Options);
let islock = |m| m == DavMethod::Lock || m == DavMethod::Unlock;
let mm = |v: &mut Vec<String>, m: &str, y: DavMethod| {
if (y == DavMethod::Options || (y != method || islock(y) != islock(method))) &&
(!islock(y) || self.ls.is_some()) &&
self.allow.map(|x| x.contains(y)).unwrap_or(true)
{
v.push(m.to_string());
}
};
let path = self.path(&req);
let meta = self.fs.metadata(&path).await;
let is_unmapped = meta.is_err();
let is_file = meta.and_then(|m| Ok(m.is_file())).unwrap_or_default();
let is_star = path.is_star() && method == DavMethod::Options;
let mut v = Vec::new();
if is_unmapped && !is_star {
mm(&mut v, "OPTIONS", DavMethod::Options);
mm(&mut v, "MKCOL", DavMethod::MkCol);
mm(&mut v, "PUT", DavMethod::Put);
mm(&mut v, "LOCK", DavMethod::Lock);
} else {
if is_file || is_star {
mm(&mut v, "HEAD", DavMethod::Head);
mm(&mut v, "GET", DavMethod::Get);
mm(&mut v, "PATCH", DavMethod::Patch);
mm(&mut v, "PUT", DavMethod::Put);
}
mm(&mut v, "OPTIONS", DavMethod::Options);
mm(&mut v, "PROPFIND", DavMethod::PropFind);
mm(&mut v, "COPY", DavMethod::Copy);
if path.as_url_string() != "/" {
mm(&mut v, "MOVE", DavMethod::Move);
mm(&mut v, "DELETE", DavMethod::Delete);
}
mm(&mut v, "LOCK", DavMethod::Lock);
mm(&mut v, "UNLOCK", DavMethod::Unlock);
}
let a = v.clone().join(",").parse().unwrap();
res.headers_mut().insert("allow", a);
Ok(res)
}
}