Latest Many Hells Of Webdav: Writing A Client/server In Go 2026 - Guide
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.
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.
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:
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!
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:
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.
Source: HackerNews