Feature request: full WebDAV / CalDAV / CardDAV compatibility in official ICP HTTP gateways (PROPFIND, REPORT, MKCOL, LOCK, custom headers, auth, client interoperability)

Hello everyone,

I would like to raise what I believe is an important feature request for the Internet Computer ecosystem: enabling real, production-grade support for WebDAV / CalDAV / CardDAV style HTTP traffic in the official ICP HTTP gateways, so that standard clients such as Thunderbird, Apple Calendar / Contacts, iPhone, Android DAV clients, and other enterprise DAV tools can talk directly to canisters without requiring a centralized compatibility proxy.

At the moment, the ICP HTTP model is already very close to what is needed on paper:

  • the HTTP Gateway Protocol forwards the request to the canister,

  • the request object includes method, url, headers, and body,

  • the response object supports arbitrary status_code, headers, body,

  • and http_request_update exists for state-changing requests.

This is a strong foundation. However, in practice, the official gateways still do not provide the full pass-through behavior and interoperability needed for DAV clients.

Why this matters

Today, one can build HTTP APIs and websites on ICP, but it is still not realistically possible to build a native, standards-compatible WebDAV / CalDAV / CardDAV server that works directly with mainstream clients over the official gateways.

That is a significant limitation.

Supporting these protocols would unlock an entirely new class of applications on ICP:

  • decentralized contacts servers,

  • decentralized calendar servers,

  • decentralized document storage and sync,

  • enterprise collaboration backends,

  • sovereign address books,

  • fully onchain team calendars,

  • decentralized file spaces with open client compatibility,

  • self-hosted or DAO-governed productivity infrastructure,

  • and ICP-native alternatives to cloud silos like Google Contacts, Google Calendar, iCloud Contacts/Calendar, Nextcloud DAV, and similar stacks.

In other words: this is not only about “one more HTTP method”. It is about enabling open, interoperable, standard client access to onchain data and services.

Why ICP is uniquely suited for this

ICP is especially interesting for this use case because it can offer something that traditional cloud DAV servers cannot offer:

1. Full onchain backend with no mandatory centralized middleware

ICP can already host backend logic and data directly inside canisters. If DAV compatibility were completed at the gateway layer, we could have a true end-to-end ICP-native CalDAV/CardDAV/WebDAV backend without having to insert a conventional reverse proxy or centralized translation server in front.

That would be strategically important because it removes a major dependency on traditional infrastructure and preserves the architectural purity of a fully decentralized stack.

2. User- and DAO-controlled data/services

The value proposition of ICP is that applications and data can be governed in a decentralized way, instead of being locked behind a single operator. This is particularly compelling for contacts, calendars, and collaborative data, because these are highly sensitive and deeply integrated into people’s digital lives.

A fully ICP-native DAV backend could make it possible to build:

  • user-owned personal information managers,

  • organization-owned collaborative infrastructure,

  • DAO-governed scheduling/contact systems,

  • and long-lived public-interest services where no cloud vendor can unilaterally alter access rules or product direction.

3. Certified responses and integrity guarantees

The HTTP gateway stack on ICP is specifically designed around certified responses and response verification. That means that standard HTTP clients can benefit from a backend whose responses come from canister logic running on ICP rather than from a conventional opaque server stack.

For productivity and identity-related infrastructure, verifiability is not a minor detail. It can become a major differentiator.

4. Open standards instead of app-specific lock-in

CalDAV/CardDAV/WebDAV are valuable precisely because they are open protocols supported by existing clients. Supporting them would allow developers to build on ICP without forcing users to install a special front-end first.

That is powerful for adoption:
people could use existing software they already trust and already run in their organizations.

The current blocker

The protocol definition is already flexible enough to carry what DAV needs. The HTTP Gateway Protocol specification explicitly models the request with:

  • method: text

  • url: text

  • headers: vec HeaderField

  • body: blob

and the canister response with:

  • status_code

  • headers

  • body

  • optional upgrade

  • optional streaming strategy.

Also, the gateway can escalate from http_request to http_request_update when the canister returns upgrade = true.

