RFC 5995

Using POST to Add Members to Web Distributed Authoring and Versioning (WebDAV) Collections

πŸ“… published September 2010, from ietf

Using POST to Add Members to Web Distributed Authoring and Versioning (WebDAV) Collections πŸŽ€

Part 1 of 2 ✨ Written by J. Reschke of greenbytes, published September 2010 as a Standards Track document (ISSN 2070-1721). The title block doesn't list anything this one obsoletes or updates. πŸ¦‹


Abstract 🌸

Okay so the HTTP Extensions for WebDAV don't define what POST does on collections. That's because the base HTTP spec gives implementers lots of freedom with POST, so nobody's really locked it in. πŸ€·β€β™€οΈ

The result? Tons of WebDAV servers just don't do POST for collections at all πŸ’€. Which is wild, because POST is literally perfect for adding new members to a collection where the server gets to decide the new URL. The Atom Publishing Protocol (AtomPub) already does exactly this 😭. Meanwhile WebDAV-based protocols like CalDAV make clients pick a unique URL even though the server could totally handle that itself. Not it. πŸ™…β€β™€οΈ

This spec adds a discovery mechanism so servers can announce that they support POST with those "add collection member" semantics. Main character energy πŸ‘‘.

Status of This Memo πŸ“œ

This is an Internet Standards Track document.

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). For more on Internet Standards, check Section 2 of RFC 5741 🧚.

Want the current status, any errata, or a way to send feedback? Head to http://www.rfc-editor.org/info/rfc5995 πŸ”—.

Copyright (c) 2010 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, because they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

Table of Contents πŸ’œ

1. Introduction ....................................................2
2. Terminology .....................................................4
3. Protocol Extension ..............................................4
   3.1. Definition of "Add-Member" URI .............................5
   3.2. Discovery ..................................................6
        3.2.1. DAV:add-member Property (Protected) .................6
        3.2.2. Example .............................................6
   3.3. Relation to AtomPub's "Slug" Header Field ..................7
   3.4. Example Operation ..........................................7
4. Additional Semantics for Existing Methods .......................8
   4.1. Additional Preconditions ...................................8
   4.2. Example: Failed PUT Request ................................8
5. Relationship to WebDAV Access Control Protocol ..................9
6. Internationalization Considerations .............................9
7. Security Considerations .........................................9
8. Acknowledgements ...............................................10
9. References .....................................................10
   9.1. Normative References ......................................10
   9.2. Informative References ....................................11
Index .............................................................11

1. Introduction πŸ’–

So WebDAV (the HTTP Extensions for the Web Distributed Authoring and Versioning) ([RFC4918], Section 9.5) doesn't define POST for collections. The base HTTP spec leaves implementers so much room for what POST means that WebDAV just kind of shrugged πŸ€·β€β™€οΈ. Here's what it says:

   9.5 POST for Collections

   Since by definition the actual function performed by POST is
   determined by the server and often depends on the particular
   resource, the behavior of POST when applied to collections cannot
   be meaningfully modified because it is largely undefined.  Thus,
   the semantics of POST are unmodified when applied to a collection.

The problem is that a lot of WebDAV servers never implement POST for collections at all 😭, even though it's a great fit for adding new members where the server controls the newly assigned URL. AtomPub is the proof, since it uses POST exactly for that purpose ([RFC5023], Section 9.2):

   9.2 Creating Resources with POST

   To add members to a Collection, clients send POST requests to the
   URI of the Collection.

Then you've got WebDAV-based protocols like CalDAV, which make clients pick a unique URL even though the server could easily do it ([RFC4791], Section 5.3.2) πŸ™„:

   5.3.2 Creating Calendar Object Resources

   ...

   When servers create new resources, it's not hard for the server to
   choose an unmapped URI.  It's slightly tougher for clients,
   because a client might not want to examine all resources in the
   collection and might not want to lock the entire collection to
   ensure that a new resource isn't created with a name collision.
   (...)

Letting the server pick the member URI is a simplification for certain kinds of clients 🧚. It can also cut down on server complexity, since the server doesn't have to store an extra client-supplied identifier when it already has an internal one like a Universally Unique Identifier (UUID) or a primary key πŸ”‘.

