Many hells of WebDAV

2026-01-0715:5017096candid.dev

Standards are great, until they aren't

Standards are great, until they aren’t

Implementing a WebDAV/CalDAV client and server should be easy! It’s a well documented spec, standardized in the early 00s, and somewhat widely supported. At least, that’s the naive assumption we started from when creating one for Homechart.

Existing Go Implementations

Now before you mention NIH syndrome, yes, we looked at the existing Go implementation, go-webdav. This library was lacking some key features we needed, like server-side collection synchronization, and the interfaces didn’t really align with our data model. This is also going to be a key feature of our product, so we should have some level of ownership for what gets implemented.

To start creating our client and server, we should read the RFCs, right? Well, where do you start?

How about the original, RFC 2518? Ah, looks like it was somewhat superseded by RFC 4918, but we’re not going to tell you which parts! How about those extension RFCs? There’s only 7 of them…

Reading through the RFCs, all that our implementation cares about is CRUD for Calendar events. After spending almost a month trying to implement the full RFC spec, we threw in the towel, there’s just to much legacy cruft that we didn’t need.

Reverse Engineering

With a decent understanding of the RFC in hand, we instead looked into reverse engineering existing clients and servers by inspecting their requests and responses. This process was MUCH faster, and we quickly had the API mapped out and what kind of requests/responses we needed to support.

We started by identifying the clients/servers we wanted to support:

Clients:

  • Apple Calendar
  • DavX
  • Thunderbird

Servers:

  • Apple iCloud
  • Google Calendar
  • Radicale

And then ran HTTP proxies or Wireshark to capture the HTTP requests. Because WebDAV is so obtuse, you not only need to inspect the HTTP body, but also the headers!

XML in Go

As an aside, we spent quite a bit of time trying to make XML work well in Go. The default Go XML library is truly terrible, and we decided to create a wrapper around it for managing XML nodes similar to how JavaScript manages HTML nodes:

var davDisplayName = xmel.Element{
 Name: "displayname",
 Space: davNS,
}

davDisplayName.SetValue("name")
n, err := davResponse.Find(davCollectionType)
davOwner = davOwner.AddChild(davHref.SetValue("http://example.com"))

With WebDAV having such an…“unstructured” schema to a lot of the requests/responses, this library was key in helping us marshal/unmarshal things without writing a bunch of “best case” structs.

Standards are Just Suggestions

When we finally had our MVP built out, we put it to the test: validating our client and server against the existing implementations! For the most part, it worked as expected, but as always, things drift from the RFC.

Apple and Google, for instance, don’t implement half of the RFCs, and basically provide a MVP for other clients to use. They don’t really document what they support/don’t support, as WebDAV is supposed to do it via HTTP responses advertising capabilities, but both seem to provide generic responses advertising capabilities they don’t have a lot of the time.

The clients were another story. CalDAV clients are all over the place with what they support and how they will request it. Most clients should prefer to support sync-collection as it’s very efficient, but Apple Calendar doesn’t, and uses ctags and etags instead.

As a little fish in a big pond, it’s frustrating dealing with situations where big providers can skirt around some standards or add quirks for their implementations, but I’m required to follow them to the T because I don’t have their inertia. I can’t file a bug, or a lawsuit, against them claiming nonconformance, they’ll tell me to get bent. And you see this in other open source libraries too, where they’re littered with comments about workarounds for Google’s specific implementation or whatever.

I wouldn’t recommend anyone who values their sanity to pursue creating a WebDAV/CalDAV library.


Read the original article

