aboutsummaryrefslogtreecommitdiff
path: root/aero-proto/src/dav/controller.rs
diff options
context:
space:
mode:
Diffstat (limited to 'aero-proto/src/dav/controller.rs')
-rw-r--r--aero-proto/src/dav/controller.rs34
1 files changed, 26 insertions, 8 deletions
diff --git a/aero-proto/src/dav/controller.rs b/aero-proto/src/dav/controller.rs
index 243a455..c8432dd 100644
--- a/aero-proto/src/dav/controller.rs
+++ b/aero-proto/src/dav/controller.rs
@@ -2,7 +2,8 @@ use anyhow::Result;
use http_body_util::combinators::BoxBody;
use hyper::body::Incoming;
use hyper::{Request, Response, body::Bytes};
-use http_body_util::StreamBody;
+use http_body_util::BodyStream;
+use futures::stream::{StreamExt, TryStreamExt};
use aero_collections::user::User;
use aero_dav::types as dav;
@@ -10,7 +11,7 @@ use aero_dav::realization::All;
use aero_dav::caltypes as cal;
use crate::dav::codec::{serialize, deserialize, depth, text_body};
-use crate::dav::node::DavNode;
+use crate::dav::node::{DavNode, PutPolicy};
use crate::dav::resource::RootNode;
use crate::dav::codec;
@@ -65,10 +66,7 @@ impl Controller {
.status(404)
.body(codec::text_body(""))?)
},
- "PUT" => {
- let to_create = path_segments.last().expect("Bound checked earlier in this fx");
- ctrl.put(to_create).await
- },
+ "PUT" => ctrl.put().await,
"DELETE" => {
todo!();
},
@@ -177,8 +175,28 @@ impl Controller {
serialize(status, Self::multistatus(&self.user, nodes, not_found, propname))
}
- async fn put(self, child: &str) -> Result<Response<BoxBody<Bytes, std::io::Error>>> {
- todo!()
+ async fn put(self) -> Result<Response<BoxBody<Bytes, std::io::Error>>> {
+ //@FIXME temporary, look at If-None-Match & If-Match headers
+ let put_policy = PutPolicy::CreateOnly;
+
+ let stream_of_frames = BodyStream::new(self.req.into_body());
+ let stream_of_bytes = stream_of_frames
+ .map_ok(|frame| frame.into_data())
+ .map(|obj| match obj {
+ Ok(Ok(v)) => Ok(v),
+ Ok(Err(_)) => Err(std::io::Error::new(std::io::ErrorKind::Other, "conversion error")),
+ Err(err) => Err(std::io::Error::new(std::io::ErrorKind::Other, err)),
+ }).boxed();
+
+ let etag = self.node.put(put_policy, stream_of_bytes).await?;
+
+ let response = Response::builder()
+ .status(201)
+ .header("ETag", etag)
+ //.header("content-type", "application/xml; charset=\"utf-8\"")
+ .body(text_body(""))?;
+
+ Ok(response)
}
async fn get(self) -> Result<Response<BoxBody<Bytes, std::io::Error>>> {