Note: The vCard Extensions to WebDAV (CardDAV) ([CARDDAV]) run into the same issue, and they might be able to use this spec too πŸ’….

This spec adds a discovery mechanism so servers can say they support POST with those "add collection member" semantics. Sis, that's the whole vibe ✨.

This spec is very intentional about only covering creating new non-collection resources. It's not trying to do the same thing for creating collections (MKCOL), or for other operations where the client has to name a new URL (LOCK, MOVE, or COPY) 🚫.

Note: The author originally proposed a brand new HTTP method for exactly this purpose ([ADDMEMBER]). Quite a few reviewers pointed out that it would just duplicate the original semantics of POST πŸ™ˆ. So this proposal avoids adding a new HTTP method. Iconic glow-up πŸ¦‹.

2. Terminology 🌈

The terminology follows the WebDAV specification ([RFC4918]) πŸ“–.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] 🫢.

This document uses XML DTD fragments ([XML]) as a purely notational convention. Specifically:

  • Element ordering is irrelevant. πŸ“
  • Extension elements and attributes (the ones not already defined as valid child elements) may be added anywhere, unless it's explicitly stated otherwise. πŸŽ€
Note: This spec defines new properties and precondition names in the "DAV:" namespace. WebDAV reserves that namespace for use by the IETF ([RFC4918], Section 21.1). But the WebDAV community had rough consensus that this spec applies to other WebDAV-related standards efforts too, so it deserves a spot in the base namespace πŸ’œ.

3. Protocol Extension ⭐

Remember the reasons from Section 1? Clients can't count on a specific server behavior when POST is applied to a collection 😀. So this spec lets servers advertise a URI that has the "add member" semantics they want.

Servers that already use POST for something else can just expose a separate URI 🌸. Everyone else can advertise the collection's own URI, which means no minting another URI for one limited purpose πŸ’….

3.1. Definition of "Add-Member" URI πŸ¦‹

The "Add-Member" URI of a WebDAV collection is a URI that accepts HTTP POST requests. It interprets them as requests to store the enclosed entity as a new internal member of the collection (see Section 3 of [RFC4918] for the definition of "internal member") 🧚. It MUST identify a resource on the same server as the WebDAV collection, meaning the host and port components ([RFC2616], Section 3.2.2) of the URIs must match πŸ”’.

If there are preconditions for creating a resource in the collection with a PUT request, then those same preconditions apply to the new POST behavior. The same HTTP response body gets returned on failure too πŸ™…β€β™€οΈ.

The URI of the newly created resource comes back in the HTTP Location response header field ([RFC2616], Section 14.30) πŸ“¬.

Note: Advertising an "Add-Member" URI doesn't imply any special semantics for the collection itself. For example, member URIs the server assigns aren't necessarily unique over time. A member URI can get assigned again to a new resource after the old one was removed πŸ‘€.
Note: The "Add-Member" URI can be identical to the collection's URI. In that case the server is just announcing that POST to the WebDAV collection's URI is supported as defined in this spec πŸ’–. It can also be different, and then it doesn't need any relation to the collection's URI at all ✨.

Given a collection URI of

/docs/collection/

any of these might show up as an "Add-Member" URI:

/docs/collection/
/docs/collection/;post
/docs/collection;post/
/docs/collection/&post
/post-service?path=/collection/

The rest of the document uses the same format just to stay consistent. Any other HTTP URI on the same server would work too 🌈.

3.2. Discovery πŸ”

3.2.1. DAV:add-member Property (Protected) πŸ”

DAV:add-member is a protected property (see [RFC4918], Section 15) defined on WebDAV collections. It holds the "Add-Member" URI for that collection, wrapped inside a DAV:href element πŸŽ€.

<!ELEMENT add-member (href)>
<!-- href: defined in [RFC4918], Section 14.7 -->

A PROPFIND/allprop request SHOULD NOT return this property (see [RFC4918], Section 9.1) πŸ™ˆ. Servers MUST implement the DAV:supported-live-property-set property defined in Section 3.1.4 of [RFC3253], and they MUST report the property DAV:add-member as a supported live property πŸ’œ.