Comments

  • By eddieroger 2026-01-0716:212 reply

    I've been playing with a toy app that dabbles in the Cal/CardDAV space, and it blows my mind that for all the power latest generation languages have, the thing I keep coming back to is PHP-based Sabre/DAV. That's not to say PHP isn't modern now, but instead a reflection of my surprise that there doesn't appear to be any other library out there that does as good or nearly as good a job at DAV as that one, and that one is pretty darn old.

    On a different point, I don't think the author's point about having to "also" inspect the headers is a fair critique of DAV - HTTP headers are to indicate a certain portion of the request/response, and the body a different one. I wish it was simpler, but I think it's an acceptable round peg in a round hole use of the tools.

    • By candiddevmike 2026-01-0716:40

      Author here, I'd be more inclined to agree about the headers if they were consistent. For instance, why is only Allow and DAV part of the header (and all of their bizarre options) and not things like supported report set or privileges? It would be better to have all of this in the body somehow, especially Depth.

    • By inferiorhuman 2026-01-0717:341 reply

      I wrote a standalone CardDAV server ages ago and the biggest frustration for me was just how buggy the clients were. At some point I stopped self-hosting and moved on.

      • By lifestyleguru 2026-01-0821:321 reply

        I've been self-hosting one of the CalDAV+CardDAV servers based on Sabre for few years now and that thing is solid. Multiple clients - iPhone, Android, Thunderbird. Using it with very few users though.

        • By inferiorhuman 2026-01-095:31

          This would've been years ago. Both MacOS and iOS were insanely buggy (Tiger era). I think the lack of momentum is due to the fact that CardDAV is pretty darn simple, and CalDAV is… idk. Complex yet mature?

  • By 112233 2026-01-0717:077 reply

    Mounting WebDAV -- if you are in a situation, where you have to do it (e.g. own^W^W^Wnextcloud) is such an adventure. Everything - mac, win, linux - supports WebDAV. You mount and it works! Then you notice HOW it works: files are downloaded in full before program can access them, some operations are super slow, some fail or time out, plaintext credentials in mysterious places...

    I heard DeltaV is very advanced, and Subversion supported it. I'm afraid to ask.

    • By hurflmurfl 2026-01-0719:481 reply

      I'm using the nextcloud app on my android, and for my Linux systems I mount WebDAV using rclone, with VFS cache mode set to FULL. This way I can: 1. Have the file structure etc synced to local without downloading the files 2. Have it fetch files automatically when I try to read them. Also supports range requests, so if I want to play a video, it sort of streams it, no need to wait for download. 3. If a file has been accessed locally, it's going to be cached for a while, so even if I'm offline, I can still access the cached version without having to verify that it's the latest. If I'm online, then it will verify if it's the latest version.

      Overall, this has worked great for me, but it did take me a while before I set it up correctly. Now I have a cache of files I use, and the rest of the stuff that I just keep there for backup or hogging purposes doesn't take disk space and stays in the cloud until I sync it.

      • By sureglymop 2026-01-0722:361 reply

        Sine you are mounting and not syncing the files, what happens when you edit a file offline? And what if on another offline device the file is also edited?

        • By hurflmurfl 2026-01-087:56

          Fair question. Conflicts happen, which I'm fine with.

          Realistically speaking, most files I have in my cloud are read-only. The most common file that I read-write on multiple devices is my keepass file, which supports conflict resolution (by merging changes) in clients.

          Also used to happen when I tried editing some markdown notes using obsidian on PC, and then using text editor (or maybe obsidian again?) on android, but I eventually sort of gave up on that use-case. Editing my notes from my phone is sort of inconvenient anyway, so I mostly just create new short notes that I can later edit into some larger note, but honestly can't remember the last time this happened.

          But yes, if not careful, you could run into your laptop overwriting the file when it comes online. In my case, it doesn't really happen, and when it does, Nextcloud will have the "overwritten version" saved, so I can always check what was overwritten and manually merge the changes.

          P.S. If anyone wants to set this up, here's my nixos config for the service, feel free to comment on it:

            # don't forget to run `rclone config` beforehand
            # to create the "nextcloud:" remote
            # some day I may do this declaratively, but not today
            systemd.services.rclone-nextcloud-mount = {
              # Ensure the service starts after the network is up
              wantedBy = [ "multi-user.target" ];
              after = [ "network-online.target" ];
              requires = [ "network-online.target" ];
          
              # Service configuration
              serviceConfig = let
                ncDir = "/home/username/nextcloud";
                mountOptions = "--vfs-cache-mode full --dir-cache-time 1w --vfs-cache-max-age 1w";
              in {
                Type = "simple";
                ExecStartPre = "/run/current-system/sw/bin/mkdir -p ${ncDir}"; # Creates folder if didn't exist
                ExecStart = "${pkgs.rclone}/bin/rclone mount ${mountOptions} nextcloud: ${ncDir}"; # Mounts
                ExecStop = "/run/current-system/sw/bin/fusermount -u ${ncDir}"; # Dismounts
                Restart = "on-failure";
                RestartSec = "10s";
                User = "username";
                Group = "users";
                Environment = [ "PATH=/run/wrappers/bin/:$PATH" ];
              };
            };

    • By blacklion 2026-01-0723:031 reply

      Windows officialy removed support for WebDAV. It still works, but nothing is guaranteed. It has stupid limitation on file size of 10MB, it can be lifted to 2GB (max signed 32 bit number) in Registry, but it is still not very much in modern world (I wanted to share my medial library via WebDAV and failed due to this limitation). It lose credentials on regular basis, errors are too vague («Wrong credentials» means both mistyped password AND expired server certificate), etc.

    • By Fnoord 2026-01-0720:461 reply

      > own^W^W^Wnextcloud

      own^H^H^Hnextcloud

      or

      own^Wnextcloud

      You might wanna look into OpenCloud (formerly known as nextcloud-go) [1]. I still use Nextcloud for the uploading of files and the calendar (though I may switch the latter), but I now sync the dir with Immich. Performance-wise a relief. I also swapped Airsonic Advanced (Java) with Navidrome (Go). Same story.

      [1] https://github.com/opencloud-eu/opencloud

      • By solarkraft 2026-01-0818:531 reply

        > but I now sync the dir with Immich

        Do you use this for anything other than photos and videos?

        • By Fnoord 2026-01-094:29

          Good point, I have to migrate that away and clean it up, but the main user is my wife, not me. I might completely get rid of Nextcloud. I mean, the name is tarnished for my wife.

    • By 8fingerlouie 2026-01-0912:49

      WebDAV is like the 12V plug in cars.

      Its certainly not the optimal design, but it exists in pretty much all cars, so we use it because it's there, and because of it's universal presence, its also hard to replace.

      The sad part is, in a world that is increasingly mobile first, and computing devices move in and out of network coverage, HTTP based protocols actually handle frequent disconnects/reconnects much better than something like SMB.

      For my personal backup needs, running from my phone, WebDAV is king. S3 would probably be better, protocol wise, but i can't have that in a simple "wrapper" that simply exposes existing files, and WebDAV works perfectly fine for LAN anyway.

    • By n3storm 2026-01-0717:132 reply

      Subversion works ok over webdav, it has done it for decades.

      Mounting a directory through nfs, smb or ssh and files are downloaded in full before program access them. What you mean? Listing a directory or accessing file properties, like size for example do not need full download.

      • By 112233 2026-01-0717:402 reply

        I am confused, what do you mean? What OS forces you to download whole file over NFS or SMB before serving read()? Even SFTP does support reading and writing at an offset.

        • By n3storm 2026-01-0718:223 reply

          If I open a nfs doc with, let's say Libreoffice, will I not download whole file?

          On a second thought, I think you are looking at webdav as sysadmins not as developers. Webdav was designed for document authoring, and you cannot author a document, version it, merge other authors changes, track changes without fully controlling resources. Conceptually is much like git needs a local copy.

          I can't imagine how to have an editor editing a file and file is changed at any offset at any time by any unknown agent whitouth any type of orchestration.

          • By rkeene2 2026-01-0719:18

            If you open a file with LibreOffice will read the whole thing regardless of whether or not the file is on NFS or not.

            The parent comment was stating that if you use the open(2) system call on a WebDAV mounted filesystem, which doesn't perform any read operation, the entire file will be downloaded locally before that system call completes. This is not true for NFS which has more granular access patterns using the READ operation (e.g., READ3) and file locking operations.

            It may be the case that you're using an application that isn't LibreOffice on files that aren't as small as documents -- for example if you wanted to watch a video via a remote filesystem. If that filesystem is WebDAV (davfs2) then before the first piece of metadata can be displayed the entire file would be downloaded locally, versus if it was NFS each 4KiB (or whatever your block size is) chunk would be fetched independently.

          • By theamk 2026-01-0817:11

            Libreoffice will likely download the whole file.

            But many others clients won't. In particular, any video player will _not_ download entire file before accessing it. And for images, many viewers start showing image before whole thing is downloaded. And to look at zip files, you don't need the whole thing - just index at the end. And for music, you stream data...

            Requiring that file is "downloaded in full before program access them" is a pretty bad degradation in a lot of cases. I've used smb and nfs and sshfs and they all let you read any range of file, and start giving the data immediately, even before the full download.

          • By wbl 2026-01-0718:56

            NFS infamously proxies reads and writes. Obviously there is some caching but that just makes the behavior funner.

        • By shellac 2026-01-0718:132 reply

          Are you saying WebDAV doesn't support range requests?

          • By 112233 2026-01-0719:38

            That's the beauty of working with WebDAV, also captured vividly in the above article -- any particular server/client combination feels no obligation to try and act like some "standards" prescribe, or make use of facilities available.

            I might be wrong, but when I last mounted webdav from windows, it did the same dumb thing too.

          • By blacklion 2026-01-0723:04

            WebDAV as standard? Supports. This particular combination of client and server? Who knows, good luck.

      • By goodthink 2026-01-083:21

        > Subversion works ok over webdav, it has done it for decades.

        Thank you!!!!

    • By heavyset_go 2026-01-082:582 reply

      Regarding Linux, WebDAV has been partially working/broken in Dolphin/kio since Plasma 5 on KDE. I've found the davfs2 FUSE module to be more reliable.

      • By 112233 2026-01-0819:202 reply

        Sibling comment mentioned rclone, which is enabling piece of software and much better at webdaw than davfs2

        • By esperent 2026-01-098:22

          As it happens, I've been deep in the with rclone, webdav, and Nextcloud over the last few days.

          It works. It's slow when synching a ton of small files but besides that I haven't run into any unexpected problems.

          If I did it again I'd probably use the Nextcloud client in API mode. But this was originally supposed to be a small project... Oh well.

        • By Avamander 2026-01-0919:40

          Rclone works but is still not very good, either it doesn't allow a lot of the things you'd expect from a filesystem or it'll just consume tremendous amount of disk space while it slowly transfers the files to the remote host (even on a really fast link).

      • By QuercusMax 2026-01-085:451 reply

        I just imagined implementing webdav as a kernel module and I think I just broke my brain

    • By jjkaczor 2026-01-0717:43

      Actually - I believe - within Windows 11 - the "WebClient" service is now deprecated (which is what - IIRC, actually implements the WebDAV client protocol so that it works with Windows File Explorer, drive mappings, etc.)...

      Played around with WebDAV alot... a long time ago... (Exchange Webstore/Webstorage System, STS/SharePoint early editions)...

  • By imclaren 2026-01-0723:272 reply

    I built a go caldav server and client for my task management app (http://calmtasks.com) and had a similar experience, which surprised me. Go generally has at least one good, working, and well documented implementation for all standard protocols.

    Apple calendar supports caldav but in a way not specified in the spec. I basically had to send requests and responses to figure out how it works. I would be willing to open source my server and client (alot of which was built using/on top of existing libraries) if there is interest.

    • By raybb 2026-01-082:14

      Why did you make a native app instead of PWA? Because of push notifications or just ease of development?

      Also, would be nice to add some screenshots of the web UI.

      Looks like a nice little app!

    • By sdoering 2026-01-0723:41

      I‘d be interested. A caldav server is still on my list.

HackerNews