Improved topological sorting
This commit is contained in:
@@ -8,7 +8,9 @@ resolver = "2"
|
||||
dav-proto = { path = "/Users/me/code/dav-proto" }
|
||||
common = { path = "../common" }
|
||||
groupware = { path = "../groupware" }
|
||||
directory = { path = "../directory" }
|
||||
http_proto = { path = "../http-proto" }
|
||||
trc = { path = "../trc" }
|
||||
hashify = { version = "0.2" }
|
||||
hyper = { version = "1.0.1", features = ["server", "http1", "http2"] }
|
||||
|
||||
|
||||
5
crates/dav/src/calendar/mod.rs
Normal file
5
crates/dav/src/calendar/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
5
crates/dav/src/card/mod.rs
Normal file
5
crates/dav/src/card/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
29
crates/dav/src/file/acl.rs
Normal file
29
crates/dav/src/file/acl.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::{RequestHeaders, schema::request::Acl};
|
||||
use http_proto::HttpResponse;
|
||||
|
||||
pub(crate) trait FileAclRequestHandler: Sync + Send {
|
||||
fn handle_file_acl_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: Acl,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl FileAclRequestHandler for Server {
|
||||
async fn handle_file_acl_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: Acl,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
29
crates/dav/src/file/changes.rs
Normal file
29
crates/dav/src/file/changes.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::{RequestHeaders, schema::request::SyncCollection};
|
||||
use http_proto::HttpResponse;
|
||||
|
||||
pub(crate) trait FileChangesRequestHandler: Sync + Send {
|
||||
fn handle_file_changes_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: SyncCollection,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl FileChangesRequestHandler for Server {
|
||||
async fn handle_file_changes_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: SyncCollection,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
29
crates/dav/src/file/copy_move.rs
Normal file
29
crates/dav/src/file/copy_move.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::RequestHeaders;
|
||||
use http_proto::HttpResponse;
|
||||
|
||||
pub(crate) trait FileCopyMoveRequestHandler: Sync + Send {
|
||||
fn handle_file_copy_move_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
is_move: bool,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl FileCopyMoveRequestHandler for Server {
|
||||
async fn handle_file_copy_move_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
is_move: bool,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
27
crates/dav/src/file/delete.rs
Normal file
27
crates/dav/src/file/delete.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::RequestHeaders;
|
||||
use http_proto::HttpResponse;
|
||||
|
||||
pub(crate) trait FileDeleteRequestHandler: Sync + Send {
|
||||
fn handle_file_delete_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl FileDeleteRequestHandler for Server {
|
||||
async fn handle_file_delete_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
29
crates/dav/src/file/get.rs
Normal file
29
crates/dav/src/file/get.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::RequestHeaders;
|
||||
use http_proto::HttpResponse;
|
||||
|
||||
pub(crate) trait FileGetRequestHandler: Sync + Send {
|
||||
fn handle_file_get_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
is_head: bool,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl FileGetRequestHandler for Server {
|
||||
async fn handle_file_get_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
is_head: bool,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
29
crates/dav/src/file/lock.rs
Normal file
29
crates/dav/src/file/lock.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::{RequestHeaders, schema::request::LockInfo};
|
||||
use http_proto::HttpResponse;
|
||||
|
||||
pub(crate) trait FileLockRequestHandler: Sync + Send {
|
||||
fn handle_file_lock_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: Option<LockInfo>,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl FileLockRequestHandler for Server {
|
||||
async fn handle_file_lock_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: Option<LockInfo>,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
29
crates/dav/src/file/mkcol.rs
Normal file
29
crates/dav/src/file/mkcol.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::{RequestHeaders, schema::request::MkCol};
|
||||
use http_proto::HttpResponse;
|
||||
|
||||
pub(crate) trait FileMkColRequestHandler: Sync + Send {
|
||||
fn handle_file_mkcol_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: Option<MkCol>,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl FileMkColRequestHandler for Server {
|
||||
async fn handle_file_mkcol_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: Option<MkCol>,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
22
crates/dav/src/file/mod.rs
Normal file
22
crates/dav/src/file/mod.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
pub mod acl;
|
||||
pub mod changes;
|
||||
pub mod copy_move;
|
||||
pub mod delete;
|
||||
pub mod get;
|
||||
pub mod lock;
|
||||
pub mod mkcol;
|
||||
pub mod propfind;
|
||||
pub mod proppatch;
|
||||
pub mod update;
|
||||
|
||||
pub(crate) enum UpdateType {
|
||||
Post(Vec<u8>),
|
||||
Put(Vec<u8>),
|
||||
Patch(Vec<u8>),
|
||||
}
|
||||
29
crates/dav/src/file/propfind.rs
Normal file
29
crates/dav/src/file/propfind.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::{RequestHeaders, schema::request::PropFind};
|
||||
use http_proto::HttpResponse;
|
||||
|
||||
pub(crate) trait FilePropFindRequestHandler: Sync + Send {
|
||||
fn handle_file_propfind_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: PropFind,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl FilePropFindRequestHandler for Server {
|
||||
async fn handle_file_propfind_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: PropFind,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
29
crates/dav/src/file/proppatch.rs
Normal file
29
crates/dav/src/file/proppatch.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::{RequestHeaders, schema::request::PropertyUpdate};
|
||||
use http_proto::HttpResponse;
|
||||
|
||||
pub(crate) trait FilePropPatchRequestHandler: Sync + Send {
|
||||
fn handle_file_proppatch_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: PropertyUpdate,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl FilePropPatchRequestHandler for Server {
|
||||
async fn handle_file_proppatch_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: PropertyUpdate,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
31
crates/dav/src/file/update.rs
Normal file
31
crates/dav/src/file/update.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use dav_proto::{RequestHeaders, schema::request::SyncCollection};
|
||||
use http_proto::HttpResponse;
|
||||
|
||||
use super::UpdateType;
|
||||
|
||||
pub(crate) trait FileUpdateRequestHandler: Sync + Send {
|
||||
fn handle_file_update_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: UpdateType,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl FileUpdateRequestHandler for Server {
|
||||
async fn handle_file_update_request(
|
||||
&self,
|
||||
access_token: &AccessToken,
|
||||
headers: RequestHeaders<'_>,
|
||||
request: UpdateType,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@@ -4,16 +4,24 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
|
||||
pub mod calendar;
|
||||
pub mod card;
|
||||
pub mod file;
|
||||
pub mod principal;
|
||||
pub mod request;
|
||||
|
||||
use dav_proto::schema::request::Report;
|
||||
use http_proto::HttpResponse;
|
||||
use hyper::{Method, StatusCode};
|
||||
|
||||
pub(crate) type Result<T> = std::result::Result<T, DavError>;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum DavResource {
|
||||
Card,
|
||||
Cal,
|
||||
File,
|
||||
Principal,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -22,6 +30,7 @@ pub enum DavMethod {
|
||||
PUT,
|
||||
POST,
|
||||
DELETE,
|
||||
HEAD,
|
||||
PATCH,
|
||||
PROPFIND,
|
||||
PROPPATCH,
|
||||
@@ -32,6 +41,13 @@ pub enum DavMethod {
|
||||
LOCK,
|
||||
UNLOCK,
|
||||
OPTIONS,
|
||||
ACL,
|
||||
}
|
||||
|
||||
pub(crate) enum DavError {
|
||||
Parse(dav_proto::parser::Error),
|
||||
Internal(trc::Error),
|
||||
UnsupportedReport(Report),
|
||||
}
|
||||
|
||||
impl DavResource {
|
||||
@@ -39,7 +55,8 @@ impl DavResource {
|
||||
hashify::tiny_map!(service.as_bytes(),
|
||||
"card" => DavResource::Card,
|
||||
"cal" => DavResource::Cal,
|
||||
"file" => DavResource::File
|
||||
"file" => DavResource::File,
|
||||
"pri" => DavResource::Principal,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -59,6 +76,7 @@ impl DavMethod {
|
||||
Method::OPTIONS => Some(DavMethod::OPTIONS),
|
||||
Method::POST => Some(DavMethod::POST),
|
||||
Method::PATCH => Some(DavMethod::PATCH),
|
||||
Method::HEAD => Some(DavMethod::HEAD),
|
||||
_ => {
|
||||
hashify::tiny_map!(method.as_str().as_bytes(),
|
||||
"PROPFIND" => DavMethod::PROPFIND,
|
||||
@@ -68,7 +86,8 @@ impl DavMethod {
|
||||
"COPY" => DavMethod::COPY,
|
||||
"MOVE" => DavMethod::MOVE,
|
||||
"LOCK" => DavMethod::LOCK,
|
||||
"UNLOCK" => DavMethod::UNLOCK
|
||||
"UNLOCK" => DavMethod::UNLOCK,
|
||||
"ACL" => DavMethod::ACL
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -84,9 +103,8 @@ impl DavMethod {
|
||||
| DavMethod::PROPPATCH
|
||||
| DavMethod::PROPFIND
|
||||
| DavMethod::REPORT
|
||||
| DavMethod::MKCOL
|
||||
| DavMethod::COPY
|
||||
| DavMethod::MOVE
|
||||
| DavMethod::LOCK
|
||||
| DavMethod::ACL
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
5
crates/dav/src/principal/mod.rs
Normal file
5
crates/dav/src/principal/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
||||
*/
|
||||
@@ -7,9 +7,25 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use common::{Server, auth::AccessToken};
|
||||
use http_proto::{HttpRequest, HttpResponse, HttpSessionData};
|
||||
use dav_proto::{
|
||||
RequestHeaders,
|
||||
parser::{DavParser, tokenizer::Tokenizer},
|
||||
schema::request::{Acl, LockInfo, MkCol, PropFind, PropertyUpdate, Report},
|
||||
};
|
||||
use directory::Permission;
|
||||
use http_proto::{HttpRequest, HttpResponse, HttpSessionData, request::fetch_body};
|
||||
use hyper::{StatusCode, header};
|
||||
|
||||
use crate::{DavMethod, DavResource};
|
||||
use crate::{
|
||||
DavError, DavMethod, DavResource,
|
||||
file::{
|
||||
UpdateType, acl::FileAclRequestHandler, changes::FileChangesRequestHandler,
|
||||
copy_move::FileCopyMoveRequestHandler, delete::FileDeleteRequestHandler,
|
||||
get::FileGetRequestHandler, lock::FileLockRequestHandler, mkcol::FileMkColRequestHandler,
|
||||
propfind::FilePropFindRequestHandler, proppatch::FilePropPatchRequestHandler,
|
||||
update::FileUpdateRequestHandler,
|
||||
},
|
||||
};
|
||||
|
||||
pub trait DavRequestHandler: Sync + Send {
|
||||
fn handle_dav_request(
|
||||
@@ -19,20 +35,206 @@ pub trait DavRequestHandler: Sync + Send {
|
||||
session: &HttpSessionData,
|
||||
resource: DavResource,
|
||||
method: DavMethod,
|
||||
body: Vec<u8>,
|
||||
) -> impl Future<Output = HttpResponse> + Send;
|
||||
}
|
||||
|
||||
pub(crate) trait DavRequestDispatcher: Sync + Send {
|
||||
fn dispatch_dav_request(
|
||||
&self,
|
||||
request: &HttpRequest,
|
||||
access_token: Arc<AccessToken>,
|
||||
resource: DavResource,
|
||||
method: DavMethod,
|
||||
body: Vec<u8>,
|
||||
) -> impl Future<Output = crate::Result<HttpResponse>> + Send;
|
||||
}
|
||||
|
||||
impl DavRequestDispatcher for Server {
|
||||
async fn dispatch_dav_request(
|
||||
&self,
|
||||
request: &HttpRequest,
|
||||
access_token: Arc<AccessToken>,
|
||||
resource: DavResource,
|
||||
method: DavMethod,
|
||||
body: Vec<u8>,
|
||||
) -> crate::Result<HttpResponse> {
|
||||
// Parse headers
|
||||
let mut headers = RequestHeaders::new(request.uri().path());
|
||||
for (key, value) in request.headers() {
|
||||
headers.parse(key.as_str(), value.to_str().unwrap_or_default());
|
||||
}
|
||||
|
||||
// Dispatch
|
||||
match resource {
|
||||
DavResource::Card => {
|
||||
todo!()
|
||||
}
|
||||
DavResource::Cal => {
|
||||
todo!()
|
||||
}
|
||||
DavResource::Principal => {
|
||||
todo!()
|
||||
}
|
||||
DavResource::File => match method {
|
||||
DavMethod::PROPFIND => {
|
||||
self.handle_file_propfind_request(
|
||||
&access_token,
|
||||
headers,
|
||||
PropFind::parse(&mut Tokenizer::new(&body))?,
|
||||
)
|
||||
.await
|
||||
}
|
||||
DavMethod::PROPPATCH => {
|
||||
self.handle_file_proppatch_request(
|
||||
&access_token,
|
||||
headers,
|
||||
PropertyUpdate::parse(&mut Tokenizer::new(&body))?,
|
||||
)
|
||||
.await
|
||||
}
|
||||
DavMethod::MKCOL => {
|
||||
self.handle_file_mkcol_request(
|
||||
&access_token,
|
||||
headers,
|
||||
if !body.is_empty() {
|
||||
Some(MkCol::parse(&mut Tokenizer::new(&body))?)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
DavMethod::GET => {
|
||||
self.handle_file_get_request(&access_token, headers, false)
|
||||
.await
|
||||
}
|
||||
DavMethod::HEAD => {
|
||||
self.handle_file_get_request(&access_token, headers, true)
|
||||
.await
|
||||
}
|
||||
DavMethod::DELETE => {
|
||||
self.handle_file_delete_request(&access_token, headers)
|
||||
.await
|
||||
}
|
||||
DavMethod::PUT => {
|
||||
self.handle_file_update_request(&access_token, headers, UpdateType::Put(body))
|
||||
.await
|
||||
}
|
||||
DavMethod::POST => {
|
||||
self.handle_file_update_request(&access_token, headers, UpdateType::Post(body))
|
||||
.await
|
||||
}
|
||||
DavMethod::PATCH => {
|
||||
self.handle_file_update_request(&access_token, headers, UpdateType::Patch(body))
|
||||
.await
|
||||
}
|
||||
DavMethod::COPY => {
|
||||
self.handle_file_copy_move_request(&access_token, headers, false)
|
||||
.await
|
||||
}
|
||||
DavMethod::MOVE => {
|
||||
self.handle_file_copy_move_request(&access_token, headers, true)
|
||||
.await
|
||||
}
|
||||
DavMethod::LOCK => {
|
||||
self.handle_file_lock_request(
|
||||
&access_token,
|
||||
headers,
|
||||
LockInfo::parse(&mut Tokenizer::new(&body))?.into(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
DavMethod::UNLOCK => {
|
||||
self.handle_file_lock_request(&access_token, headers, None)
|
||||
.await
|
||||
}
|
||||
DavMethod::ACL => {
|
||||
self.handle_file_acl_request(
|
||||
&access_token,
|
||||
headers,
|
||||
Acl::parse(&mut Tokenizer::new(&body))?,
|
||||
)
|
||||
.await
|
||||
}
|
||||
DavMethod::REPORT => match Report::parse(&mut Tokenizer::new(&body))? {
|
||||
Report::SyncCollection(sync_collection) => {
|
||||
self.handle_file_changes_request(&access_token, headers, sync_collection)
|
||||
.await
|
||||
}
|
||||
report => Err(DavError::UnsupportedReport(report)),
|
||||
},
|
||||
DavMethod::OPTIONS => unreachable!(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DavRequestHandler for Server {
|
||||
async fn handle_dav_request(
|
||||
&self,
|
||||
request: HttpRequest,
|
||||
mut request: HttpRequest,
|
||||
access_token: Arc<AccessToken>,
|
||||
session: &HttpSessionData,
|
||||
resource: DavResource,
|
||||
method: DavMethod,
|
||||
body: Vec<u8>,
|
||||
) -> HttpResponse {
|
||||
todo!()
|
||||
let body = if method.has_body()
|
||||
|| request
|
||||
.headers()
|
||||
.get(header::CONTENT_LENGTH)
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.and_then(|v| v.parse::<u64>().ok())
|
||||
.is_some_and(|len| len > 0)
|
||||
{
|
||||
if let Some(body) = fetch_body(
|
||||
&mut request,
|
||||
if !access_token.has_permission(Permission::UnlimitedUploads) {
|
||||
self.core.dav.max_request_size
|
||||
} else {
|
||||
0
|
||||
},
|
||||
session.session_id,
|
||||
)
|
||||
.await
|
||||
{
|
||||
body
|
||||
} else {
|
||||
trc::event!(
|
||||
Limit(trc::LimitEvent::SizeRequest),
|
||||
SpanId = session.session_id,
|
||||
Contents = "Request body too large",
|
||||
);
|
||||
|
||||
return HttpResponse::new(StatusCode::PAYLOAD_TOO_LARGE);
|
||||
}
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
match self
|
||||
.dispatch_dav_request(&request, access_token, resource, method, body)
|
||||
.await
|
||||
{
|
||||
Ok(response) => response,
|
||||
Err(DavError::Internal(err)) => {
|
||||
trc::error!(err.span_id(session.session_id));
|
||||
|
||||
HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
}
|
||||
Err(DavError::UnsupportedReport(report)) => HttpResponse::new(StatusCode::BAD_REQUEST),
|
||||
Err(DavError::Parse(err)) => HttpResponse::new(StatusCode::BAD_REQUEST),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<dav_proto::parser::Error> for DavError {
|
||||
fn from(err: dav_proto::parser::Error) -> Self {
|
||||
DavError::Parse(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<trc::Error> for DavError {
|
||||
fn from(err: trc::Error) -> Self {
|
||||
DavError::Internal(err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user