The RFC that explains the handshake is now available.
If you use iCal/Calendar on Mac OS X or iOS, you might have seen that you don't have to specify the type of server ("Automatic" is the default type). But to work, you need to setup DNS entries so that iCal/Calendar can find the server for the user, and your CalDAV server must support "well-known" URLs. "well-known" is supported by iCal Server (OS X Server 10.7 or 10.8), Calendar Server (the open source version of iCal Server) and Kerio Connect (starting with version 7.2).
For DNS, I found how to do it in this article. In short, you need at least one SRV entry that will tell where your server is located. If your domain is "macti.lan", you need to add the following entry:
Where 8443 is the port on which your CalDAV server is running (8443 is the HTTPS port for iCal Server/Calendar Server, for Kerio Connect by default it's on port 443). server.macti.lan is the DNS name of the host running the CalDAV service.
You will notice that the DNS entry is _caldavs_. If your CalDAV server is running on a non-protected port, or if it's available on both ports, you should add a DNS entry like this:
Notice that the 's' is missing in the DNS entry. If you have both entries, iCal/Calendar will try the secure entry first, and it's not working, it will try the non-secure entry after.
If you have a iCloud account with a @me.com, a SRV entry do exist:
Once the DNS entry is found, the CalDAV client will take the value off the SRV record and do the following:
Do a PROPFIND (WebDAV method) request on https://server.macti.lan:443/.well-known/caldav (or port 80 if the SRV record wasn't specifying https) with the following body:
- If nothing was found on port 443 or port 80, it will do the same request on port 8443 or 8008.
- If nothing was found on port 8443 or 8008, it will then use use the host and port from the SRV record.
The response from /.well-known/caldav might be a redirect (HTTP status code 301 or 302). In fact, that's what iCal Server 10.8 does, it redirect the request to http://server.macti.lan:8008/. So again, iCal will do the same request as before until it gets a 207 status code instead of a redirect. The response will look like this:
The value we need is the value of current-user-principal, which indicates the location of the user's "principals". With this value, iCal will make a OPTIONS request to /principals/__uids__/C0F07FAF-A20A-4A88-A518-D27E5D3074CA/. I don't know why iCal is making the request, but my guess it's doing it so that it can find which CalDAV features are supported by the CalDAV server. That list is available in the response's DAV header:
This is a response from iCal Server 10.8, which supports all CalDAV features and extensions. Doing the same request to a Google Calendar server will return a lot less features/extensions.
Following the OPTIONS request, iCal will make a PROPFIND request on the same URL as the OPTIONS request, with the following body:
The value that we need back from this request is the value of the calendar-home-set property. This property is the URL to calendar collections. So iCal can finally found where the calendars are, and it will do a PROPFIND request to the URL found with the value of calendar-home-set. The body of that PROPFIND request is quite large so I'm not going to past it here, but in short, that PROPFIND will find the request properties for each sub-collections in the main calendar collection. For example, if the main collection is located at:
The "calendar" collection will be located at:
And the "tasks" collection:
So, for each sub-collection, iCal will do the following:
- A PROPFIND request to find the value of the checksum-versions property;
- A PROPFIND request to find the value of the getctag and sync-token properties;
- A PROPFIND request to find the value of the getcontenttype and getetag properties;