Dav XML types
This commit is contained in:
parent
c10eb33585
commit
ffe4d071f6
4 changed files with 778 additions and 84 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -46,6 +46,7 @@ dependencies = [
|
||||||
"eml-codec",
|
"eml-codec",
|
||||||
"futures",
|
"futures",
|
||||||
"hex",
|
"hex",
|
||||||
|
"http 1.0.0",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
"hyper 1.2.0",
|
"hyper 1.2.0",
|
||||||
"hyper-rustls 0.26.0",
|
"hyper-rustls 0.26.0",
|
||||||
|
@ -2701,6 +2702,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
|
checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -41,6 +41,7 @@ imap-codec = { version = "2.0.0", features = ["bounded-static", "ext_condstore_q
|
||||||
imap-flow = { git = "https://github.com/duesee/imap-flow.git", branch = "main" }
|
imap-flow = { git = "https://github.com/duesee/imap-flow.git", branch = "main" }
|
||||||
|
|
||||||
# http & web
|
# http & web
|
||||||
|
http = "1.0"
|
||||||
http-body-util = "0.1"
|
http-body-util = "0.1"
|
||||||
hyper = "1.2"
|
hyper = "1.2"
|
||||||
hyper-rustls = { version = "0.26", features = ["http2"] }
|
hyper-rustls = { version = "0.26", features = ["http2"] }
|
||||||
|
@ -53,7 +54,7 @@ toml = "0.5"
|
||||||
base64 = "0.21"
|
base64 = "0.21"
|
||||||
hex = "0.4"
|
hex = "0.4"
|
||||||
nom = "7.1"
|
nom = "7.1"
|
||||||
quick-xml = "0.31"
|
quick-xml = { version = "0.31", features = ["async-tokio"] }
|
||||||
zstd = { version = "0.9", default-features = false }
|
zstd = { version = "0.9", default-features = false }
|
||||||
|
|
||||||
# cryptography & security
|
# cryptography & security
|
||||||
|
|
|
@ -1,16 +1,48 @@
|
||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use quick_xml::events::{Event, BytesEnd, BytesStart, BytesText};
|
||||||
|
use quick_xml::writer::{ElementWriter, Writer};
|
||||||
|
use quick_xml::name::PrefixDeclaration;
|
||||||
|
use tokio::io::AsyncWrite;
|
||||||
|
use super::types::*;
|
||||||
|
|
||||||
|
//@FIXME a cleaner way to manager namespace would be great
|
||||||
|
//but at the same time, the quick-xml library is not cooperating.
|
||||||
|
//So instead of writing many cursed workarounds - I tried, I am just hardcoding the namespaces...
|
||||||
|
|
||||||
pub trait Encode {
|
pub trait Encode {
|
||||||
fn write(&self, a: &mut u64) -> String;
|
async fn write(&self, xml: &mut Writer<impl AsyncWrite + Unpin>) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encode for Href {
|
||||||
|
async fn write(&self, xml: &mut Writer<impl AsyncWrite + Unpin>) -> Result<()> {
|
||||||
|
xml.create_element("D:href")
|
||||||
|
.write_text_content_async(BytesText::new(&self.0))
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
// Note this useful idiom: importing names from outer (for mod tests) scope.
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
#[test]
|
/// To run only the unit tests and avoid the behavior ones:
|
||||||
fn test_href() {
|
/// cargo test --bin aerogramme
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_href() {
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
let mut tokio_buffer = tokio::io::BufWriter::new(&mut buffer);
|
||||||
|
let mut writer = Writer::new_with_indent(&mut tokio_buffer, b' ', 4);
|
||||||
|
|
||||||
|
Href("/SOGo/dav/so/".into()).write(&mut writer).await.expect("xml serialization");
|
||||||
|
tokio_buffer.flush().await.expect("tokio buffer flush");
|
||||||
|
|
||||||
|
assert_eq!(buffer.as_slice(), &b"<D:href>/SOGo/dav/so/</D:href>"[..]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
815
src/dav/types.rs
815
src/dav/types.rs
|
@ -1,4 +1,78 @@
|
||||||
pub enum Error {
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use chrono::{DateTime,FixedOffset};
|
||||||
|
|
||||||
|
/// 14.1. activelock XML Element
|
||||||
|
///
|
||||||
|
/// Name: activelock
|
||||||
|
///
|
||||||
|
/// Purpose: Describes a lock on a resource.
|
||||||
|
/// <!ELEMENT activelock (lockscope, locktype, depth, owner?, timeout?,
|
||||||
|
/// locktoken?, lockroot)>
|
||||||
|
pub struct ActiveLock {
|
||||||
|
lockscope: u64,
|
||||||
|
locktype: u64,
|
||||||
|
depth: Depth,
|
||||||
|
owner: Option<u64>,
|
||||||
|
timeout: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 14.2 allprop XML Element
|
||||||
|
///
|
||||||
|
/// Name: allprop
|
||||||
|
///
|
||||||
|
/// Purpose: Specifies that all names and values of dead properties and
|
||||||
|
/// the live properties defined by this document existing on the
|
||||||
|
/// resource are to be returned.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT allprop EMPTY >
|
||||||
|
pub struct AllProp{}
|
||||||
|
|
||||||
|
/// 14.3 collection XML Element
|
||||||
|
///
|
||||||
|
/// Name: collection
|
||||||
|
///
|
||||||
|
/// Purpose: Identifies the associated resource as a collection. The
|
||||||
|
/// DAV:resourcetype property of a collection resource MUST contain
|
||||||
|
/// this element. It is normally empty but extensions may add sub-
|
||||||
|
/// elements.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT collection EMPTY >
|
||||||
|
pub struct Collection{}
|
||||||
|
|
||||||
|
/// 14.4 depth XML Element
|
||||||
|
///
|
||||||
|
/// Name: depth
|
||||||
|
///
|
||||||
|
/// Purpose: Used for representing depth values in XML content (e.g.,
|
||||||
|
/// in lock information).
|
||||||
|
///
|
||||||
|
/// Value: "0" | "1" | "infinity"
|
||||||
|
///
|
||||||
|
/// <!ELEMENT depth (#PCDATA) >
|
||||||
|
pub enum Depth {
|
||||||
|
Zero,
|
||||||
|
One,
|
||||||
|
Infinity
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 14.5 error XML Element
|
||||||
|
///
|
||||||
|
/// Name: error
|
||||||
|
///
|
||||||
|
/// Purpose: Error responses, particularly 403 Forbidden and 409
|
||||||
|
/// Conflict, sometimes need more information to indicate what went
|
||||||
|
/// wrong. In these cases, servers MAY return an XML response body
|
||||||
|
/// with a document element of 'error', containing child elements
|
||||||
|
/// identifying particular condition codes.
|
||||||
|
///
|
||||||
|
/// Description: Contains at least one XML element, and MUST NOT
|
||||||
|
/// contain text or mixed content. Any element that is a child of the
|
||||||
|
/// 'error' element is considered to be a precondition or
|
||||||
|
/// postcondition code. Unrecognized elements MUST be ignored.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT error ANY >
|
||||||
|
pub enum Error<T> {
|
||||||
/// Name: lock-token-matches-request-uri
|
/// Name: lock-token-matches-request-uri
|
||||||
///
|
///
|
||||||
/// Use with: 409 Conflict
|
/// Use with: 409 Conflict
|
||||||
|
@ -26,66 +100,63 @@ pub enum Error {
|
||||||
/// succeeding if it knows them all.
|
/// succeeding if it knows them all.
|
||||||
///
|
///
|
||||||
/// <!ELEMENT lock-token-submitted (href+) >
|
/// <!ELEMENT lock-token-submitted (href+) >
|
||||||
LockTokenSubmitted(Vec<String>),
|
LockTokenSubmitted(Vec<Href>),
|
||||||
NoConflictingLock,
|
|
||||||
|
/// Name: no-conflicting-lock (precondition)
|
||||||
|
///
|
||||||
|
/// Use with: Typically 423 Locked
|
||||||
|
///
|
||||||
|
/// Purpose: A LOCK request failed due the presence of an already
|
||||||
|
/// existing conflicting lock. Note that a lock can be in conflict
|
||||||
|
/// although the resource to which the request was directed is only
|
||||||
|
/// indirectly locked. In this case, the precondition code can be
|
||||||
|
/// used to inform the client about the resource that is the root of
|
||||||
|
/// the conflicting lock, avoiding a separate lookup of the
|
||||||
|
/// "lockdiscovery" property.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT no-conflicting-lock (href)* >
|
||||||
|
NoConflictingLock(Vec<Href>),
|
||||||
|
|
||||||
|
/// Name: no-external-entities
|
||||||
|
///
|
||||||
|
/// Use with: 403 Forbidden
|
||||||
|
///
|
||||||
|
/// Purpose: (precondition) -- If the server rejects a client request
|
||||||
|
/// because the request body contains an external entity, the server
|
||||||
|
/// SHOULD use this error.
|
||||||
NoExternalEntities,
|
NoExternalEntities,
|
||||||
|
|
||||||
|
/// Name: preserved-live-properties
|
||||||
|
///
|
||||||
|
/// Use with: 409 Conflict
|
||||||
|
///
|
||||||
|
/// Purpose: (postcondition) -- The server received an otherwise-valid
|
||||||
|
/// MOVE or COPY request, but cannot maintain the live properties with
|
||||||
|
/// the same behavior at the destination. It may be that the server
|
||||||
|
/// only supports some live properties in some parts of the
|
||||||
|
/// repository, or simply has an internal error.
|
||||||
PreservedLiveProperties,
|
PreservedLiveProperties,
|
||||||
|
|
||||||
|
/// Name: propfind-finite-depth
|
||||||
|
///
|
||||||
|
/// Use with: 403 Forbidden
|
||||||
|
///
|
||||||
|
/// Purpose: (precondition) -- This server does not allow infinite-depth
|
||||||
|
/// PROPFIND requests on collections.
|
||||||
PropfindFiniteDepth,
|
PropfindFiniteDepth,
|
||||||
Calendar(u64),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 14.1. activelock XML Element
|
|
||||||
///
|
|
||||||
/// Name: activelock
|
|
||||||
///
|
|
||||||
/// Purpose: Describes a lock on a resource.
|
|
||||||
/// <!ELEMENT activelock (lockscope, locktype, depth, owner?, timeout?,
|
|
||||||
/// locktoken?, lockroot)>
|
|
||||||
pub struct ActiveLock {
|
|
||||||
lockscope: u64,
|
|
||||||
locktype: u64,
|
|
||||||
depth: Depth,
|
|
||||||
owner: Option<u64>,
|
|
||||||
timeout: Option<u64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// allprop XML Element
|
/// Name: cannot-modify-protected-property
|
||||||
///
|
///
|
||||||
/// Name: allprop
|
/// Use with: 403 Forbidden
|
||||||
///
|
///
|
||||||
/// Purpose: Specifies that all names and values of dead properties and
|
/// Purpose: (precondition) -- The client attempted to set a protected
|
||||||
/// the live properties defined by this document existing on the
|
/// property in a PROPPATCH (such as DAV:getetag). See also
|
||||||
/// resource are to be returned.
|
/// [RFC3253], Section 3.12.
|
||||||
///
|
CannotModifyProtectedProperty,
|
||||||
/// <!ELEMENT allprop EMPTY >
|
|
||||||
pub struct AllProp{}
|
|
||||||
|
|
||||||
/// collection XML Element
|
/// Specific errors
|
||||||
///
|
Extensions(T),
|
||||||
/// Name: collection
|
|
||||||
///
|
|
||||||
/// Purpose: Identifies the associated resource as a collection. The
|
|
||||||
/// DAV:resourcetype property of a collection resource MUST contain
|
|
||||||
/// this element. It is normally empty but extensions may add sub-
|
|
||||||
/// elements.
|
|
||||||
///
|
|
||||||
/// <!ELEMENT collection EMPTY >
|
|
||||||
pub struct Collection{}
|
|
||||||
|
|
||||||
/// depth XML Element
|
|
||||||
///
|
|
||||||
/// Name: depth
|
|
||||||
///
|
|
||||||
/// Purpose: Used for representing depth values in XML content (e.g.,
|
|
||||||
/// in lock information).
|
|
||||||
///
|
|
||||||
/// Value: "0" | "1" | "infinity"
|
|
||||||
///
|
|
||||||
/// <!ELEMENT depth (#PCDATA) >
|
|
||||||
pub enum Depth {
|
|
||||||
Zero,
|
|
||||||
One,
|
|
||||||
Infinity
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 14.6. exclusive XML Element
|
/// 14.6. exclusive XML Element
|
||||||
|
@ -97,14 +168,180 @@ pub enum Depth {
|
||||||
/// <!ELEMENT exclusive EMPTY >
|
/// <!ELEMENT exclusive EMPTY >
|
||||||
pub struct Exclusive {}
|
pub struct Exclusive {}
|
||||||
|
|
||||||
pub struct Href(String);
|
/// 14.7. href XML Element
|
||||||
|
///
|
||||||
|
/// Name: href
|
||||||
|
///
|
||||||
|
/// Purpose: MUST contain a URI or a relative reference.
|
||||||
|
///
|
||||||
|
/// Description: There may be limits on the value of 'href' depending
|
||||||
|
/// on the context of its use. Refer to the specification text where
|
||||||
|
/// 'href' is used to see what limitations apply in each case.
|
||||||
|
///
|
||||||
|
/// Value: Simple-ref
|
||||||
|
///
|
||||||
|
/// <!ELEMENT href (#PCDATA)>
|
||||||
|
pub struct Href(pub String);
|
||||||
|
|
||||||
pub struct Status(String);
|
|
||||||
|
|
||||||
pub struct ResponseDescription(String);
|
/// 14.8. include XML Element
|
||||||
|
///
|
||||||
|
/// Name: include
|
||||||
|
///
|
||||||
|
/// Purpose: Any child element represents the name of a property to be
|
||||||
|
/// included in the PROPFIND response. All elements inside an
|
||||||
|
/// 'include' XML element MUST define properties related to the
|
||||||
|
/// resource, although possible property names are in no way limited
|
||||||
|
/// to those property names defined in this document or other
|
||||||
|
/// standards. This element MUST NOT contain text or mixed content.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT include ANY >
|
||||||
|
pub struct Include(Vec<Property>);
|
||||||
|
|
||||||
|
/// 14.9. location XML Element
|
||||||
|
///
|
||||||
|
/// Name: location
|
||||||
|
///
|
||||||
|
/// Purpose: HTTP defines the "Location" header (see [RFC2616], Section
|
||||||
|
/// 14.30) for use with some status codes (such as 201 and the 300
|
||||||
|
/// series codes). When these codes are used inside a 'multistatus'
|
||||||
|
/// element, the 'location' element can be used to provide the
|
||||||
|
/// accompanying Location header value.
|
||||||
|
///
|
||||||
|
/// Description: Contains a single href element with the same value
|
||||||
|
/// that would be used in a Location header.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT location (href)>
|
||||||
pub struct Location(Href);
|
pub struct Location(Href);
|
||||||
|
|
||||||
|
/// 14.10. lockentry XML Element
|
||||||
|
///
|
||||||
|
/// Name: lockentry
|
||||||
|
///
|
||||||
|
/// Purpose: Defines the types of locks that can be used with the
|
||||||
|
/// resource.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT lockentry (lockscope, locktype) >
|
||||||
|
pub struct LockEntry {
|
||||||
|
lokscope: LockScope,
|
||||||
|
locktype: LockType,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 14.11. lockinfo XML Element
|
||||||
|
///
|
||||||
|
/// Name: lockinfo
|
||||||
|
///
|
||||||
|
/// Purpose: The 'lockinfo' XML element is used with a LOCK method to
|
||||||
|
/// specify the type of lock the client wishes to have created.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT lockinfo (lockscope, locktype, owner?) >
|
||||||
|
pub struct LockInfo {
|
||||||
|
lockscope: LockScope,
|
||||||
|
locktype: LockType,
|
||||||
|
owner: Option<Owner>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 14.12. lockroot XML Element
|
||||||
|
///
|
||||||
|
/// Name: lockroot
|
||||||
|
///
|
||||||
|
/// Purpose: Contains the root URL of the lock, which is the URL
|
||||||
|
/// through which the resource was addressed in the LOCK request.
|
||||||
|
///
|
||||||
|
/// Description: The href element contains the root of the lock. The
|
||||||
|
/// server SHOULD include this in all DAV:lockdiscovery property
|
||||||
|
/// values and the response to LOCK requests.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT lockroot (href) >
|
||||||
|
pub struct LockRoot(Href);
|
||||||
|
|
||||||
|
/// 14.13. lockscope XML Element
|
||||||
|
///
|
||||||
|
/// Name: lockscope
|
||||||
|
///
|
||||||
|
/// Purpose: Specifies whether a lock is an exclusive lock, or a shared
|
||||||
|
/// lock.
|
||||||
|
/// <!ELEMENT lockscope (exclusive | shared) >
|
||||||
|
pub enum LockScope {
|
||||||
|
Exclusive,
|
||||||
|
Shared
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 14.14. locktoken XML Element
|
||||||
|
///
|
||||||
|
/// Name: locktoken
|
||||||
|
///
|
||||||
|
/// Purpose: The lock token associated with a lock.
|
||||||
|
///
|
||||||
|
/// Description: The href contains a single lock token URI, which
|
||||||
|
/// refers to the lock.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT locktoken (href) >
|
||||||
|
pub struct LockToken(Href);
|
||||||
|
|
||||||
|
/// 14.15. locktype XML Element
|
||||||
|
///
|
||||||
|
/// Name: locktype
|
||||||
|
///
|
||||||
|
/// Purpose: Specifies the access type of a lock. At present, this
|
||||||
|
/// specification only defines one lock type, the write lock.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT locktype (write) >
|
||||||
|
pub enum LockType {
|
||||||
|
/// 14.30. write XML Element
|
||||||
|
///
|
||||||
|
/// Name: write
|
||||||
|
///
|
||||||
|
/// Purpose: Specifies a write lock.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// <!ELEMENT write EMPTY >
|
||||||
|
Write
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 14.16. multistatus XML Element
|
||||||
|
///
|
||||||
|
/// Name: multistatus
|
||||||
|
///
|
||||||
|
/// Purpose: Contains multiple response messages.
|
||||||
|
///
|
||||||
|
/// Description: The 'responsedescription' element at the top level is
|
||||||
|
/// used to provide a general message describing the overarching
|
||||||
|
/// nature of the response. If this value is available, an
|
||||||
|
/// application may use it instead of presenting the individual
|
||||||
|
/// response descriptions contained within the responses.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT multistatus (response*, responsedescription?) >
|
||||||
|
pub struct Multistatus<T> {
|
||||||
|
responses: Vec<Response<T>>,
|
||||||
|
responsedescription: Option<ResponseDescription>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 14.17. owner XML Element
|
||||||
|
///
|
||||||
|
/// Name: owner
|
||||||
|
///
|
||||||
|
/// Purpose: Holds client-supplied information about the creator of a
|
||||||
|
/// lock.
|
||||||
|
///
|
||||||
|
/// Description: Allows a client to provide information sufficient for
|
||||||
|
/// either directly contacting a principal (such as a telephone number
|
||||||
|
/// or Email URI), or for discovering the principal (such as the URL
|
||||||
|
/// of a homepage) who created a lock. The value provided MUST be
|
||||||
|
/// treated as a dead property in terms of XML Information Item
|
||||||
|
/// preservation. The server MUST NOT alter the value unless the
|
||||||
|
/// owner value provided by the client is empty. For a certain amount
|
||||||
|
/// of interoperability between different client implementations, if
|
||||||
|
/// clients have URI-formatted contact information for the lock
|
||||||
|
/// creator suitable for user display, then clients SHOULD put those
|
||||||
|
/// URIs in 'href' child elements of the 'owner' element.
|
||||||
|
///
|
||||||
|
/// Extensibility: MAY be extended with child elements, mixed content,
|
||||||
|
/// text content or attributes.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT owner ANY >
|
||||||
|
pub struct Owner(String);
|
||||||
|
|
||||||
/// 14.18. prop XML Element
|
/// 14.18. prop XML Element
|
||||||
///
|
///
|
||||||
/// Name: prop
|
/// Name: prop
|
||||||
|
@ -119,11 +356,52 @@ pub struct Location(Href);
|
||||||
/// text or mixed content.
|
/// text or mixed content.
|
||||||
///
|
///
|
||||||
/// <!ELEMENT prop ANY >
|
/// <!ELEMENT prop ANY >
|
||||||
pub struct Prop {
|
pub struct Prop(Vec<Property>);
|
||||||
something: u64,
|
|
||||||
|
/// 14.19. propertyupdate XML Element
|
||||||
|
///
|
||||||
|
/// Name: propertyupdate
|
||||||
|
///
|
||||||
|
/// Purpose: Contains a request to alter the properties on a resource.
|
||||||
|
///
|
||||||
|
/// Description: This XML element is a container for the information
|
||||||
|
/// required to modify the properties on the resource.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT propertyupdate (remove | set)+ >
|
||||||
|
pub struct PropertyUpdate(Vec<PropertyUpdateItem>);
|
||||||
|
pub enum PropertyUpdateItem {
|
||||||
|
Remove(Remove),
|
||||||
|
Set(Set),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// propstat XML Element
|
/// 14.20. propfind XML Element
|
||||||
|
///
|
||||||
|
/// Name: propfind
|
||||||
|
///
|
||||||
|
/// Purpose: Specifies the properties to be returned from a PROPFIND
|
||||||
|
/// method. Four special elements are specified for use with
|
||||||
|
/// 'propfind': 'prop', 'allprop', 'include', and 'propname'. If
|
||||||
|
/// 'prop' is used inside 'propfind', it MUST NOT contain property
|
||||||
|
/// values.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT propfind ( propname | (allprop, include?) | prop ) >
|
||||||
|
pub enum PropFind {
|
||||||
|
PropName(PropName),
|
||||||
|
AllProp(AllProp, Option<Include>),
|
||||||
|
Prop(Prop),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 14.21. propname XML Element
|
||||||
|
///
|
||||||
|
/// Name: propname
|
||||||
|
///
|
||||||
|
/// Purpose: Specifies that only a list of property names on the
|
||||||
|
/// resource is to be returned.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT propname EMPTY >
|
||||||
|
pub struct PropName {}
|
||||||
|
|
||||||
|
/// 14.22 propstat XML Element
|
||||||
///
|
///
|
||||||
/// Name: propstat
|
/// Name: propstat
|
||||||
///
|
///
|
||||||
|
@ -138,13 +416,28 @@ pub struct Prop {
|
||||||
/// the properties named in 'prop'.
|
/// the properties named in 'prop'.
|
||||||
///
|
///
|
||||||
/// <!ELEMENT propstat (prop, status, error?, responsedescription?) >
|
/// <!ELEMENT propstat (prop, status, error?, responsedescription?) >
|
||||||
pub struct PropStat {
|
pub struct PropStat<T> {
|
||||||
prop: Prop,
|
prop: Prop,
|
||||||
status: Status,
|
status: Status,
|
||||||
error: Option<Error>,
|
error: Option<Error<T>>,
|
||||||
responsedescription: Option<ResponseDescription>,
|
responsedescription: Option<ResponseDescription>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 14.23. remove XML Element
|
||||||
|
///
|
||||||
|
/// Name: remove
|
||||||
|
///
|
||||||
|
/// Purpose: Lists the properties to be removed from a resource.
|
||||||
|
///
|
||||||
|
/// Description: Remove instructs that the properties specified in prop
|
||||||
|
/// should be removed. Specifying the removal of a property that does
|
||||||
|
/// not exist is not an error. All the XML elements in a 'prop' XML
|
||||||
|
/// element inside of a 'remove' XML element MUST be empty, as only
|
||||||
|
/// the names of properties to be removed are required.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT remove (prop) >
|
||||||
|
pub struct Remove(Prop);
|
||||||
|
|
||||||
/// 14.24. response XML Element
|
/// 14.24. response XML Element
|
||||||
///
|
///
|
||||||
/// Name: response
|
/// Name: response
|
||||||
|
@ -167,31 +460,397 @@ pub struct PropStat {
|
||||||
///
|
///
|
||||||
/// <!ELEMENT response (href, ((href*, status)|(propstat+)),
|
/// <!ELEMENT response (href, ((href*, status)|(propstat+)),
|
||||||
/// error?, responsedescription? , location?) >
|
/// error?, responsedescription? , location?) >
|
||||||
pub struct Response {
|
pub struct Response<T> {
|
||||||
href: Vec<Href>,
|
href: Vec<Href>,
|
||||||
status: Status,
|
status: Status,
|
||||||
propstat: Vec<PropStat>,
|
propstat: Vec<PropStat<T>>,
|
||||||
error: Option<Error>,
|
error: Option<Error<T>>,
|
||||||
responsedescription: Option<ResponseDescription>,
|
responsedescription: Option<ResponseDescription>,
|
||||||
location: Option<u64>,
|
location: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 14.16. multistatus XML Element
|
/// 14.25. responsedescription XML Element
|
||||||
///
|
///
|
||||||
/// Name: multistatus
|
/// Name: responsedescription
|
||||||
///
|
///
|
||||||
/// Purpose: Contains multiple response messages.
|
/// Purpose: Contains information about a status response within a
|
||||||
|
/// Multi-Status.
|
||||||
///
|
///
|
||||||
/// Description: The 'responsedescription' element at the top level is
|
/// Description: Provides information suitable to be presented to a
|
||||||
/// used to provide a general message describing the overarching
|
/// user.
|
||||||
/// nature of the response. If this value is available, an
|
|
||||||
/// application may use it instead of presenting the individual
|
|
||||||
/// response descriptions contained within the responses.
|
|
||||||
///
|
///
|
||||||
/// <!ELEMENT multistatus (response*, responsedescription?) >
|
/// <!ELEMENT responsedescription (#PCDATA) >
|
||||||
pub struct Multistatus {
|
pub struct ResponseDescription(String);
|
||||||
responses: Vec<Response>,
|
|
||||||
responsedescription: Option<ResponseDescription>,
|
/// 14.26. set XML Element
|
||||||
|
///
|
||||||
|
/// Name: set
|
||||||
|
///
|
||||||
|
/// Purpose: Lists the property values to be set for a resource.
|
||||||
|
///
|
||||||
|
/// Description: The 'set' element MUST contain only a 'prop' element.
|
||||||
|
/// The elements contained by the 'prop' element inside the 'set'
|
||||||
|
/// element MUST specify the name and value of properties that are set
|
||||||
|
/// on the resource identified by Request-URI. If a property already
|
||||||
|
/// exists, then its value is replaced. Language tagging information
|
||||||
|
/// appearing in the scope of the 'prop' element (in the "xml:lang"
|
||||||
|
/// attribute, if present) MUST be persistently stored along with the
|
||||||
|
/// property, and MUST be subsequently retrievable using PROPFIND.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT set (prop) >
|
||||||
|
pub struct Set(Prop);
|
||||||
|
|
||||||
|
/// 14.27. shared XML Element
|
||||||
|
///
|
||||||
|
/// Name: shared
|
||||||
|
///
|
||||||
|
/// Purpose: Specifies a shared lock.
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// <!ELEMENT shared EMPTY >
|
||||||
|
pub struct Shared {}
|
||||||
|
|
||||||
|
|
||||||
|
/// 14.28. status XML Element
|
||||||
|
///
|
||||||
|
/// Name: status
|
||||||
|
///
|
||||||
|
/// Purpose: Holds a single HTTP status-line.
|
||||||
|
///
|
||||||
|
/// Value: status-line (defined in Section 6.1 of [RFC2616])
|
||||||
|
///
|
||||||
|
/// <!ELEMENT status (#PCDATA) >
|
||||||
|
//@FIXME: Better typing is possible with an enum for example
|
||||||
|
pub struct Status(http::status::StatusCode);
|
||||||
|
|
||||||
|
/// 14.29. timeout XML Element
|
||||||
|
///
|
||||||
|
/// Name: timeout
|
||||||
|
///
|
||||||
|
/// Purpose: The number of seconds remaining before a lock expires.
|
||||||
|
///
|
||||||
|
/// Value: TimeType (defined in Section 10.7)
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// <!ELEMENT timeout (#PCDATA) >
|
||||||
|
pub struct Timeout(u64);
|
||||||
|
|
||||||
|
|
||||||
|
/// 15. DAV Properties
|
||||||
|
///
|
||||||
|
/// For DAV properties, the name of the property is also the same as the
|
||||||
|
/// name of the XML element that contains its value. In the section
|
||||||
|
/// below, the final line of each section gives the element type
|
||||||
|
/// declaration using the format defined in [REC-XML]. The "Value"
|
||||||
|
/// field, where present, specifies further restrictions on the allowable
|
||||||
|
/// contents of the XML element using BNF (i.e., to further restrict the
|
||||||
|
/// values of a PCDATA element).
|
||||||
|
///
|
||||||
|
/// A protected property is one that cannot be changed with a PROPPATCH
|
||||||
|
/// request. There may be other requests that would result in a change
|
||||||
|
/// to a protected property (as when a LOCK request affects the value of
|
||||||
|
/// DAV:lockdiscovery). Note that a given property could be protected on
|
||||||
|
/// one type of resource, but not protected on another type of resource.
|
||||||
|
///
|
||||||
|
/// A computed property is one with a value defined in terms of a
|
||||||
|
/// computation (based on the content and other properties of that
|
||||||
|
/// resource, or even of some other resource). A computed property is
|
||||||
|
/// always a protected property.
|
||||||
|
///
|
||||||
|
/// COPY and MOVE behavior refers to local COPY and MOVE operations.
|
||||||
|
///
|
||||||
|
/// For properties defined based on HTTP GET response headers (DAV:get*),
|
||||||
|
/// the header value could include LWS as defined in [RFC2616], Section
|
||||||
|
/// 4.2. Server implementors SHOULD strip LWS from these values before
|
||||||
|
/// using as WebDAV property values.
|
||||||
|
pub enum PropertyRequest {
|
||||||
|
CreationDate,
|
||||||
|
DisplayName,
|
||||||
|
GetContentLanguage,
|
||||||
|
GetContentLength,
|
||||||
|
GetContentType,
|
||||||
|
GetEtag,
|
||||||
|
GetLastModified,
|
||||||
|
LockDiscovery,
|
||||||
|
ResourceType,
|
||||||
|
}
|
||||||
|
pub enum Property {
|
||||||
|
/// 15.1. creationdate Property
|
||||||
|
///
|
||||||
|
/// Name: creationdate
|
||||||
|
///
|
||||||
|
/// Purpose: Records the time and date the resource was created.
|
||||||
|
///
|
||||||
|
/// Value: date-time (defined in [RFC3339], see the ABNF in Section
|
||||||
|
/// 5.6.)
|
||||||
|
///
|
||||||
|
/// Protected: MAY be protected. Some servers allow DAV:creationdate
|
||||||
|
/// to be changed to reflect the time the document was created if that
|
||||||
|
/// is more meaningful to the user (rather than the time it was
|
||||||
|
/// uploaded). Thus, clients SHOULD NOT use this property in
|
||||||
|
/// synchronization logic (use DAV:getetag instead).
|
||||||
|
///
|
||||||
|
/// COPY/MOVE behavior: This property value SHOULD be kept during a
|
||||||
|
/// MOVE operation, but is normally re-initialized when a resource is
|
||||||
|
/// created with a COPY. It should not be set in a COPY.
|
||||||
|
///
|
||||||
|
/// Description: The DAV:creationdate property SHOULD be defined on all
|
||||||
|
/// DAV compliant resources. If present, it contains a timestamp of
|
||||||
|
/// the moment when the resource was created. Servers that are
|
||||||
|
/// incapable of persistently recording the creation date SHOULD
|
||||||
|
/// instead leave it undefined (i.e. report "Not Found").
|
||||||
|
///
|
||||||
|
/// <!ELEMENT creationdate (#PCDATA) >
|
||||||
|
CreationDate(DateTime<FixedOffset>),
|
||||||
|
|
||||||
|
/// 15.2. displayname Property
|
||||||
|
///
|
||||||
|
/// Name: displayname
|
||||||
|
///
|
||||||
|
/// Purpose: Provides a name for the resource that is suitable for
|
||||||
|
/// presentation to a user.
|
||||||
|
///
|
||||||
|
/// Value: Any text.
|
||||||
|
///
|
||||||
|
/// Protected: SHOULD NOT be protected. Note that servers implementing
|
||||||
|
/// [RFC2518] might have made this a protected property as this is a
|
||||||
|
/// new requirement.
|
||||||
|
///
|
||||||
|
/// COPY/MOVE behavior: This property value SHOULD be preserved in COPY
|
||||||
|
/// and MOVE operations.
|
||||||
|
///
|
||||||
|
/// Description: Contains a description of the resource that is
|
||||||
|
/// suitable for presentation to a user. This property is defined on
|
||||||
|
/// the resource, and hence SHOULD have the same value independent of
|
||||||
|
/// the Request-URI used to retrieve it (thus, computing this property
|
||||||
|
/// based on the Request-URI is deprecated). While generic clients
|
||||||
|
/// might display the property value to end users, client UI designers
|
||||||
|
/// must understand that the method for identifying resources is still
|
||||||
|
/// the URL. Changes to DAV:displayname do not issue moves or copies
|
||||||
|
/// to the server, but simply change a piece of meta-data on the
|
||||||
|
/// individual resource. Two resources can have the same DAV:
|
||||||
|
/// displayname value even within the same collection.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT displayname (#PCDATA) >
|
||||||
|
DisplayName(String),
|
||||||
|
|
||||||
|
|
||||||
|
/// 15.3. getcontentlanguage Property
|
||||||
|
///
|
||||||
|
/// Name: getcontentlanguage
|
||||||
|
///
|
||||||
|
/// Purpose: Contains the Content-Language header value (from Section
|
||||||
|
/// 14.12 of [RFC2616]) as it would be returned by a GET without
|
||||||
|
/// accept headers.
|
||||||
|
///
|
||||||
|
/// Value: language-tag (language-tag is defined in Section 3.10 of
|
||||||
|
/// [RFC2616])
|
||||||
|
///
|
||||||
|
/// Protected: SHOULD NOT be protected, so that clients can reset the
|
||||||
|
/// language. Note that servers implementing [RFC2518] might have
|
||||||
|
/// made this a protected property as this is a new requirement.
|
||||||
|
///
|
||||||
|
/// COPY/MOVE behavior: This property value SHOULD be preserved in COPY
|
||||||
|
/// and MOVE operations.
|
||||||
|
///
|
||||||
|
/// Description: The DAV:getcontentlanguage property MUST be defined on
|
||||||
|
/// any DAV-compliant resource that returns the Content-Language
|
||||||
|
/// header on a GET.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT getcontentlanguage (#PCDATA) >
|
||||||
|
GetContentLanguage(String),
|
||||||
|
|
||||||
|
/// 15.4. getcontentlength Property
|
||||||
|
///
|
||||||
|
/// Name: getcontentlength
|
||||||
|
///
|
||||||
|
/// Purpose: Contains the Content-Length header returned by a GET
|
||||||
|
/// without accept headers.
|
||||||
|
///
|
||||||
|
/// Value: See Section 14.13 of [RFC2616].
|
||||||
|
///
|
||||||
|
/// Protected: This property is computed, therefore protected.
|
||||||
|
///
|
||||||
|
/// Description: The DAV:getcontentlength property MUST be defined on
|
||||||
|
/// any DAV-compliant resource that returns the Content-Length header
|
||||||
|
/// in response to a GET.
|
||||||
|
///
|
||||||
|
/// COPY/MOVE behavior: This property value is dependent on the size of
|
||||||
|
/// the destination resource, not the value of the property on the
|
||||||
|
/// source resource.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT getcontentlength (#PCDATA) >
|
||||||
|
GetContentLength(u64),
|
||||||
|
|
||||||
|
/// 15.5. getcontenttype Property
|
||||||
|
///
|
||||||
|
/// Name: getcontenttype
|
||||||
|
///
|
||||||
|
/// Purpose: Contains the Content-Type header value (from Section 14.17
|
||||||
|
/// of [RFC2616]) as it would be returned by a GET without accept
|
||||||
|
/// headers.
|
||||||
|
///
|
||||||
|
/// Value: media-type (defined in Section 3.7 of [RFC2616])
|
||||||
|
///
|
||||||
|
/// Protected: Potentially protected if the server prefers to assign
|
||||||
|
/// content types on its own (see also discussion in Section 9.7.1).
|
||||||
|
///
|
||||||
|
/// COPY/MOVE behavior: This property value SHOULD be preserved in COPY
|
||||||
|
/// and MOVE operations.
|
||||||
|
///
|
||||||
|
/// Description: This property MUST be defined on any DAV-compliant
|
||||||
|
/// resource that returns the Content-Type header in response to a
|
||||||
|
/// GET.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT getcontenttype (#PCDATA) >
|
||||||
|
GetContentType(String),
|
||||||
|
|
||||||
|
/// 15.6. getetag Property
|
||||||
|
///
|
||||||
|
/// Name: getetag
|
||||||
|
///
|
||||||
|
/// Purpose: Contains the ETag header value (from Section 14.19 of
|
||||||
|
/// [RFC2616]) as it would be returned by a GET without accept
|
||||||
|
/// headers.
|
||||||
|
///
|
||||||
|
/// Value: entity-tag (defined in Section 3.11 of [RFC2616])
|
||||||
|
///
|
||||||
|
/// Protected: MUST be protected because this value is created and
|
||||||
|
/// controlled by the server.
|
||||||
|
///
|
||||||
|
/// COPY/MOVE behavior: This property value is dependent on the final
|
||||||
|
/// state of the destination resource, not the value of the property
|
||||||
|
/// on the source resource. Also note the considerations in
|
||||||
|
/// Section 8.8.
|
||||||
|
///
|
||||||
|
/// Description: The getetag property MUST be defined on any DAV-
|
||||||
|
/// compliant resource that returns the Etag header. Refer to Section
|
||||||
|
/// 3.11 of RFC 2616 for a complete definition of the semantics of an
|
||||||
|
/// ETag, and to Section 8.6 for a discussion of ETags in WebDAV.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT getetag (#PCDATA) >
|
||||||
|
GetEtag(String),
|
||||||
|
|
||||||
|
/// 15.7. getlastmodified Property
|
||||||
|
///
|
||||||
|
/// Name: getlastmodified
|
||||||
|
///
|
||||||
|
/// Purpose: Contains the Last-Modified header value (from Section
|
||||||
|
/// 14.29 of [RFC2616]) as it would be returned by a GET method
|
||||||
|
/// without accept headers.
|
||||||
|
///
|
||||||
|
/// Value: rfc1123-date (defined in Section 3.3.1 of [RFC2616])
|
||||||
|
///
|
||||||
|
/// Protected: SHOULD be protected because some clients may rely on the
|
||||||
|
/// value for appropriate caching behavior, or on the value of the
|
||||||
|
/// Last-Modified header to which this property is linked.
|
||||||
|
///
|
||||||
|
/// COPY/MOVE behavior: This property value is dependent on the last
|
||||||
|
/// modified date of the destination resource, not the value of the
|
||||||
|
/// property on the source resource. Note that some server
|
||||||
|
/// implementations use the file system date modified value for the
|
||||||
|
/// DAV:getlastmodified value, and this can be preserved in a MOVE
|
||||||
|
/// even when the HTTP Last-Modified value SHOULD change. Note that
|
||||||
|
/// since [RFC2616] requires clients to use ETags where provided, a
|
||||||
|
/// server implementing ETags can count on clients using a much better
|
||||||
|
/// mechanism than modification dates for offline synchronization or
|
||||||
|
/// cache control. Also note the considerations in Section 8.8.
|
||||||
|
///
|
||||||
|
/// Description: The last-modified date on a resource SHOULD only
|
||||||
|
/// reflect changes in the body (the GET responses) of the resource.
|
||||||
|
/// A change in a property only SHOULD NOT cause the last-modified
|
||||||
|
/// date to change, because clients MAY rely on the last-modified date
|
||||||
|
/// to know when to overwrite the existing body. The DAV:
|
||||||
|
/// getlastmodified property MUST be defined on any DAV-compliant
|
||||||
|
/// resource that returns the Last-Modified header in response to a
|
||||||
|
/// GET.
|
||||||
|
///
|
||||||
|
/// <!ELEMENT getlastmodified (#PCDATA) >
|
||||||
|
GetLastModified(DateTime<FixedOffset>),
|
||||||
|
|
||||||
|
/// 15.8. lockdiscovery Property
|
||||||
|
///
|
||||||
|
/// Name: lockdiscovery
|
||||||
|
///
|
||||||
|
/// Purpose: Describes the active locks on a resource
|
||||||
|
///
|
||||||
|
/// Protected: MUST be protected. Clients change the list of locks
|
||||||
|
/// through LOCK and UNLOCK, not through PROPPATCH.
|
||||||
|
///
|
||||||
|
/// COPY/MOVE behavior: The value of this property depends on the lock
|
||||||
|
/// state of the destination, not on the locks of the source resource.
|
||||||
|
/// Recall that locks are not moved in a MOVE operation.
|
||||||
|
///
|
||||||
|
/// Description: Returns a listing of who has a lock, what type of lock
|
||||||
|
/// he has, the timeout type and the time remaining on the timeout,
|
||||||
|
/// and the associated lock token. Owner information MAY be omitted
|
||||||
|
/// if it is considered sensitive. If there are no locks, but the
|
||||||
|
/// server supports locks, the property will be present but contain
|
||||||
|
/// zero 'activelock' elements. If there are one or more locks, an
|
||||||
|
/// 'activelock' element appears for each lock on the resource. This
|
||||||
|
/// property is NOT lockable with respect to write locks (Section 7).
|
||||||
|
///
|
||||||
|
/// <!ELEMENT lockdiscovery (activelock)* >
|
||||||
|
LockDiscovery(Vec<ActiveLock>),
|
||||||
|
|
||||||
|
|
||||||
|
/// 15.9. resourcetype Property
|
||||||
|
///
|
||||||
|
/// Name: resourcetype
|
||||||
|
///
|
||||||
|
/// Purpose: Specifies the nature of the resource.
|
||||||
|
///
|
||||||
|
/// Protected: SHOULD be protected. Resource type is generally decided
|
||||||
|
/// through the operation creating the resource (MKCOL vs PUT), not by
|
||||||
|
/// PROPPATCH.
|
||||||
|
///
|
||||||
|
/// COPY/MOVE behavior: Generally a COPY/MOVE of a resource results in
|
||||||
|
/// the same type of resource at the destination.
|
||||||
|
///
|
||||||
|
/// Description: MUST be defined on all DAV-compliant resources. Each
|
||||||
|
/// child element identifies a specific type the resource belongs to,
|
||||||
|
/// such as 'collection', which is the only resource type defined by
|
||||||
|
/// this specification (see Section 14.3). If the element contains
|
||||||
|
/// the 'collection' child element plus additional unrecognized
|
||||||
|
/// elements, it should generally be treated as a collection. If the
|
||||||
|
/// element contains no recognized child elements, it should be
|
||||||
|
/// treated as a non-collection resource. The default value is empty.
|
||||||
|
/// This element MUST NOT contain text or mixed content. Any custom
|
||||||
|
/// child element is considered to be an identifier for a resource
|
||||||
|
/// type.
|
||||||
|
///
|
||||||
|
/// Example: (fictional example to show extensibility)
|
||||||
|
///
|
||||||
|
/// <x:resourcetype xmlns:x="DAV:">
|
||||||
|
/// <x:collection/>
|
||||||
|
/// <f:search-results xmlns:f="http://www.example.com/ns"/>
|
||||||
|
/// </x:resourcetype>
|
||||||
|
ResourceType(Collection),
|
||||||
|
|
||||||
|
/// 15.10. supportedlock Property
|
||||||
|
///
|
||||||
|
/// Name: supportedlock
|
||||||
|
///
|
||||||
|
/// Purpose: To provide a listing of the lock capabilities supported by
|
||||||
|
/// the resource.
|
||||||
|
///
|
||||||
|
/// Protected: MUST be protected. Servers, not clients, determine what
|
||||||
|
/// lock mechanisms are supported.
|
||||||
|
/// COPY/MOVE behavior: This property value is dependent on the kind of
|
||||||
|
/// locks supported at the destination, not on the value of the
|
||||||
|
/// property at the source resource. Servers attempting to COPY to a
|
||||||
|
/// destination should not attempt to set this property at the
|
||||||
|
/// destination.
|
||||||
|
///
|
||||||
|
/// Description: Returns a listing of the combinations of scope and
|
||||||
|
/// access types that may be specified in a lock request on the
|
||||||
|
/// resource. Note that the actual contents are themselves controlled
|
||||||
|
/// by access controls, so a server is not required to provide
|
||||||
|
/// information the client is not authorized to see. This property is
|
||||||
|
/// NOT lockable with respect to write locks (Section 7).
|
||||||
|
///
|
||||||
|
/// <!ELEMENT supportedlock (lockentry)* >
|
||||||
|
SupportedLock(Vec<LockEntry>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue