CalDAV protocol synchronization and behavior of different clients

Refresh

March 2019

Views

728 time

1

i am currently trying to implement a „simple“ readonly CALDAV-interface for a system. But the synchronization protocol and the CALDAV-clients give me some headaches.

The main test client i use is the macos-calendar (sierra). The initial handshake (DAV principle, calendar lookup) and inital load of data is working. I get some REPORT:calendar-query requests. The issue is the incremental sync after initial load. There are two approaches:

  • Via WebSync-extension (REPORT:sync-collection and sync-token prop) my main issue here is that provisioning the sync-token from the server is not trivial in my system. Changes and New data is not an issue, but physical deletion (not yet logged in the user context) and changes in the scope of group- and/or role-assignments. Maybe i need to consider to invalidate in complex cases the sync-token and let the client resetup without sync-collection? A nasty workaround could be to retain the calendar item IDs send to the client and check on each request for their existence and responds if necessary with a not found per deleted/out of scope calendar item. But this would mean i store client-state on the server which doesnt sound right and might be error prone.

  • Via basic protocal synchronization (respond to REPORT:calendar-query and propfind (depth=1) requests no webdav-sync active) this is also working already in principle for new and changed data. But the macos-calendar doesnt remove items which are not part the collection response (propfind with depth=1). According to the protocol the client should determine the deleted items and remove them, but it doesnt do it in my case. Any ideas here? For my system currently it would be ideal to use this approach though the performance might be not the ideal one.

With ios-Calendar i face another issue:

  • Initial handshake is somehow working as the requests in the network are coming and are answered.

  • But than a MKCALENDAR request is coming (instead of a calendar-query or propfind for items) which answer with 403 as i also dont provide it in the Allow-header of the options response. the request looks like this:

MKCALENDAR /services/cal/_userid/220EDB4A-F00C-41C9-B78F-10781BBA77E4/ HTTP/1.1 Host: 127.0.0.1:8003 Content-Type: text/xml User-Agent: iOS/10.0.1 (14A403) dataaccessd/1.0 <?xml version="1.0" encoding="UTF-8"?> <B:mkcalendar xmlns:B="urn:ietf:params:xml:ns:caldav"> <A:set xmlns:A="DAV:"> <A:prop> <B:calendar-free-busy-set> <NO/> </B:calendar-free-busy-set> <D:calendar-order xmlns:D="http://apple.com/ns/ical/">1</D:calendar-order> <A:displayname>Kalender</A:displayname> <B:calendar-timezone>BEGIN:VCALENDAR ...deleted.... </B:calendar-timezone> <B:supported-calendar-component-set> <B:comp name="VEVENT"/> </B:supported-calendar-component-set> </A:prop> </A:set> </B:mkcalendar>

  • Nothing is happening afterwards.

  • Anyone experiencing this as well? Why ios-calendar tries to do a mkcalendar though i have a calendar-collection as resource-type?

With Thunderbird Lightning:

  • Initial handshake with the calendar-collection is working

  • A propfind-and multiget request for items is answered with iCal-Items.

  • But they are not displayed and in the error log i receive:

  • Warnung: CalDAV: Get failed: CalDAV: Error: got status 200 fetching calendar data for Debug Proxy, null

  • (text in german: error code: 0x80004005) Warnung: Fehler beim Lesen von Daten für Kalender: Debug Proxy. Allerdings ist dieser Fehler wahrscheinlich vernachlässigbar, daher versucht das Programm fortzufahren. Fehlercode: 0x80004005. Beschreibung: CalDAV: Error: got status 200 fetching calendar data for Debug Proxy, null

  • (text in german: error code: READ_FAILED) Warnung: Fehler beim Lesen von Daten für Kalender: Debug Proxy. Allerdings ist dieser Fehler wahrscheinlich vernachlässigbar, daher versucht das Programm fortzufahren. Fehlercode: READ_FAILED. Beschreibung:

  • http channel Listener OnDataAvailable contract violation

  • a similiar response is though working in macos-calendar – could it be some encoding issue?

Any hints are highly appreciated!

2 answers

3

This is indeed a pretty broad question. But let me try to address some stuff:

Via WebSync-extension (REPORT:sync-collection and sync-token prop) my main issue here is that provisioning the sync-token from the server is not trivial in my system

Even if it is hard for you, you should really try to come up with something here. Even if this means storing some extra info on the server. Sync-collection is way more efficient. (Idea: Maybe you can at least set a flag when something actually got deleted and only then expire the sync-token?)

Via basic protocal synchronization (respond to REPORT:calendar-query and propfind (depth=1))

Which one, calendar-range-query or PROPFIND? Completely different things ...

this is also working already in principle for new and changed data. But the macos-calendar doesnt remove items which are not part the collection response (propfind with depth=1).

If we are talking about a calendar-range-query, the client cannot proactively delete items since it doesn't know whether they just left the range (vs being deleted).

With PROPFIND it should do this. If you have proof it doesn't, maybe create another question with all the relevant details.

With ios-Calendar i face another issue: ... a MKCALENDAR request is coming ...

This probably means that it can't find the default scheduling calendar, no calendar at all, none with a proper component-type property. Or all the same for todos (Reminders app, same account). What is the payload of the MKCALENDAR? Hard to diagnose w/o details, if you can't figure it out, ask a specific question on this with all the relevant details included (e.g. the XML you send in response to the home query).

Thunderbird Lightning

Can't say much about this, probably depends a lot on the version and what extensions you are using. AFAIK many people use the ScalableOGo Thunderbird extensions to get proper Cal/CardDAV with Thunderbird.

hnh
1

For Thunderbird/Lightning you may want to turn on calendar.debug.log and calendar.debug.log.verbose in the advanced config editor and restart. You can find it in Options > Advanced > General > Config Editor. This will get you more detailed http requests and information about what failed. You can also hook up the remote debugger and look at the network monitor, or set breakpoints in the code.

With Thunderbird/Lightning please note that we are using a mix of previous and current versions of the webdav-sync draft. I can't say much from the error message as is given it is very general, but it does look like there is something unexpected in the results.

Maybe it makes sense to compare the handshake between an existing server (like sabre/dav) and the client, then see where the difference between your communication and theirs is.

Also, you may be interested in the CalDAVTester from Apple, which checks server interoperability. Note however that it does contain various apple specific tests. The folks at CalConnect are working together with Apple to make it more generally usable and to split out the Apple-specific tests. Given your server is read-only, don't expect everything to work, but you can hunt for fixing specific tests.