mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 22:52:22 +00:00
Make sure collections have trailing slashes (py-caldav is very pedantic about that)
This commit is contained in:
@@ -50,6 +50,7 @@ impl<C: CalendarStore, S: SubscriptionStore> ResourceService for CalendarResourc
|
|||||||
type PrincipalUri = CalDavPrincipalUri;
|
type PrincipalUri = CalDavPrincipalUri;
|
||||||
|
|
||||||
const DAV_HEADER: &str = "1, 3, access-control, calendar-access";
|
const DAV_HEADER: &str = "1, 3, access-control, calendar-access";
|
||||||
|
const IS_COLLECTION: bool = true;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ impl<C: CalendarStore> ResourceService for CalendarObjectResourceService<C> {
|
|||||||
type PrincipalUri = CalDavPrincipalUri;
|
type PrincipalUri = CalDavPrincipalUri;
|
||||||
|
|
||||||
const DAV_HEADER: &str = "1, 3, access-control, calendar-access";
|
const DAV_HEADER: &str = "1, 3, access-control, calendar-access";
|
||||||
|
const IS_COLLECTION: bool = false;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ impl<C: CalendarStore, S: SubscriptionStore> ResourceService for CalendarSetReso
|
|||||||
type PrincipalUri = CalDavPrincipalUri;
|
type PrincipalUri = CalDavPrincipalUri;
|
||||||
|
|
||||||
const DAV_HEADER: &str = "1, 3, access-control, extended-mkcol, calendar-access";
|
const DAV_HEADER: &str = "1, 3, access-control, extended-mkcol, calendar-access";
|
||||||
|
const IS_COLLECTION: bool = true;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub struct CalDavPrincipalUri(&'static str);
|
|||||||
|
|
||||||
impl PrincipalUri for CalDavPrincipalUri {
|
impl PrincipalUri for CalDavPrincipalUri {
|
||||||
fn principal_uri(&self, principal: &str) -> String {
|
fn principal_uri(&self, principal: &str) -> String {
|
||||||
format!("{}/principal/{}", self.0, principal)
|
format!("{}/principal/{}/", self.0, principal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ impl Resource for PrincipalResource {
|
|||||||
.map(|principal| puri.principal_uri(principal))
|
.map(|principal| puri.principal_uri(principal))
|
||||||
.flat_map(|principal_url| {
|
.flat_map(|principal_url| {
|
||||||
self.home_set.iter().map(move |&home_name| {
|
self.home_set.iter().map(move |&home_name| {
|
||||||
HrefElement::new(format!("{}/{}", &principal_url, home_name))
|
HrefElement::new(format!("{}{}/", &principal_url, home_name))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ impl<AP: AuthenticationProvider, S: SubscriptionStore, CS: CalendarStore, BS: Ca
|
|||||||
type PrincipalUri = CalDavPrincipalUri;
|
type PrincipalUri = CalDavPrincipalUri;
|
||||||
|
|
||||||
const DAV_HEADER: &str = "1, 3, access-control, calendar-access";
|
const DAV_HEADER: &str = "1, 3, access-control, calendar-access";
|
||||||
|
const IS_COLLECTION: bool = true;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ impl<AS: AddressbookStore> ResourceService for AddressObjectResourceService<AS>
|
|||||||
type PrincipalUri = CardDavPrincipalUri;
|
type PrincipalUri = CardDavPrincipalUri;
|
||||||
|
|
||||||
const DAV_HEADER: &str = "1, 3, access-control, addressbook";
|
const DAV_HEADER: &str = "1, 3, access-control, addressbook";
|
||||||
|
const IS_COLLECTION: bool = false;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ impl<AS: AddressbookStore, S: SubscriptionStore> ResourceService
|
|||||||
type PrincipalUri = CardDavPrincipalUri;
|
type PrincipalUri = CardDavPrincipalUri;
|
||||||
|
|
||||||
const DAV_HEADER: &str = "1, 3, access-control, addressbook";
|
const DAV_HEADER: &str = "1, 3, access-control, addressbook";
|
||||||
|
const IS_COLLECTION: bool = true;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ pub struct CardDavPrincipalUri(&'static str);
|
|||||||
|
|
||||||
impl PrincipalUri for CardDavPrincipalUri {
|
impl PrincipalUri for CardDavPrincipalUri {
|
||||||
fn principal_uri(&self, principal: &str) -> String {
|
fn principal_uri(&self, principal: &str) -> String {
|
||||||
format!("{}/principal/{}", self.0, principal)
|
format!("{}/principal/{}/", self.0, principal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ impl<A: AddressbookStore, AP: AuthenticationProvider, S: SubscriptionStore> Reso
|
|||||||
type PrincipalUri = CardDavPrincipalUri;
|
type PrincipalUri = CardDavPrincipalUri;
|
||||||
|
|
||||||
const DAV_HEADER: &str = "1, 3, access-control, addressbook";
|
const DAV_HEADER: &str = "1, 3, access-control, addressbook";
|
||||||
|
const IS_COLLECTION: bool = true;
|
||||||
|
|
||||||
async fn get_resource(
|
async fn get_resource(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -76,8 +76,13 @@ pub(crate) async fn route_propfind<R: ResourceService>(
|
|||||||
let mut member_responses = Vec::new();
|
let mut member_responses = Vec::new();
|
||||||
if depth != &Depth::Zero {
|
if depth != &Depth::Zero {
|
||||||
for member in resource_service.get_members(path_components).await? {
|
for member in resource_service.get_members(path_components).await? {
|
||||||
|
// Collections should have a trailing slash
|
||||||
|
let mut name = member.get_name();
|
||||||
|
if R::IS_COLLECTION {
|
||||||
|
name.push('/')
|
||||||
|
}
|
||||||
member_responses.push(member.propfind_typed(
|
member_responses.push(member.propfind_typed(
|
||||||
&format!("{}/{}", path.trim_end_matches('/'), member.get_name()),
|
&format!("{}/{}", path.trim_end_matches('/'), name),
|
||||||
&propfind_member.prop,
|
&propfind_member.prop,
|
||||||
puri,
|
puri,
|
||||||
principal,
|
principal,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ pub trait ResourceService: Clone + Sized + Send + Sync + AxumMethods + 'static {
|
|||||||
type PrincipalUri: PrincipalUri;
|
type PrincipalUri: PrincipalUri;
|
||||||
|
|
||||||
const DAV_HEADER: &'static str;
|
const DAV_HEADER: &'static str;
|
||||||
|
const IS_COLLECTION: bool;
|
||||||
|
|
||||||
async fn get_members(
|
async fn get_members(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ where
|
|||||||
type PrincipalUri = PURI;
|
type PrincipalUri = PURI;
|
||||||
|
|
||||||
const DAV_HEADER: &str = "1, 3, access-control";
|
const DAV_HEADER: &str = "1, 3, access-control";
|
||||||
|
const IS_COLLECTION: bool = true;
|
||||||
|
|
||||||
async fn get_resource(&self, _: &()) -> Result<Self::Resource, Self::Error> {
|
async fn get_resource(&self, _: &()) -> Result<Self::Resource, Self::Error> {
|
||||||
Ok(RootResource::<PRS::Resource, P>::default())
|
Ok(RootResource::<PRS::Resource, P>::default())
|
||||||
|
|||||||
Reference in New Issue
Block a user