mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2025-10-06 18:45:45 +08:00
Store dead element's namespaces (#1545)
This commit is contained in:
parent
1b1f85a156
commit
85bc434fbf
15 changed files with 198 additions and 86 deletions
|
@ -5,8 +5,8 @@
|
|||
{
|
||||
"type": "ElementStart",
|
||||
"data": {
|
||||
"name": "D:href",
|
||||
"attrs": null
|
||||
"name": "href",
|
||||
"attrs": "xmlns=\"DAV:\""
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
{
|
||||
"type": "ElementStart",
|
||||
"data": {
|
||||
"name": "D:href",
|
||||
"attrs": null
|
||||
"name": "href",
|
||||
"attrs": "xmlns=\"DAV:\""
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -4,29 +4,29 @@
|
|||
{
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "R:bigbox",
|
||||
"attrs": null
|
||||
"name": "bigbox",
|
||||
"attrs": "xmlns=\"http://ns.example.com/boxschema/\""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "R:author",
|
||||
"attrs": null
|
||||
"name": "author",
|
||||
"attrs": "xmlns=\"http://ns.example.com/boxschema/\""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "R:DingALing",
|
||||
"attrs": null
|
||||
"name": "DingALing",
|
||||
"attrs": "xmlns=\"http://ns.example.com/boxschema/\""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "R:Random",
|
||||
"attrs": null
|
||||
"name": "Random",
|
||||
"attrs": "xmlns=\"http://ns.example.com/boxschema/\""
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
{
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "apple:calendar-color",
|
||||
"attrs": null
|
||||
"name": "calendar-color",
|
||||
"attrs": "xmlns=\"http://apple.com/ns/ical/\""
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
36
crates/dav-proto/resources/requests/propfind-010.json
Normal file
36
crates/dav-proto/resources/requests/propfind-010.json
Normal file
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"type": "Prop",
|
||||
"data": [
|
||||
{
|
||||
"type": "WebDav",
|
||||
"data": {
|
||||
"type": "ResourceType"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "WebDav",
|
||||
"data": {
|
||||
"type": "DisplayName"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "WebDav",
|
||||
"data": {
|
||||
"type": "SyncToken"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "WebDav",
|
||||
"data": {
|
||||
"type": "GetCTag"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "me-card",
|
||||
"attrs": "xmlns=\"http://calendarserver.org/ns/\" hello=\"world & test\""
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
1
crates/dav-proto/resources/requests/propfind-010.xml
Normal file
1
crates/dav-proto/resources/requests/propfind-010.xml
Normal file
|
@ -0,0 +1 @@
|
|||
<d:propfind xmlns:d="DAV:" xmlns:cs="http://calendarserver.org/ns/" xmlns:c="urn:ietf:params:xml:ns:carddav"><d:prop><d:resourcetype /><d:displayname/><d:sync-token></d:sync-token><cs:getctag /><cs:me-card hello="world & test"/></d:prop></d:propfind>
|
|
@ -14,8 +14,8 @@
|
|||
"property": {
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "B:title",
|
||||
"attrs": null
|
||||
"name": "title",
|
||||
"attrs": "xmlns=\"http://www.example.com/ns/\""
|
||||
}
|
||||
},
|
||||
"match_": "Sales"
|
||||
|
@ -31,29 +31,29 @@
|
|||
{
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "B:department",
|
||||
"attrs": null
|
||||
"name": "department",
|
||||
"attrs": "xmlns=\"http://www.example.com/ns/\""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "B:phone",
|
||||
"attrs": null
|
||||
"name": "phone",
|
||||
"attrs": "xmlns=\"http://www.example.com/ns/\""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "B:office",
|
||||
"attrs": null
|
||||
"name": "office",
|
||||
"attrs": "xmlns=\"http://www.example.com/ns/\""
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "DeadProperty",
|
||||
"data": {
|
||||
"name": "B:salary",
|
||||
"attrs": null
|
||||
"name": "salary",
|
||||
"attrs": "xmlns=\"http://www.example.com/ns/\""
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -20,11 +20,14 @@ pub mod tokenizer;
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Error {
|
||||
Xml(quick_xml::Error),
|
||||
UnexpectedToken {
|
||||
expected: Option<Token<'static>>,
|
||||
found: Token<'static>,
|
||||
},
|
||||
Xml(Box<quick_xml::Error>),
|
||||
UnexpectedToken(Box<UnexpectedToken>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UnexpectedToken {
|
||||
pub expected: Option<Token<'static>>,
|
||||
pub found: Token<'static>,
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
@ -43,7 +46,10 @@ pub enum Token<'x> {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RawElement<'x>(pub BytesStart<'x>);
|
||||
pub struct RawElement<'x> {
|
||||
pub element: BytesStart<'x>,
|
||||
pub namespace: Option<Cow<'static, [u8]>>,
|
||||
}
|
||||
|
||||
pub trait DavParser: Sized {
|
||||
fn parse(stream: &mut Tokenizer<'_>) -> Result<Self>;
|
||||
|
@ -89,20 +95,50 @@ impl Token<'_> {
|
|||
match self {
|
||||
Token::ElementStart { name, raw } => Token::ElementStart {
|
||||
name,
|
||||
raw: RawElement(raw.0.into_owned()),
|
||||
raw: raw.into_owned(),
|
||||
},
|
||||
Token::ElementEnd => Token::ElementEnd,
|
||||
Token::Bytes(bytes) => Token::Bytes(bytes.into_owned().into()),
|
||||
Token::Text(text) => Token::Text(text.into_owned().into()),
|
||||
Token::UnknownElement(raw) => Token::UnknownElement(RawElement(raw.0.into_owned())),
|
||||
Token::UnknownElement(raw) => Token::UnknownElement(raw.into_owned()),
|
||||
Token::Eof => Token::Eof,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_unexpected(self) -> Error {
|
||||
Error::UnexpectedToken {
|
||||
Error::UnexpectedToken(Box::new(UnexpectedToken {
|
||||
expected: None,
|
||||
found: self.into_owned(),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'x> RawElement<'x> {
|
||||
pub fn new(element: BytesStart<'x>) -> Self {
|
||||
RawElement {
|
||||
element,
|
||||
namespace: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_namespace(self, namespace: quick_xml::name::Namespace<'_>) -> Self {
|
||||
RawElement {
|
||||
element: self.element,
|
||||
namespace: Some(Cow::Owned(namespace.into_inner().to_vec())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_namespace_static(self, namespace: &'static [u8]) -> Self {
|
||||
RawElement {
|
||||
element: self.element,
|
||||
namespace: Some(Cow::Borrowed(namespace)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn into_owned(self) -> RawElement<'static> {
|
||||
RawElement {
|
||||
element: self.element.into_owned(),
|
||||
namespace: self.namespace,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,16 +159,17 @@ impl PartialEq for Token<'_> {
|
|||
) => {
|
||||
l_name == r_name
|
||||
&& l_raw
|
||||
.0
|
||||
.element
|
||||
.attributes_raw()
|
||||
.trim_ascii()
|
||||
.eq_ignore_ascii_case(r_raw.0.attributes_raw().trim_ascii())
|
||||
.eq_ignore_ascii_case(r_raw.element.attributes_raw().trim_ascii())
|
||||
}
|
||||
(Self::Bytes(l0), Self::Bytes(r0)) => l0 == r0,
|
||||
(Self::Text(l0), Self::Text(r0)) => l0 == r0,
|
||||
(Self::UnknownElement(l0), Self::UnknownElement(r0)) => {
|
||||
l0.0.as_ref().eq_ignore_ascii_case(r0.0.as_ref())
|
||||
}
|
||||
(Self::UnknownElement(l0), Self::UnknownElement(r0)) => l0
|
||||
.element
|
||||
.as_ref()
|
||||
.eq_ignore_ascii_case(r0.element.as_ref()),
|
||||
_ => core::mem::discriminant(self) == core::mem::discriminant(other),
|
||||
}
|
||||
}
|
||||
|
@ -140,19 +177,19 @@ impl PartialEq for Token<'_> {
|
|||
|
||||
impl NamedElement {
|
||||
pub fn into_unexpected(self) -> Error {
|
||||
Error::UnexpectedToken {
|
||||
Error::UnexpectedToken(Box::new(UnexpectedToken {
|
||||
expected: None,
|
||||
found: Token::ElementStart {
|
||||
name: self,
|
||||
raw: RawElement(BytesStart::new("")),
|
||||
raw: RawElement::new(BytesStart::new("")),
|
||||
},
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for RawElement<'_> {
|
||||
fn default() -> Self {
|
||||
RawElement(BytesStart::new(""))
|
||||
RawElement::new(BytesStart::new(""))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,9 +197,9 @@ impl Display for Error {
|
|||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Error::Xml(err) => write!(f, "XML error: {}", err),
|
||||
Error::UnexpectedToken { expected, found } => {
|
||||
write!(f, "Unexpected token: {found:?}")?;
|
||||
if let Some(expected) = expected {
|
||||
Error::UnexpectedToken(err) => {
|
||||
write!(f, "Unexpected token: {:?}", err.found)?;
|
||||
if let Some(expected) = &err.expected {
|
||||
write!(f, ", expected: {expected:?}")?;
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -65,7 +65,7 @@ impl Tokenizer<'_> {
|
|||
break;
|
||||
}
|
||||
Token::UnknownElement(name) => {
|
||||
elements.push(DavProperty::DeadProperty(name.into()));
|
||||
elements.push(DavProperty::DeadProperty((&name).into()));
|
||||
self.expect_element_end()?;
|
||||
}
|
||||
token => return Err(token.into_unexpected()),
|
||||
|
@ -369,7 +369,7 @@ impl Tokenizer<'_> {
|
|||
}
|
||||
Token::UnknownElement(raw) => {
|
||||
elements.push(DavPropertyValue {
|
||||
property: DavProperty::DeadProperty(raw.into()),
|
||||
property: DavProperty::DeadProperty((&raw).into()),
|
||||
value: DavValue::DeadProperty(DeadProperty::parse(self)?),
|
||||
});
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use quick_xml::{
|
|||
|
||||
use crate::schema::{Attribute, AttributeValue, Element, NamedElement, Namespace};
|
||||
|
||||
use super::{Error, RawElement, Token, XmlValueParser};
|
||||
use super::{Error, RawElement, Token, UnexpectedToken, XmlValueParser};
|
||||
|
||||
pub struct Tokenizer<'x> {
|
||||
xml: NsReader<&'x [u8]>,
|
||||
|
@ -47,7 +47,10 @@ impl<'x> Tokenizer<'x> {
|
|||
return Ok(Token::ElementEnd);
|
||||
}
|
||||
Event::Text(text) if text.iter().any(|ch| !ch.is_ascii_whitespace()) => {
|
||||
return text.unescape().map(Token::Text).map_err(Error::Xml);
|
||||
return text
|
||||
.unescape()
|
||||
.map(Token::Text)
|
||||
.map_err(|err| Error::Xml(Box::new(err)));
|
||||
}
|
||||
Event::CData(bytes) => return Ok(Token::Bytes(bytes.into_inner())),
|
||||
Event::Eof => return Ok(Token::Eof),
|
||||
|
@ -59,26 +62,29 @@ impl<'x> Tokenizer<'x> {
|
|||
// Parse element
|
||||
let name = tag.name();
|
||||
match resolve_result {
|
||||
ResolveResult::Bound(ns) if !ns.as_ref().is_empty() => {
|
||||
ResolveResult::Bound(raw_ns) if !raw_ns.as_ref().is_empty() => {
|
||||
if let (Some(ns), Some(element)) = (
|
||||
Namespace::try_parse(ns.as_ref()),
|
||||
Namespace::try_parse(raw_ns.as_ref()),
|
||||
Element::try_parse(name.local_name().as_ref()).copied(),
|
||||
) {
|
||||
return Ok(Token::ElementStart {
|
||||
name: NamedElement { ns, element },
|
||||
raw: RawElement(tag),
|
||||
raw: RawElement::new(tag)
|
||||
.with_namespace_static(ns.namespace().as_bytes()),
|
||||
});
|
||||
} else {
|
||||
return Ok(Token::UnknownElement(RawElement(tag)));
|
||||
return Ok(Token::UnknownElement(
|
||||
RawElement::new(tag).with_namespace(raw_ns),
|
||||
));
|
||||
}
|
||||
}
|
||||
ResolveResult::Unknown(p) => {
|
||||
return Err(Error::Xml(quick_xml::Error::Namespace(
|
||||
return Err(Error::Xml(Box::new(quick_xml::Error::Namespace(
|
||||
quick_xml::name::NamespaceError::UnknownPrefix(p),
|
||||
)))
|
||||
))))
|
||||
}
|
||||
_ => {
|
||||
return Ok(Token::UnknownElement(RawElement(tag)));
|
||||
return Ok(Token::UnknownElement(RawElement::new(tag)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,24 +93,24 @@ impl<'x> Tokenizer<'x> {
|
|||
pub fn unwrap_named_element(&mut self) -> super::Result<NamedElement> {
|
||||
match self.token()? {
|
||||
Token::ElementStart { name, .. } => Ok(name),
|
||||
found => Err(Error::UnexpectedToken {
|
||||
found => Err(Error::UnexpectedToken(Box::new(UnexpectedToken {
|
||||
expected: None,
|
||||
found: found.into_owned(),
|
||||
}),
|
||||
}))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_named_element(&mut self, expected: NamedElement) -> super::Result<()> {
|
||||
match self.token()? {
|
||||
Token::ElementStart { name, .. } if name == expected => Ok(()),
|
||||
found => Err(Error::UnexpectedToken {
|
||||
found => Err(Error::UnexpectedToken(Box::new(UnexpectedToken {
|
||||
expected: Token::ElementStart {
|
||||
name: expected,
|
||||
raw: RawElement::default(),
|
||||
}
|
||||
.into(),
|
||||
found: found.into_owned(),
|
||||
}),
|
||||
}))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,24 +118,24 @@ impl<'x> Tokenizer<'x> {
|
|||
match self.token()? {
|
||||
Token::ElementStart { name, .. } if name == expected => Ok(true),
|
||||
Token::Eof => Ok(false),
|
||||
found => Err(Error::UnexpectedToken {
|
||||
found => Err(Error::UnexpectedToken(Box::new(UnexpectedToken {
|
||||
expected: Token::ElementStart {
|
||||
name: expected,
|
||||
raw: RawElement::default(),
|
||||
}
|
||||
.into(),
|
||||
found: found.into_owned(),
|
||||
}),
|
||||
}))),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_element_end(&mut self) -> super::Result<()> {
|
||||
match self.token()? {
|
||||
Token::ElementEnd => Ok(()),
|
||||
found => Err(Error::UnexpectedToken {
|
||||
found => Err(Error::UnexpectedToken(Box::new(UnexpectedToken {
|
||||
expected: Token::ElementEnd.into(),
|
||||
found: found.into_owned(),
|
||||
}),
|
||||
}))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,7 +255,7 @@ impl RawElement<'_> {
|
|||
pub fn attributes<T: AttributeValue>(
|
||||
&self,
|
||||
) -> impl Iterator<Item = super::Result<Attribute<T>>> + '_ {
|
||||
self.0.attributes().filter_map(|attr| match attr {
|
||||
self.element.attributes().filter_map(|attr| match attr {
|
||||
Ok(attr) => match attr.unescape_value() {
|
||||
Ok(value) => Attribute::from_param(attr.key.as_ref(), value).map(Ok),
|
||||
Err(err) => Some(Err(err.into())),
|
||||
|
@ -261,13 +267,13 @@ impl RawElement<'_> {
|
|||
|
||||
impl From<quick_xml::Error> for Error {
|
||||
fn from(err: quick_xml::Error) -> Self {
|
||||
Error::Xml(err)
|
||||
Error::Xml(Box::new(err))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AttrError> for Error {
|
||||
fn from(err: AttrError) -> Self {
|
||||
Error::Xml(err.into())
|
||||
Error::Xml(Box::new(err.into()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ impl DavParser for DeadProperty {
|
|||
loop {
|
||||
match stream.token()? {
|
||||
Token::ElementStart { raw, .. } | Token::UnknownElement(raw) => {
|
||||
items.0.push(DeadPropertyTag::ElementStart(raw.into()));
|
||||
items.0.push(DeadPropertyTag::ElementStart((&raw).into()));
|
||||
depth += 1;
|
||||
}
|
||||
Token::ElementEnd => {
|
||||
|
@ -142,14 +142,42 @@ impl ArchivedDeadElementTag {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<RawElement<'_>> for DeadElementTag {
|
||||
fn from(raw: RawElement<'_>) -> Self {
|
||||
let name = String::from_utf8_lossy(raw.0.name().as_ref().trim_ascii()).into_owned();
|
||||
let attr = raw.0.attributes_raw().trim_ascii();
|
||||
impl From<&RawElement<'_>> for DeadElementTag {
|
||||
fn from(raw: &RawElement<'_>) -> Self {
|
||||
let name = std::str::from_utf8(raw.element.local_name().as_ref())
|
||||
.unwrap_or("invalid-utf8")
|
||||
.trim_ascii()
|
||||
.to_string();
|
||||
let mut attrs = String::with_capacity(raw.element.attributes_raw().len());
|
||||
if let Some(namespace) = &raw.namespace {
|
||||
attrs.push_str("xmlns=\"");
|
||||
attrs.push_str(std::str::from_utf8(namespace).unwrap_or("invalid-utf8"));
|
||||
attrs.push('"');
|
||||
}
|
||||
|
||||
for attr in raw.element.attributes().flatten() {
|
||||
if attr.key.as_ref() == b"xmlns" || attr.key.as_ref().starts_with(b"xmlns:") {
|
||||
// Skip namespace attributes
|
||||
continue;
|
||||
}
|
||||
if let (Ok(key), Ok(value)) = (
|
||||
std::str::from_utf8(attr.key.as_ref()),
|
||||
std::str::from_utf8(attr.value.as_ref()),
|
||||
) {
|
||||
if !attrs.is_empty() {
|
||||
attrs.push(' ');
|
||||
}
|
||||
attrs.push_str(key);
|
||||
attrs.push('=');
|
||||
attrs.push('"');
|
||||
attrs.push_str(value);
|
||||
attrs.push('"');
|
||||
}
|
||||
}
|
||||
|
||||
DeadElementTag {
|
||||
name,
|
||||
attrs: (!attr.is_empty()).then(|| String::from_utf8_lossy(attr).into_owned()),
|
||||
attrs: (!attrs.is_empty()).then_some(attrs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -528,7 +528,7 @@ impl DavParser for ExpandProperty {
|
|||
depth: depth - 1,
|
||||
});
|
||||
} else {
|
||||
let attrs = raw.0.attributes_raw().trim_ascii();
|
||||
let attrs = raw.element.attributes_raw().trim_ascii();
|
||||
ep.properties.push(ExpandPropertyItem {
|
||||
property: DavProperty::DeadProperty(DeadElementTag {
|
||||
name,
|
||||
|
|
|
@ -66,10 +66,8 @@ impl Namespace {
|
|||
Namespace::CalendarServer => "C",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for Namespace {
|
||||
fn as_ref(&self) -> &str {
|
||||
pub fn namespace(&self) -> &'static str {
|
||||
match self {
|
||||
Namespace::Dav => "DAV:",
|
||||
Namespace::CalDav => "urn:ietf:params:xml:ns:caldav",
|
||||
|
@ -79,6 +77,12 @@ impl AsRef<str> for Namespace {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for Namespace {
|
||||
fn as_ref(&self) -> &str {
|
||||
self.namespace()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(test, derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum Element {
|
||||
|
|
|
@ -32,7 +32,7 @@ pub async fn test(test: &WebDavTest) {
|
|||
.with_status(StatusCode::CREATED);
|
||||
let lock_token = response
|
||||
.with_value(
|
||||
"D:prop.D:lockdiscovery.D:activelock.D:owner.D:href",
|
||||
"D:prop.D:lockdiscovery.D:activelock.D:owner.href",
|
||||
"super-owner",
|
||||
)
|
||||
.with_value("D:prop.D:lockdiscovery.D:activelock.D:depth", "infinity")
|
||||
|
@ -55,7 +55,7 @@ pub async fn test(test: &WebDavTest) {
|
|||
.await
|
||||
.with_status(StatusCode::OK)
|
||||
.with_value(
|
||||
"D:prop.D:lockdiscovery.D:activelock.D:owner.D:href",
|
||||
"D:prop.D:lockdiscovery.D:activelock.D:owner.href",
|
||||
"super-owner",
|
||||
)
|
||||
.with_any_value(
|
||||
|
@ -117,7 +117,7 @@ pub async fn test(test: &WebDavTest) {
|
|||
props
|
||||
.get(DavProperty::WebDav(WebDavProperty::LockDiscovery))
|
||||
.with_some_values([
|
||||
"D:activelock.D:owner.D:href:super-owner",
|
||||
"D:activelock.D:owner.href:super-owner",
|
||||
"D:activelock.D:depth:infinity",
|
||||
format!("D:activelock.D:locktoken.D:href:{lock_token}").as_str(),
|
||||
format!("D:activelock.D:lockroot.D:href:{path}").as_str(),
|
||||
|
|
|
@ -501,8 +501,8 @@ pub async fn test(test: &WebDavTest) {
|
|||
),
|
||||
(
|
||||
DavProperty::DeadProperty(DeadElementTag::new(
|
||||
"C:my-dead-element".to_string(),
|
||||
None,
|
||||
"my-dead-element".to_string(),
|
||||
Some("xmlns=\"http://example.com/ns/\"".to_string()),
|
||||
)),
|
||||
"this is a dead but exciting element",
|
||||
),
|
||||
|
@ -514,8 +514,8 @@ pub async fn test(test: &WebDavTest) {
|
|||
let mut props = vec![
|
||||
(
|
||||
DavProperty::DeadProperty(DeadElementTag::new(
|
||||
"C:my-dead-element".to_string(),
|
||||
None,
|
||||
"my-dead-element".to_string(),
|
||||
Some("xmlns=\"http://example.com/ns/\"".to_string()),
|
||||
)),
|
||||
"",
|
||||
),
|
||||
|
@ -604,8 +604,8 @@ pub async fn test(test: &WebDavTest) {
|
|||
let mut chunky_props = vec![
|
||||
DavProperty::WebDav(WebDavProperty::DisplayName),
|
||||
DavProperty::DeadProperty(DeadElementTag::new(
|
||||
"C:my-chunky-dead-element".to_string(),
|
||||
None,
|
||||
"my-chunky-dead-element".to_string(),
|
||||
Some("xmlns=\"http://example.com/ns/\"".to_string()),
|
||||
)),
|
||||
];
|
||||
if !is_file {
|
||||
|
|
Loading…
Add table
Reference in a new issue