So on the specification side, this is not fundamentally limited to GET/POST websites. The machinery is generic enough for richer HTTP protocols. The issue appears to be in the practical behavior of official gateways / boundary infrastructure and interoperability assumptions, not in the conceptual design of the canister HTTP interface itself.

Concrete interoperability requirements for DAV support

To make WebDAV / CalDAV / CardDAV truly possible on official ICP gateways, I believe the following should be supported as a first-class goal.

A. Pass through the required HTTP methods

At minimum, the official gateways should reliably pass through DAV-related methods to the canister instead of rejecting them or normalizing them away.

This includes at least:

  • OPTIONS

  • PROPFIND

  • PROPPATCH

  • REPORT

  • MKCOL

  • COPY

  • MOVE

  • LOCK

  • UNLOCK

Depending on the exact DAV profile, also potentially:

  • MKCALENDAR

  • ACL

  • other extension methods used by specific clients or servers.

For CalDAV/CardDAV in particular, PROPFIND and REPORT are core to discovery and synchronization workflows. Without them, standard clients simply cannot interoperate correctly.

B. Method-aware routing to query vs update semantics

Some DAV methods are read-like, some are mutation-like. ICP already has a useful separation between http_request and http_request_update.

It would be ideal if official guidance or gateway behavior clearly supported the following model:

  • safe/read DAV methods can remain query-oriented where appropriate,

  • mutating DAV methods can cleanly upgrade to http_request_update,

  • and this should be documented as an intended use case, not just an edge case.

This is especially important because DAV is not simply REST-style GET/POST JSON; the protocol relies on a richer method surface.

C. Full header pass-through for DAV semantics

DAV clients rely heavily on headers. Interoperability requires that gateways do not strip, rewrite, hardcode, or override headers in a way that breaks protocol semantics.

Headers commonly needed include, depending on the workflow:

  • Depth

  • Destination

  • If

  • Lock-Token

  • Overwrite

  • Brief

  • Prefer

  • Translate

  • Range

  • If-Match

  • If-None-Match

  • ETag

  • Authorization

  • WWW-Authenticate

  • DAV

  • Allow

The key point is broader than any one header: developers need confidence that arbitrary protocol-significant headers can reach the canister and come back from the canister unchanged when appropriate.

D. Correct handling of OPTIONS

There has already been prior forum discussion showing that OPTIONS handling at the gateway layer was historically special-cased, and that gateway-managed behavior could override the canister’s own response. That is a serious issue for protocol compatibility because DAV discovery often begins with OPTIONS and expects meaningful server capability signaling.

A DAV-capable stack needs OPTIONS to be trustworthy and under canister control, or at least to support a mode where the canister-defined response is honored.

E. Authentication challenge compatibility

For native interoperability with existing DAV clients, support around authentication headers and HTTP auth flows is also very important.

Even if ICP developers ultimately choose to build stronger token- or delegation-based auth patterns, standard clients frequently expect familiar challenge/response mechanics and header behavior. In practice, interoperability may depend on whether Authorization and WWW-Authenticate can participate in the handshake without being broken by gateway policy.

F. XML request/response interoperability

DAV protocols are XML-heavy and use 207 Multi-Status responses extensively. The canister interface already supports binary bodies and arbitrary response codes, which is good. But it would be helpful for DFINITY to explicitly state that supporting XML-heavy multi-status DAV traffic is a target use case for official gateways and certification tooling.

G. Large collection sync and streaming

Address books, calendars, attachments, and large DAV listings can become substantial in size. This makes reliable response body streaming relevant for DAV workloads too, not just websites or static assets.

If ICP wants to support serious synchronization use cases, gateway streaming and certification should be considered part of the DAV readiness story.

H. Stable behavior across official gateways and local tooling

The development experience matters. If local gateways, PocketIC/dfx HTTP behavior, and mainnet gateways differ materially for methods or headers, developers will struggle to build and test standards-compatible DAV services.

A clear compatibility target and conformance tests for DAV-style traffic would greatly help.

Why this is strategically valuable for ICP

I think this feature request has ecosystem-wide value far beyond one niche protocol family.

Productivity infrastructure is a major adoption surface

