Description
As came up several times, the code keeps getting more and more complicated due to the fact that we support different path layouts (as defined below). The latest example for this is #99. While that PR does a lot of the work already, the complexity of adding features (such as multiple address books might) will always be much higher when accounting for support for all use cases.
I figured it might be wise to take a step back and reiterate how we got here, what problems we are actually trying to solve, and if there is maybe different approach altogether that could ease the pain here.
Let's start with some definitions: WebDAV/CardDAV/CalDAV define a set of paths that serve certain special purposes. We need to consider the following:
- User principal URL - defined in RFC 5397, identifies a user, actually an extension, but required by CardDAV/CalDAV. Also indispensable for discovery purposes, so we need this. Its relation to other paths is not specified, so it could be anything really. However, many implementations make it the root of all collections that this user owns, as such a root has to exist anyway if you want to support accessing other users' resources.
- Calendar/Address book home set - defined by CalDAV and CardDAV respectively, identifies a collection that contains all calendar/address book collections. Also used for discovery, see e.g. RFC 4791 section 8.4
- Calendar/Address book URL - identifies a calendar or adress book, essentially a regular WebDAV collection which contains either events or contacts and provides some additional CalDAV/CardDAV-specific attributes. At the moment,
go-webdav
only supports a single calendar/address book. This URL has a relation to the calendar/address book home set: it should be underneath it (or at least equal to it), to be discoverable.
For brevity, I will from now on only focus on CalDAV, but the same applies of course to CardDAV.
Where we started
Initially, the server was designed in such a way that everything was served at the root path (/
). The root path was user principal URL, calendar home set, and calendar URL at the same time. The only other URLs involved were the individual resources (events). This works, but has the following drawbacks:
- Multiple calendars impossible - for multiple calendars, each one must be addressable, requiring URLs like
/calendar1/
etc. - Serving calendars and address book in the same server impossible - for this to work, a user must be able to discover a calendar home set and an address book home set, which must be distinct from each other, e.g.
/contacts/
and/calendars/
. - Addressing other user's (and their calendars) impossible - though this might be far off in terms of being supported, it is worth considering at this point. For this to work, each user has to have a unique user principal URL, such as
/bitfehler/
or/emersion/
.
Current status
Right now, we try to still the support the old case of everything at /
, and everything in between that and the most extreme opposite, where everything has it's own URL, such as /bitfehler/calendars/work/
, where /bitfehler/
is a user pricipal URL, /bitfehler/calendars/
is the calendar home set, and /bitfehler/calendars/work/
is an actual calendar.
Keeping support for everything has caused the regression that #99 tries to fix and leads to all this complicated code where we have to check if something is e.g. also a calendar home set, even though we already know it's a user principal URL.
What now?
Writing all this down, I think my proposal would be to go with the layout that makes everything possible (/bitfehler/calendars/work/
), but only support that. That should make the code much clearer again, while still allowing to add any feature we might want in the future. It would make writing a backend a tiny bit more work, but I think if all you need is one user and one calendar, hard-coding some names the backend is not too much to ask.
If you think this might be a route worth pursuing, I can offer to create a PR for that, to see what the code might look like?