3.2.2. Example ✨

Okay so here's a full PROPFIND moment πŸ’… The client asks /collection/ for its add-member property, and the server basically says "oh, you want to add stuff? here's a whole separate URI just for that" πŸ¦‹

>>Request

PROPFIND /collection/ HTTP/1.1
Host: example.com
Content-Type: application/xml; charset="utf-8"
Content-Length: 118

<?xml version="1.0" encoding="utf-8" ?>
<propfind xmlns="DAV:">
  <prop>
    <add-member/>
  </prop>
</propfind>
>>Response

HTTP/1.1 207 Multi-Status
Content-Type: application/xml; charset="utf-8"
Content-Length: 340

<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
  <response>
    <href>/collection/</href>
    <propstat>
      <prop>
        <add-member>
          <href>/collection;add-member/</href>
        </add-member>
      </prop>
      <status>HTTP/1.1 200 OK</status>
    </propstat>
  </response>
</multistatus>

In this case, the server has minted a separate URI just for adding new content. Iconic behaviour πŸŽ€

3.3. Relation to AtomPub's "Slug" Header Field

Okay, so in the AtomPub protocol, clients can use the entity header field Slug to suggest parts of the URI that get created (see [RFC5023], Section 9.7). Servers are totally free to ignore that suggestion, or to use whatever algorithm makes sense to make the new URI. No pressure πŸ’–

The same vibe applies to the extension defined here. Clients can use the Slug header field, because by definition it's a generic HTTP header field. Servers should process it exactly the way AtomPub defines, and that's giving consistency 🫢

3.4. Example Operation

Let's see it in action 🧚

>>Request

POST /collection;add-member/ HTTP/1.1
Host: example.com
Content-Type: text/plain
Slug: Sample Title
Content-Length: 12

Sample text.

>>Response

HTTP/1.1 201 Created
Location: http://example.com/collection/sample%20title

4. Additional Semantics for Existing Methods 🌸

One important use case for this spec is collections that act as WebDAV collections for read access (PROPFIND Depth 1/Infinity), but that only support internal member URIs assigned by the server. These collections won't let a client create a new member using methods like PUT, MKCOL, LOCK, COPY, or MOVE. So this specification defines a new precondition name ([RFC4918], Section 16) that can be used to give the client extra info about exactly why the request failed. Clear communication, periodt πŸ’…

Note: Although the precondition defined below can be used for methods other than PUT, the "Add-Member" mechanism defined by this specification deliberately is restricted to PUT.

4.1. Additional Preconditions

DAV:allow-client-defined-URI: the server allows clients to specify the last path segment for newly created resources. Main character energy πŸ‘‘

The precondition element MAY contain an add-member-uri XML element specifying the "Add-Member" URI associated with the collection where the creation of a new child resource was attempted:

<!ELEMENT allow-client-defined-uri (add-member?)>

4.2. Example: Failed PUT Request

In this example, the client tries to use PUT to create a new internal member of /collection/. Bestie, it's giving rejection, but a helpful one πŸ™ˆ

>>Request

PUT /collection/new.txt HTTP/1.1
Host: example.com
Content-Type: text/plain
Content-Length: 12

Sample text.

>>Response

HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, TRACE, PROPFIND, COPY, MOVE
Content-Type: application/xml; charset=UTF-8
Content-Length: 172

<error xmlns="DAV:">
  <allow-client-defined-uri>
    <add-member>
      <href>/collection;add-member/</href>
    </add-member>
  </allow-client-defined-uri>
</error>

The request fails with a 405 (Method Not Allowed) status, but it also gives the reason, plus a pointer to the "Add-Member" URI in the response body. Iykyk, that's a lowkey iconic move ✨

5. Relationship to WebDAV Access Control Protocol πŸ”

The WebDAV Access Control Protocol spec requires the DAV:bind privilege to be granted on a collection for the client to be able to add new collection members ([RFC3744], Section 3.9). Consistent with that, a server MUST reject a POST request to the Add-Member URI of a collection, unless the principal executing the request is granted DAV:bind privilege on the associated WebDAV collection resource. No bind, no add, no cap 🚫

