My efforts to put a server-backed calendar on my Android phone entered a new phase. I had Radicale on the server and the CalDAV adapater on the phone but they seemed to talk past each other. My phone would set up a CalDAV account successfully but then tell me "You have no calendar" when I tried to create events.
Radicale documentation says calendars are created automagically based on a URL convention, i.e. simply accessing a non-existent calendar should bring it into existence. I tried it with the Mozilla Lightning client and it worked as advertised. The Android adapter, however, still wouldn't see the new calendar nor its events.
WireShark revealed that a CalDAV client apparently enjoys a lot of freedom when formulating requests. A PROPFIND request from Lightning looked like this:
<D:propfind xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/" xmlns:C="urn:ietf:params:xml:ns:caldav"> <D:prop> <D:resourcetype/> <D:owner/> <D:supported-report-set/> <C:supported-calendar-component-set/> <CS:getctag/> </D:prop> </D:propfind>
whereas the Android adapter was sending
<d:propfind xmlns:d="DAV:" xmlns:c="urn:ietf:params:xml:ns:caldav" xmlns:cs="http://calendarserver.org/ns/" xmlns:ic="http://apple.com/ns/ical/"> <d:prop> <d:displayname /> <d:resourcetype /> <cs:getctag /> </d:prop> </d:propfind>
and it seemed Radicale was not happy with the displayname bit:
... <propstat> <prop> <displayname /> </prop> <status>HTTP/1.1 404 Not Found</status> </propstat> ...
Server-side source code revealed that Radicale returns 404 for properties which it does not recognize (see the final else in the long if-elif chain in _propfind_response() in xmlutils.py). My installed version of Radicale was 0.7. I downloaded the most recent stable release (0.7.1) from the project site and tried that instead. Lo and behold, it finally said
<multistatus xmlns="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:CS="http://calendarserver.org/ns/"> <response> <href>/jh/calendar/</href> <propstat> <prop> <displayname>calendar</displayname> <resourcetype> <C:calendar /> <collection /> </resourcetype> <CS:getctag>"0"</CS:getctag> </prop> <status>HTTP/1.1 200 OK</status> </propstat> </response> </multistatus>
The Calendar app on my phone, however, still insisted I had no calendar. Continued in part 4.