Calendars, contacts, and files are foundational infrastructure. If ICP can support them natively with open standard clients, that makes the platform more relevant to:

  • enterprises,

  • public sector organizations,

  • privacy-focused communities,

  • digital sovereignty initiatives,

  • regulated industries,

  • and teams that want open interoperability without surrendering control to hyperscalers.

It would demonstrate that ICP is not limited to web frontends

ICP is already strong at hosting web assets and application logic. But full DAV compatibility would send a much stronger message: ICP can serve as the backend for existing protocol ecosystems, not only custom dapps.

That would widen the addressable market considerably.

It strengthens the “full ICP stack” story

A lot of builders want to avoid a hybrid architecture where ICP stores the important data but a conventional server still has to sit in front as a protocol adapter.

Every time a centralized proxy is required, we lose some of the benefits of decentralization:

  • more operational complexity,

  • more trust assumptions,

  • more cost,

  • more attack surface,

  • more vendor dependency,

  • and less architectural clarity.

Removing that need would be a major milestone for ICP as a full-stack decentralized compute platform.

It aligns well with blockchain-native governance and ownership

A contact book, calendar system, or shared file repository backed by canisters can be governed by:

  • a user,

  • a company,

  • an association,

  • a municipality,

  • a cooperative,

  • or a DAO.

That is a meaningful real-world use case for blockchain governance: not speculation, but durable administration of shared digital infrastructure.

Requested outcome

I would love to see DFINITY and the broader community consider a roadmap toward official gateway compatibility for DAV-class protocols.

Concretely, I would suggest:

  1. defining a target compatibility scope for WebDAV / CalDAV / CardDAV on official gateways,

  2. documenting which methods and headers should be transparently passed through,

  3. ensuring canister-controlled OPTIONS and custom protocol headers work reliably,

  4. clarifying best practices for mapping DAV operations to http_request vs http_request_update,

  5. adding conformance/integration tests using real DAV client behavior,

  6. and treating native client interoperability as a first-class product goal.

A possible governance angle

Since the Network Nervous System governs important parts of ICP evolution, this also feels like a good candidate for broader community discussion and possibly a governance motion later on, once the technical scope is refined.

The governance value here would not merely be “add one method”, but rather:

  • enable a new class of decentralized applications,

  • strengthen the full-ICP architecture story,

  • reduce dependency on centralized protocol bridges,

  • and improve ICP’s competitiveness for enterprise and productivity workloads.

References / prior discussion

Relevant background that motivated this request includes:

  • the HTTP Gateway Protocol specification, which already models generic HTTP method/header/body handling,

  • prior forum discussion on supported HTTP methods for canisters,

  • prior forum discussion on boundary-node/gateway handling of OPTIONS,

  • prior discussion on header limitations and gateway-layer overrides,

  • and prior feature requests around richer http_request behavior.

If helpful, I would be happy to help test this with a concrete CardDAV/CalDAV canister implementation and real clients such as Thunderbird and mobile DAV apps.

In my view, this is exactly the kind of feature that can help ICP move from “a blockchain that can host web apps” to “a decentralized compute platform that can replace real pieces of traditional internet infrastructure”. Open protocol compatibility is one of the strongest ways to prove that vision in practice.

Thanks for considering this.

Hi Atia, thanks a lot for this idea.

The HTTP gateway protocol and its implementations are open source and we do accept contributions. You are very welcome to propose adjustments to the HTTP gateway protocol and then update the implementation to support that.

From your post, I am not so clear what are all the things missing. In particular:

What are the actual issues that you mention here. Do you have specific examples (e.g., a canister that would support certain features, but the HTTP gateway blocks it)?

You list different things of which many IMO are not an issue. For example, Method-aware routing to query vs update semantics is not an issue. Whenever a canister gets a query call, but would expect an update call, it can just reply with upgrade to update and the HTTP gateway sends the update call. OPTIONS are also passed through to the canister. The HTTP gateway will only interfere if the canister does not properly reply. Large asset streaming is also supported.

If local gateways, PocketIC/dfx HTTP behavior, and mainnet gateways differ materially for methods or headers, developers will struggle to build and test standards-compatible DAV services.

Do you have examples where PocketIC and the mainnet gateways differ? They shouldn’t as they use exactly the same code.

I would love to see DFINITY and the broader community consider a roadmap toward official gateway compatibility for DAV-class protocols.