6. Internationalization Considerations 🌍

This document doesn't introduce any new internationalization considerations beyond those discussed in Section 19 of [RFC4918]. Nothing new to see here, bestie 🧚

7. Security Considerations 🚨

Security considerations that apply to HTTP [RFC2616], WebDAV [RFC4918], and XML [XML] apply to this specification too, namely Section 20 of [RFC4918] and Section 7 of [RFC3470]. Please read those, they're literally the tea β˜•

Also, servers should be aware that deriving the member path from the data being stored in the resource could potentially expose confidential information. This could even be the case when only a hash code of the content is used. Okay this part is SERIOUS 😭

In addition, on servers that don't support this specification, a malevolent user could set the DAV:add-member URI as a custom property, tricking other users into posting content to an entirely different URI. That's a villain arc πŸ’€ Clients can protect themselves against this scenario by:

  • not following DAV:add-member URIs to different servers, and/or
  • verifying that the DAV:add-member property is indeed a live property. This can be achieved by testing the DAV:supported-live-property-set property, or by checking whether DAV:add-member is returned upon PROPFIND/allprop.

8. Acknowledgements 🫢

This document has benefited from thoughtful discussion by Cyrus Daboo and Bernard Desruisseaux. Thank you, besties πŸ’œ

9. References πŸ“š

9.1. Normative References

[RFC2119]   Bradner, S., "Key words for use in RFCs to Indicate
            Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2616]   Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
            Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
            Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.

[RFC3253]   Clemm, G., Amsden, J., Ellison, T., Kaler, C., and J.
            Whitehead, "Versioning Extensions to WebDAV (Web
            Distributed Authoring and Versioning)", RFC 3253,
            March 2002.

[RFC3744]   Clemm, G., Reschke, J., Sedlar, E., and J. Whitehead,
            "Web Distributed Authoring and Versioning (WebDAV) Access
            Control Protocol", RFC 3744, May 2004.

[RFC4918]   Dusseault, L., Ed., "HTTP Extensions for Web Distributed
            Authoring and Versioning (WebDAV)", RFC 4918, June 2007.

[XML]       Bray, T., Paoli, J., Sperberg-McQueen, C., Maler, E., and
            F. Yergeau, "Extensible Markup Language (XML) 1.0 (Fifth
            Edition)", W3C REC-xml-20081126, November 2008,
            <http://www.w3.org/TR/2008/REC-xml-20081126/>.

9.2. Informative References

[ADDMEMBER] Reschke, J., "The HTTP ADDMEMBER Method", Work
            in Progress, February 2005.

[CARDDAV]   Daboo, C., "vCard Extensions to WebDAV (CardDAV)", Work
            in Progress, November 2009.

[RFC3470]   Hollenbeck, S., Rose, M., and L. Masinter, "Guidelines
            for the Use of Extensible Markup Language (XML) within
            IETF Protocols", BCP 70, RFC 3470, January 2003.

[RFC4791]   Daboo, C., Desruisseaux, B., and L. Dusseault,
            "Calendaring Extensions to WebDAV (CalDAV)", RFC 4791,
            March 2007.

[RFC5023]   Gregorio, J., Ed. and B. de hOra, Ed., "The Atom
            Publishing Protocol", RFC 5023, October 2007.

Index πŸ—‚οΈ

A
   Add-Member URI  5

C
   Condition Names
      DAV:allow-client-defined-URI (pre)  8
   COPY method
      Additional Preconditions  8

D
   DAV:allow-client-defined-URI  8

L
   LOCK method
      Additional Preconditions  8

M
   MKCOL method
      Additional Preconditions  8
   MOVE method
      Additional Preconditions  8

P
   PUT method
      Additional Preconditions  8

Author's Address πŸ¦‹

Julian F. Reschke
greenbytes GmbH
Hafenweg 16
Muenster, NW  48155
Germany

Phone: +49 251 2807760
EMail: julian.reschke@greenbytes.de
URI:   http://greenbytes.de/tech/webdav/
πŸ“¦ where this page comes from