0

I want to provide access to address books and calendars that may have search filters (e.g. tags, user, groups) applied.

They should not be auto-discoverable because there may be billions of combinations but must nonetheless be compatible with common clients (e.g. iOS / OS X, Windows Phones), i.e. it should be possible to add the URL with filters to the client.

One issue seems to be that some clients rely on discovery features rather than the URL you give them, e.g. iOS (you try to add one address book by exact URL and it adds all discoverable ones instead).

Another thing is structuring the optional filters.
What about using paths?
What is considered best practice here?

Arc
  • 11,143
  • 4
  • 52
  • 75

2 Answers2

1

Are the calendars readonly or readwrite? If they are readonly, you can use webcal URLs for calendars (aka 'subscribed calendar' or iCalendar-over-HTTP).

For Cal/CardDAV calendars the Apple devices (and most other DAV clients) configure a full account (using the regular account discovery mechanisms), not just 'a URL'. I don't think there is a way around this.

Assuming you are building a web service which provides a registry/search-engine or which is an aggregator of such calendar or address data, this service could then provide Cal/CardDAV accounts (which implements the discovery).

On your web-service you would then have two options:

  1. proxy (and potentially cache) the remote data
  2. create a 'CalDAV subscribed calendar' (a special WebDAV resource which points to a CalDAV calendar (resource type {http://calendarserver.org/ns/}subscribed)).

For contacts you only have choice 1. And as an extra complication you might want to expose the stored queries as vCard groups instead of CardDAV collections. This is because some clients (i.e. some MacOS Contacts apps) only support one CardDAV collection (and only use groups to structure the data).

Sample: Lets say you invented a service called 'Caloogle.com'. The user needs to get some account on that service (could be auto-created, etc). The user adds a CalDAV account to his iOS device (e.g. using a preconfigured profile, so that he doesn't have to enter all the data), which then connects to Caloogle to fetch data into the iOS EventKit database. Now in your Caloogle app (or on the website), you let the user search for calendar data. If the user found a set he likes, he saves that as a calendar into Caloogle, say 'Dividend Release Dates BP, Apple and AlwaysRightInstitute'. iOS will ping the account eventually and pick up the saved calendar. User is amazed and happy.

How you actually implement the web service (proxy or name-to-url map) depends a lot on where your data is coming from ...

Makes sense?

P.S.: Be careful when storing queries in URLs, some HTTP infrastructure components have limits on the length of a URL, and advanced queries can quickly overflow this.

hnh
  • 13,957
  • 6
  • 30
  • 40
  • Ok, thanks, what I suspected... so I guess the only "good" workaround is to expose a _virtual_ DAV server so that filters are encoded in the path and feed them to the server so that it works everywhere. E.g. `http://server/user:john/tags:acme+denver/` would expose an entire virtual sub-server with principals, CardDAV and/or CalDAV. For bookmarked searches / favorites (as in your example), I could expose them under the "default" DAV server `http://server` (using `.well-known`). Calendars and contacts are read/write. – Arc Apr 15 '15 at 13:28
  • I can't follow all what you are saying, but yes, your server side frontend needs to be a CalDAV server to be able to connect to a CalDAV client ;-) With principals and all that. I'm not sure why you are saying that 'http://server/user:john/tags:acme+denver/ would expose an entire virtual sub-server with principals'. That _sounds_ wrong, you definitely wouldn't want to create one CalDAV account per search? – hnh Apr 15 '15 at 13:32
  • What I mean is that I'd use web server URL rewriting to provide a full sabre/dav endpoint with discoverability under multiple URLs, e.g. `http://server/user:john/` would itself be a CalDAV/CardDAV URL, below which you'd find principal information, calendars and address books. – Arc Apr 15 '15 at 13:36
  • Regarding collections: Is it legal to expose the same vCard / vEvent / ... object (with the same UID) in multiple collections, or is it mandatory to give each of them different UIDs? – Arc Apr 15 '15 at 13:43
  • Still can't follow you wrt the URL thing, but that's OK :-) Just make sure that you don't create one account per query, users would hate you :-) – hnh Apr 15 '15 at 14:12
  • Yes, you can put the same UID in different collections, that is legal in Cal/CardDAV. Though I guess it's worth noting that some servers forbid this (at different levels, e.g. iCloud allows multiple instances for non-scheduled resources, but requires server uniqueness for scheduled ones), but that shouldn't affect you. – hnh Apr 15 '15 at 14:15
0

Like hnh said in his answer, smart clients will try to discover the DAV services you are offering when you configure CardDAV or CalDAV from a URL rather than just use that very URL, so there seems to be no clean way to provide multiple virtual collections filtered by tags, users, groups etc.

The simplest solution that could work is to provide one virtual DAV server for each filter URL, with full service discovery within the constraints of that filter URL.

Virtual endpoints are provided with the help of URL rewriting, a feature found in common web servers, and will all point to the same DAV server code base and supply it with the filter criteria.

If for example, you want CalDAV / CardDAV collections of items that have the tags PR and Spain, you could expose them under https://dav.server/tag:PR/tag:Spain/, while items with a tag China can be exposed under https://dav.server/tag:China/.

Note that each URL provides full DAV functionality with discoverability. As discovery is relative to the respective roots https://dav.server/tag:PR/tag:Spain/ and https://dav.server/tag:China/, there will be no interference.

Additionally, you could expose a simple URL https://server for a well-defined set of CalDAV / CardDAV collections, e.g. a default calendar / address book or some "bookmarked" collections defined by the user in some way, e.g. "PR Spain".

The simple URL would then provide these HTTP redirects, as per RFC 5785:

https://server/.well-known/caldav    =>    https://dav.server/default
https://server/.well-known/carddav   =>    https://dav.server/default

iOS clients and those supporting well-known URIs could then be configured by just setting the host to server and supplying login credentials.
They would then try to connect via HTTPS, check for the well-known URIs and thus discover the DAV endpoint at https://dav.server/default.

Those without well-known URI support nor discovery would require the exact URL, e.g. https://dav.server/default/calendars/jane/main or https://dav.server/tag:China/calendars/jane/main.

Community
  • 1
  • 1
Arc
  • 11,143
  • 4
  • 52
  • 75