Concretely, I would suggest:
…

That’s a great plan! All the relevant repos are open-source and accept external contributions. Looking forward to your contributions!

Adding some data to this thread since I’ve been looking at the same question from a different angle, testing whether a canister can observe non-standard methods at all.

I deployed a minimal Rust canister (7k3kw-3qaaa-aaaax-qabbq-cai) that exposes both http_request (query) and http_request_update (update). The query always returns upgrade: Some(true), so any inbound request should reach the update endpoint, where it echoes back the method and headers it received.

PROPFIND doesn’t make it that far:

$ curl -i -X PROPFIND https://7k3kw-3qaaa-aaaax-qabbq-cai.icp0.io/
HTTP/2 405
allow: POST,GET,HEAD,PUT,DELETE,PATCH,OPTIONS
x-ic-canister-id: 7k3kw-3qaaa-aaaax-qabbq-cai
content-length: 0

Same response on raw.icp0.io, same allow-header. The canister never logs an invocation, so on this particular point I think the “upgrade to update” mechanism doesn’t help, the filtering is happening in front of the handler, not after it.

Tracing it in ic-gateway:

Both are compile-time, not config. On the canister side HttpRequest.method is text without a documented allowlist, which is what led me to look at the gateway as the next place a non-standard verb could be stopped.

A small change: swapping the MethodRouter for axum’s any(handler) would let http_request be the dispatch point for arbitrary verbs. The diff itself looks small; the wrinkle is CORS preflight, which would need to either broaden the advertised methods or echo Access-Control-Request-Method.

Before anyone invests time writing that PR, it would be useful to hear whether a change along these lines is something DFN would consider merging, or whether the current allowlist is a deliberate choice (security, semantics, ops) that should stay.

Short follow-up with data on the rest of the items in the original post, collected with the same test canister (7k3kw-3qaaa-aaaax-qabbq-cai). I added a call counter and log ring buffer to the canister so each test has canister-side verification independent of what the gateway does on the response path.

C / E — DAV and auth request headers: pass through fine. Depth, Destination, If, Lock-Token, Overwrite, Brief, Prefer, Translate, Range, If-Match, If-None-Match, ETag, Authorization, WWW-Authenticate, DAV, Allow, custom X-*, all arrive in req.headers unchanged. Not a blocker :white_check_mark:.

F — status codes and XML: mostly fine, one exception. Verified pass-through for 200, 201, 202, 204, 207, 301, 302, 304, 400, 401, 403, 404, 405, 409, 410, 412, 423, 424, 500, 502, 503, 507. XML request bodies and Content-Type: application/xml responses are preserved.

206 is the exception. Without Content-Range the gateway returns 503 from ic-http-gateway-protocol/response_handler.rs:250. With a valid Content-Range: bytes 0-9/10 and a 10-byte body, the response became 502 “Error reading response body from the backend”, that string is in ic-http-lb/src/routing.rs, where the load-balancer’s body.collect() errors while trying to buffer the response. I haven’t traced why collecting a 10-byte body fails on the 206 code path; would appreciate a pointer from someone who knows.

D — OPTIONS: extends item A’s pattern. In ic-gateway/src/routing/middleware/cors.rs the middleware applies a three-part validator to OPTIONS responses (is_valid_preflight_response):

  1. status code must be 2xx,
  2. body size hint must be exactly 0,
  3. response must include at least one Access-Control-Allow-* header.

If any of those fail, the canister’s principal is inserted into an invalid_canisters cache and the gateway returns its own default preflight. On subsequent OPTIONS requests, the middleware short-circuits: next.run(request) is not called, the canister is never invoked. Evidence from the test run: after one initial invalid response, the canister’s counter stayed at +0 across 16 subsequent OPTIONS requests.

For DAV this is a structural issue. A natural OPTIONS response for a DAV resource is 200 + empty or capability body + DAV: 1, 2 + Allow: OPTIONS, GET, HEAD, POST, PUT, DELETE, PROPFIND, …, which does not include any Access-Control-Allow-* header and so fails check (3). Getting this wrong once (per-canister-principal, TTL-bounded) leaves the canister silent on OPTIONS until the cache entry expires.