Network Working GroupJ. Hildebrand
Internet-DraftJabber, Inc.
Intended status: InformationalP. Saint-Andre
Expires: April 1, 2005Jabber Software Foundation
September 28, 2004

Transporting WebDAV-Related Event Notifications over the Extensible Messaging and Presence Protocol (XMPP)

Status of this Memo

This document is an Internet-Draft and is subject to all provisions of section 3 of RFC 3667. By submitting this Internet-Draft, each author represents that any applicable patent or other IPR claims of which he or she is aware have been or will be disclosed, and any of which he or she become aware will be disclosed, in accordance with RFC 3668.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF), its areas, and its working groups. Note that other groups may also distribute working documents as Internet-Drafts.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as “work in progress”.

The list of current Internet-Drafts can be accessed at http://www.ietf.org/ietf/1id-abstracts.txt.

The list of Internet-Draft Shadow Directories can be accessed at http://www.ietf.org/shadow.html.

This Internet-Draft will expire on April 1, 2005.

Copyright Notice

Copyright © The Internet Society (2004). All Rights Reserved.

Abstract

This memo describes a method for notifying interested parties about WebDAV-related events (such as PUTs and DELETEs), where such notifications are delivered via an extension to the Extensible Messaging and Presence Protocol (XMPP) for publish-subscribe functionality.


1. Introduction

1.1. Overview

[WEBDAV] defines a set of extensions to [HTTP] for remote web content authoring operations. Entities that make use of such WebDAV services, which may include both human users and ancillary applications such as content management systems, may want to be notified when a WebDAV operation is applied to a web resource. For example, a human user may want to be notified whenever a particular shared resource is locked or unlocked, and an external auditing application may need to be informed whenever a resource is added, modified, or deleted. The methods of greatest interest will probably be COPY, DELETE, LOCK, MKCOL, MOVE, POST, PROPPATCH, PUT, and UNLOCK, but event notifications related to other methods may be appropriate, as well.

Such notifications follow a classic "observer" or "publish-subscribe" design pattern: one entity initiates an event, and an event notification is broadcasted to all those who are interested in knowing when such events occur. Unfortunately, existing methods for learning that a resource has been updated are currently limited to "polling" for changes via HTTP, which is inherently inefficient. What is needed is a technology that can be relied on to "push" information only when a resource undergoes a state change, and only to those who are interested in learning about such state changes.

One possible technology for doing so is email, since [SMTP] provides a way to initiate the sending of information from "publishers" to "subscribers" (think, for example, of email lists such as those used to announce newly-published RFCs). While email is one possible solution, it is not necessarily the best solution for WebDAV; in particular, [WEBDAV] defines XML data formats for method parameters and other metadata, which implies that it might be beneficial to use a native XML delivery mechanism rather than to attach a special XML media type to email messages. Thankfully, a specialized XML delivery protocol has been developed through the IETF: the Extensible Messaging and Presence Protocol (XMPP) as specified in [XMPP-CORE]. XMPP has the added benefit of being optimized for near-real-time data delivery, which may be important in applications of WebDAV that require subscribers to be notified about WebDAV-related events in a highly timely manner.

While the semantics of a normal XMPP <message/> element may be suitable for WebDAV-related event notifications, there also exists an XMPP extension that provides more structured communications in the context of "topics" whose scope can be limited to a particular WebDAV resource or collection. This extension is specified in [XMPP-PUBSUB] and may be especially useful for delivering notifications related to changes in WebDAV resources. Therefore, this memo describes a method for notifying interested parties about WebDAV-related events, where such notifications are delivered via the XMPP publish-subscribe extension.

1.2. Use Cases

Several use cases originally motivated this proposal:

  1. A user who views a WebDAV collection through a file explorer application can use the notification protocol described herein to see in near-real-time when resources in the collection are successfully updated, locked, unlocked, etc.
  2. An application that replicates or mirrors an existing WebDAV repository can use the notification protocol described herein to stay synchronized with changes to the source repository, rather than updating less often in "batch" mode.

1.3. Process Flow

When a client performs a WebDAV operation on a resource, many other entities may be interested in learning that the operation has successfully completed. The generalized process flow is as follows:

  • A WebDAV client creates a resource at a WebDAV service.
  • The WebDAV service sends an XMPP pubsub node creation request to an XMPP pubsub service and thereafter advertises availability of that pubsub node as a live property of the resource.
  • One or more XMPP entities subscribe to the pubsub node.
  • A WebDAV client requests completion of a WebDAV operation on the resource.
  • The WebDAV service successfully completes the requested operation.
  • The WebDAV service sends an appropriate XMPP pubsub request -- node creation, node deletion, or publish (with payload if appropriate) -- to the XMPP pubsub service.
  • The XMPP pubsub service sends an XMPP message notification to each XMPP entity that subscribed to the pubsub node.

The result is that the XMPP subscribers will receive near-real-time notification whenever a WebDAV operation has been completed on a resource of interest.

The steps initiated by a WebDAV client in communication with a WebDAV service are out of scope for this memo, since they are described in [WEBDAV] and related memos. The XMPP protocols for the other steps are shown in the examples provided below.

Note: This memo describes event notifications related to successful WebDAV operations only (i.e., operations that result in a 200-series acknowledgement from the WebDAV service to the WebDAV client). The pattern described herein could be used for unsuccessful operations as well (e.g., to address auditing use cases), but such usage is out of scope for this memo.

1.4. Architecture

We can visualize the architecture as follows:

     +---------------+
     | WebDAV Client |
     +---------------+
            |
            | [HTTP/1.1 + WebDAV]
            |
     +----------------+
     | WebDAV Service |
     +----------------+
            |
            | [XMPP + Pubsub Extension]
            |
  +---------------------+
  | XMPP Pubsub Service |
  +---------------------+
            |
            | [XMPP + Pubsub Extension]
            |
     +-------------+
     | XMPP Entity |
     +-------------+
          

1.5. Terminology

This document inherits terminology from [WEBDAV], [XMPP-CORE], and [XMPP-PUBSUB].

The capitalized 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 RFC 2119 [TERMS].

1.6. Discussion Venue

The authors welcome discussion and comments related to the topics presented in this document. The preferred forum is the <w3c-dist-auth@w3.org> mailing list, for which subscription information and archive links are available at <http://www.ietf.org/html.charters/webdav-charter.html>.

1.7. Acknowledgements

Thanks to Lisa Dusseault for helpful comments.

2. Properties

This section describes the WebDAV properties that SHOULD be supported by a WebDAV service that publishes notifications to an XMPP pubsub service. Advertisement of these properties enables WebDAV clients and other entities to discover that a WebDAV service or specific resource supports the protocol defined herein.

2.1. Pubsub Notification Property

The "notify" property specifies whether XMPP pubsub notifications are published for a resource. The qualifying namespace is 'urn:ietf:params:xml:ns:webdav-event:prop:notify', the element name is <notify/>, and the allowable values of the character data are "true" and "false" (where "true" means that there exists an XMPP pubsub node associated with the resource, and "false" means that no such node exists). This property MUST be live and MAY be protected. The WebDAV service SHOULD advertise this property for each resource it hosts.

A sample of the format is shown in the following WebDAV PROPFIND example.

First, a client queries a specific WebDAV resource regarding this property.

PROPFIND /foo/bar HTTP/1.1
Host: example.com
Depth: 1
Content-Type: text/xml; charset="utf-8"
Content-Length: xxxx

<?xml version="1.0" encoding="UTF-8" ?>
<propfind xmlns="DAV:">
  <prop>
    <notify 
      xmlns="urn:ietf:params:xml:ns:webdav-event:prop:notify"/>
  </prop>
</propfind>
          

Then the WebDAV service responds with "true" or "false".

HTTP/1.1 207 Multi-Status
Date: Mon, 27 Sep 2004 19:52:01 GMT
Content-Type: text/xml; charset="utf-8"
Content-Length: xxxx

<?xml version="1.0" encoding="UTF-8" ?>
<multistatus xmlns="DAV:">
  <response>
    <href>http://example.com/foo/bar</href>
    <propstat>
      <notify 
          xmlns="urn:ietf:params:xml:ns:webdav-event:prop:notify">
        true
      </notify>
      <status>HTTT//1.1 200 OK</status>
    </propstat>
  </response>
</propfind>
          

2.2. Pubsub Node Property

The "node" property specifies the pubsub node at which notifications are published. The qualifying namespace is 'urn:ietf:params:xml:ns:webdav-event:prop:node', the element name is <node/>, and the character data of the <service/> and <nodeid/> children specify, respectively, the XMPP address of the pubsub service (in accordance with the definition of a JID in [XMPP-CORE]) and the node ID at which notifications are published (in accordance with the definition of a pubsub NodeID in [XMPP-PUBSUB]). This property MUST be live and MAY be protected. The WebDAV service SHOULD advertise this property for each resource whose <notify/> property is "true".

The syntax of the <nodeid/> element's character data is implementation-specific and therefore out of scope for this specification. If the pubsub service is a "dedicated" service connected only to the WebDAV service, the node ID could simply be the URI of the WebDAV resource (e.g., "http://example.com/foo/bar"). If the pubsub service is a generalized pubsub service that serves entities other than the WebDAV service, the pubsub node could be the WebDAV resource URI prepended by an implementation-specific or deployment-specific string such as "webdav|". Naturally, some other syntax is allowable as well, such as a SHA1-hash of the WebDAV resource URI.

A sample of the format is shown in the following WebDAV PROPFIND example.

First, a client queries a specific WebDAV resource regarding this property.

PROPFIND /foo/bar HTTP/1.1
Host: example.com
Depth: 1
Content-Type: text/xml; charset="utf-8"
Content-Length: xxxx

<?xml version="1.0" encoding="UTF-8" ?>
<propfind xmlns="DAV:">
  <prop>
    <node 
      xmlns="urn:ietf:params:xml:ns:webdav-event:prop:node"/>
  </prop>
</propfind>
          

Then the WebDAV service responds with the XMPP address of the pubsub service along with the specific node ID.

HTTP/1.1 207 Multi-Status
Date: Mon, 27 Sep 2004 20:06:38 GMT
Content-Type: text/xml; charset="utf-8"
Content-Length: xxxx

<?xml version="1.0" encoding="UTF-8" ?>
<multistatus xmlns="DAV:">
  <response>
    <href>http://example.com/foo/bar</href>
    <propstat>
      <node xmlns="urn:ietf:params:xml:ns:webdav-event:prop:node">
        <service>pubsub.example.com</service>
        <nodeid>webdav|http://example.com/foo/bar</nodeid>
      </node>
      <status>HTTT//1.1 200 OK</status>
    </propstat>
  </response>
</propfind>
          

3. Payload Format

3.1. Wrapper Element

In order to include payloads (rather than mere event notifications) in XMPP pubsub, it is necessary to re-use an existing XML format or define a new one. Since no existing format is fully appropriate for WebDAV-related events, we define a new payload format for use in WebDAV notifications. The "wrapper" for such payloads is a <webdav/> element qualified by the 'urn:ietf:params:xml:ns:webdav-event:payload' namespace; this wrapper element MUST possess two attributes: the 'method' attribute specifies which WebDAV method was applied, and the 'resource' attribute specifies the full URI of the resource to which the method was applied. The wrapper format is as follows:

  <webdav xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
          method='METHOD-NAME'
          resource='RESOURCE-URI'>
    [ OPTIONAL PAYLOAD ELEMENTS ]
  </webdav>
          

For certain operations, the wrapper element may provide complete information about the success of the operation. For example, this is true for the DELETE operation:

  <webdav xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
          method='DELETE'
          resource='http://example.com/foo/bar'/>
          

The same is true of the UNLOCK operation:

  <webdav xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
          method='UNLOCK'
          resource='http://example.com/foo/bar'/>
          

However, this is not true of all WebDAV operations, in which case the wrapper element MAY contain child elements that specify additional information about the operation. For example, a PUT or POST operation may result in changes to the resource (for which it would be helpful to receive a "diff"), a PROPPATCH operation may result in the application of new or changed properties (for which an XML format is defined in [WEBDAV]), and other operations may result in a new ETag or output in some other XML format defined in [WEBDAV]. The following subsections specify the formats to be included as children of the event wrapper element.

It is not necessary to define a payload format associated with the MKCOL operation, since that operation maps directly to node creation in the XMPP pubsub extension (where the node is a collection node). Similarly, a WebDAV PUT or POST operation that results in the creation of a new resource maps to node creation in the XMPP pubsub extension (where the node is not a collection node).

Note: Line breaks in the following protocol descriptions are not significant and are included to improve readability only.

3.2. <activelock/> Element

The <activelock/> payload child (qualified by the 'DAV:' namespace) enables a WebDAV service to communicate the results of a LOCK request received from a WebDAV client (i.e., the fact that a resource is now locked).

  <webdav xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
          method='LOCK'
          resource='http://example.com/foo/bar'>
    <activelock xmlns='DAV:'>
      <locktype><write/></locktype>
      <lockscope><exclusive/></lockscope>
      <depth>infinity</depth>
      <owner>
        <href>
          http://jabber.org/people/stpeter.php
        </href>
      </owner>
      <timeout>Second-604800</timeout>
      <lockroot>
        <href>http://example.com/foo/bar</href>
      </lockroot>
    </activelock>
  </webdav>
          

Note: A WebDAV service MAY send less information than shown above, and for security purposes SHOULD NOT include the <locktoken/> element described in [WEBDAV].

3.3. <diff/> Element

The <diff/> payload child (qualified by the 'urn:ietf:params:xml:ns:webdav-event:payload:diff' namespace) enables a WebDAV service to communicate the changes to a resource that resulted from a successful WebDAV operation (e.g., a POST or PUT). The XML character data of the <diff/> element MUST be encoded using base64, where the encoding adheres to the definition in Section 3 of RFC 3548 [BASE64]. The value of the 'format' attribute specifies which diff format is used; possible values include, but are not limited to, "gdiff" (see [GDIFF] and "vcdiff" (see [VCDIFF]).

  <webdav xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
          method='PUT'
          resource='http://example.com/foo'>
    <diff xmlns='urn:ietf:params:xml:ns:webdav-event:payload:diff'
          format='gdiff'>
      base64
    </diff>
  </webdav>
          

The <diff/> payload child MAY also be published as a result of a successful PATCH operation (see [PATCH]).

3.4. <etag/> Element

The <etag/> payload child (qualified by the 'urn:ietf:params:xml:ns:webdav-event:payload:etag' namespace) enables a WebDAV service to communicate an entity tag related to a request received from a WebDAV client. The XML character data of the <etag/> element MUST be an ETag as defined in Sections 3.11 and 14.19 of [HTTP].

  <webdav xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
          method='POST'
          resource='http://example.com/foo/bar'>
    <etag xmlns='urn:ietf:params:xml:ns:webdav-event:payload:etag'>
      some-entity-tag
    </etag>
  </webdav>
          

3.5. <href/> Element

The <href/> payload child (qualified by the 'DAV:' namespace) enables a WebDAV service to communicate a URI resulting from a successful WebDAV COPY or MOVE operation as specified by the 'method' attribute of the <webdav/> element. For body COPY and MOVE, the 'resource' attribute of the <webdav/> element specifies the URI of the source resource, and the character data of the <href/> child specifies the URI of the destination resource.

  <webdav xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
          method='COPY'
          resource='http://example.com/foo'>
    <href xmlns='DAV:'>http://example.com/foo/newbar</href>
  </webdav>
          
  <webdav xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
          method='MOVE'
          resource='http://example.com/foo'>
    <href xmlns='DAV:'>http://example.com/foo/newbar</href>
  </webdav>
          

3.6. <propertyupdate/> Element

The <propertyupdate/> payload child (qualified by the 'DAV:' namespace) enables a WebDAV service to communicate the property update received from a WebDAV client during a PROPPATCH operation. The XML format for this element is defined in [WEBDAV].

  <webdav xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
          method='POST'
          resource='http://example.com/foo/bar'>
    <propertyupdate xmlns='DAV:'>
      <set>
        <prop>
          <publish xmlns='http://example.com/ns'>true</publish>
        </prop>
      </set>
    </propertyupdate>
  </webdav>
          

4. Examples

This section currently provides several examples of process flows. We assume the following order of operations:

  1. A new collection "foo" is created at the example.com WebDAV service.
  2. A new resource "bar" is created within the "foo" collection.
  3. The "bar" resource is copied to the "newbar" resource.
  4. The properties of the "bar" resource are modified.
  5. The "bar" resource is locked.
  6. The "bar" resource is modified.
  7. The "bar" resource is unlocked.
  8. The "newbar" resource is deleted.

We also assume that the entity "trackerbot@example.com" has an XMPP pubsub subscription of type "nodes" at depth='all' to the root pubsub collection node ("pubsub.example.com") and therefore receives notification regarding all new nodes and collections created at the pubsub service.

Finally, we assume that the pubsub nodes are configured to deliver payloads, not just event notifications (since the <webdav/> wrapper element and its children are necessary in order to understand the full context of operations at the WebDAV service).

Note: Line breaks in the following protocol examples are not significant and are included to improve readability only.

4.1. Collection Created

First, a WebDAV client creates the "foo" collection by means of a MKCOL operation.

Once the WebDAV service successfully creates the "foo" collection, it sends an XMPP pubsub collection node creation request to the XMPP pubsub service:

<iq type='set'
    from='webdav-service.example.com'
    to='pubsub.example.com'
    id='mkcol1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <create node='foo'/>
    <configure>
      <x xmlns='jabber:x:data' type='submit'>
        <field type='hidden' var='FORM_TYPE'>
          <value>
            http://jabber.org/protocol/pubsub#node_config
          </value>
        </field>
        <field var='pubsub#node_type'>
          <value>collection</value>
        </field>
      </x>
    </configure>
  </pubsub>
</iq>
          

If no errors occur during processing of the foregoing XML stanza, the XMPP pubsub service then sends a pubsub node creation notification to each XMPP entity that has a subscription of type "nodes" to the root collection node (including our "TrackerBot"), where the payload contains the meta-data for the new collection node as described in [XMPP-PUBSUB]. (Note that in accordance with the rules in [XMPP-PUBSUB] allowing such behavior, the pubsub service has created a node ID of "webdav|http://example.com/foo" as a result of the request to create a node named "foo".)

<message from='pubsub.example.com'
         to='trackerbot@example.com'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items>
      <item id='webdav|http://example.com/foo'>
        <x xmlns='jabber:x:data' type='result'>
          <field var='FORM_TYPE' type='hidden'>
            <value>
              http://jabber.org/protocol/pubsub#meta-data
            </value>
          </field>
          <field var='pubsub#creation_date' 
                 label='Creation date'>
            <var>2004-09-23T17:23Z</var>
          </field>
          <field var='pubsub#creator' label='Node creator'>
            <var>webdav-service.example.com</var>
          </field>
          <field var='pubsub#type' label='The type of node'>
            <var>urn:ietf:params:xml:ns:webdav-event</var>
          </field>
        </x>
     </items>
  </event>
</message>
          

4.2. Resource Created

Next, a WebDAV client creates the "bar" resource in the "foo" collection (we assume by means of a PUT operation).

Once the WebDAV service successfully creates the "bar" resource, it sends an XMPP pubsub node creation request to the XMPP pubsub service and associates the new node with the "foo" collection:

<iq type='set'
    from='webdav-service.example.com'
    to='pubsub.example.com'
    id='put1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <create id='bar'/>
    <configure>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='pubsub#collections'>
          <value>foo</value>
        </field>
      </x>
    </configure>
  </pubsub>
</iq>
          

If no errors occur during processing of the foregoing XML stanza, the XMPP pubsub service then sends a pubsub node creation notification to each XMPP entity that has a subscription of type "nodes" to the root collection node or the "foo" collection node.

<message from='pubsub.example.com'
         to='trackerbot@example.com'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='webdav|http://example.com/foo'>
      <item id='webdav|http://example.com/foo/bar'>
        <x xmlns='jabber:x:data' type='result'>
          <field var='FORM_TYPE' type='hidden'>
            <value>
              http://jabber.org/protocol/pubsub#meta-data
            </value>
          </field>
          <field var='pubsub#creation_date' 
                 label='Creation date'>
            <var>2004-09-23T17:26Z</var>
          </field>
          <field var='pubsub#creator' label='Node creator'>
            <var>webdav-service.example.com</var>
          </field>
          <field var='pubsub#type' label='The type of node'>
            <var>urn:ietf:params:xml:ns:webdav-event</var>
          </field>
        </x>
     </items>
  </event>
</message>
          

Those informed of the new node may then decide to subscribe to it for pubsub item notifications; we shall assume that the TrackerBot does so:

<iq from='trackerbot@example.com/bot'
    to='pubsub.example.com'
    type='set'
    id='sub1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe 
        node='webdav|http://example.com/foo/bar'
        jid='trackerbot@example.com'/>
  </pubsub>
</iq>
          

The pubsub service then replies with success:

<iq from='pubsub.example.com'
    to='trackerbot@example.com/bot'
    type='result'
    id='sub1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <entity 
        node='webdav|http://example.com/foo/bar'
        jid='trackerbot@example.com'
        affiliation='none'
        subid='123-abc'
        subscription='subscribed'/>
  </pubsub>
</iq>
          

4.3. Resource Copied

Next, a WebDAV client copies the "bar" resource to a new resource "newbar" by means of a COPY operation.

Once the WebDAV service successfully copies the "bar" resource to the "newbar" resource, it (1) creates a new pubsub node for it (since the "newbar" resource is new and XMPP entities may want to know when it is modified, deleted, and so on), and (2) publishes an XMPP pubsub item to the "foo/bar" node at the XMPP pubsub service, including a <webdav/> wrapper element specifying a COPY operation and containing an <href/> child element:

First, the WebDAV service sends an XMPP pubsub node creation request to the XMPP pubsub service and associates the new node with the "foo" collection:

<iq type='set'
    from='webdav-service.example.com'
    to='pubsub.example.com'
    id='newnode2'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <create id='newbar'/>
    <configure>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='pubsub#collections'>
          <value>foo</value>
        </field>
      </x>
    </configure>
  </pubsub>
</iq>
          

If no errors occur during processing of the foregoing XML stanza, the XMPP pubsub service then sends a pubsub node creation notification to each XMPP entity that has a subscription of type "nodes" to the root collection node or the "foo" collection node.

<message from='pubsub.example.com'
         to='trackerbot@example.com'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='webdav|http://example.com/foo'>
      <item id='webdav|http://example.com/foo/newbar'>
        <x xmlns='jabber:x:data' type='result'>
          <field var='FORM_TYPE' type='hidden'>
            <value>
              http://jabber.org/protocol/pubsub#meta-data
            </value>
          </field>
          <field var='pubsub#creation_date' 
                 label='Creation date'>
            <var>2004-09-23T20:22Z</var>
          </field>
          <field var='pubsub#creator' label='Node creator'>
            <var>webdav-service.example.com</var>
          </field>
          <field var='pubsub#type' label='The type of node'>
            <var>urn:ietf:params:xml:ns:webdav-event</var>
          </field>
        </x>
     </items>
  </event>
</message>
          

Those informed of the new node may then decide to subscribe to it for pubsub item notifications; we shall assume that the TrackerBot does so:

<iq from='trackerbot@example.com/bot'
    to='pubsub.example.com'
    type='set'
    id='sub2'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe 
        node='webdav|http://example.com/foo/newbar'
        jid='trackerbot@example.com'/>
  </pubsub>
</iq>
          

The pubsub service then replies with success:

<iq from='pubsub.example.com'
    to='trackerbot@example.com/bot'
    type='result'
    id='sub2'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <entity 
        node='webdav|http://example.com/foo/newbar'
        jid='trackerbot@example.com'
        affiliation='none'
        subid='234-bcd'
        subscription='subscribed'/>
  </pubsub>
</iq>
          

Second, the WebDAV service publishes a COPY event to the pubsub node for the "bar" resource.

<iq type='set'
    from='webdav-service.example.com'
    to='pubsub.example.com'
    id='copy1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='webdav|http://example.com/foo/bar'>
      <item>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='COPY'
            resource='http://example.com/foo/bar'>
          <href xmlns='DAV:'>
            http://example.com/foo/newbar
          </href>
        </webdav>
      </item>
    </publish>
  </pubsub>
</iq>
          

If no errors occur during processing of the foregoing XML stanza, the XMPP pubsub service then sends a pubsub notification to each XMPP entity that has a subscription of type "items" to the "bar" node (or at depth='all' to any of its ancestor nodes).

<message from='pubsub.example.com'
         to='trackerbot@example.com'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='webdav|http://example.com/foo/bar'>
      <item id='copy-id'>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='COPY'
            resource='http://example.com/foo/bar'>
          <href xmlns='DAV:'>
            http://example.com/foo/newbar
          </href>
        </webdav>
      </item>
     </items>
  </event>
</message>
          

4.4. Properties Modified

Next, a WebDAV client modifies the properties of the "bar" resource by means of a PROPPATCH operation.

Once the WebDAV service successfully modifies the properties of the "bar" resource, it publishes an XMPP pubsub item to the "foo/bar" node at the XMPP pubsub service, including a <webdav/> wrapper element specifying a PROPPATCH method and containing a <propertyupdate/> child element:

<iq type='set'
    from='webdav-service.example.com'
    to='pubsub.example.com'
    id='proppatch1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='webdav|http://example.com/foo/bar'>
      <item>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='PROPPATCH'
            resource='http://example.com/foo/bar'>
          <propertyupdate xmlns='DAV:'>
            <set>
              <prop>
                <publish xmlns='http://example.com/ns'>
                  true
                </publish>
              </prop>
            </set>
          </propertyupdate>
        </webdav>
      </item>
    </publish>
  </pubsub>
</iq>
          

If no errors occur during processing of the foregoing XML stanza, the XMPP pubsub service then sends a pubsub notification to each XMPP entity that has a subscription of type "items" to the "bar" node (or at depth='all' to any of its ancestor nodes).

<message from='pubsub.example.com'
         to='trackerbot@example.com'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='webdav|http://example.com/foo/bar'>
      <item id='prop-id'>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='PROPPATCH'
            resource='http://example.com/foo/bar'>
          <propertyupdate xmlns='DAV:'>
            <set>
              <prop>
                <publish xmlns='http://example.com/ns'>
                  true
                </publish>
              </prop>
            </set>
          </propertyupdate>
        </webdav>
      </item>
     </items>
  </event>
</message>
          

4.5. Resource Locked

Next, a WebDAV client locks the "bar" resource by means of a LOCK operation.

Once the WebDAV service successfully locks the "bar" resource, it publishes an XMPP pubsub item to the "foo/bar" node at the XMPP pubsub service, including a <webdav/> wrapper element specifying a LOCK method and containing an <activelock/> child element:

<iq type='set'
    from='webdav-service.example.com'
    to='pubsub.example.com'
    id='proppatch1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='webdav|http://example.com/foo/bar'>
      <item>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='LOCK'
            resource='http://example.com/foo/bar'>
          <activelock xmlns='DAV:'>
            <locktype><write/></locktype>
            <lockscope><exclusive/></lockscope>
            <depth>infinity</depth>
            <owner>
              <href>
                http://jabber.org/people/stpeter.php
              </href>
            </owner>
            <timeout>Second-604800</timeout>
            <locktoken>
              <href>
                opaquelocktoken:e71d4fae-5dec-22d6-\
                fea5-00a0c91e6be4
              </href>
            </locktoken>
            <lockroot>
              <href>http://example.com/foo/bar</href>
            </lockroot>
          </activelock>
        </webdav>
      </item>
    </publish>
  </pubsub>
</iq>
          

If no errors occur during processing of the foregoing XML stanza, the XMPP pubsub service then sends a pubsub notification to each XMPP entity that has a subscription of type "items" to the "bar" node (or at depth='all' to any of its ancestor nodes).

<message from='pubsub.example.com'
         to='trackerbot@example.com'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='webdav|http://example.com/foo/bar'>
      <item>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='LOCK'
            resource='http://example.com/foo/bar'>
          <activelock xmlns='DAV:'>
            <locktype><write/></locktype>
            <lockscope><exclusive/></lockscope>
            <depth>infinity</depth>
            <owner>
              <href>
                http://jabber.org/people/stpeter.php
              </href>
            </owner>
            <timeout>Second-604800</timeout>
            <locktoken>
              <href>
                opaquelocktoken:e71d4fae-5dec-22d6-\
                fea5-00a0c91e6be4
              </href>
            </locktoken>
            <lockroot>
              <href>http://example.com/foo/bar</href>
            </lockroot>
          </activelock>
        </webdav>
      </item>
     </items>
  </event>
</message>
          

4.6. Resource Modified

Next, a WebDAV client modifies the "bar" resource (we assume by means of a PUT operation).

Once the WebDAV service successfully modifies the "bar" resource, it publishes an XMPP pubsub item to the "foo/bar" node at the XMPP pubsub service, including a <webdav/> wrapper element specifying a PUT method and containing a <diff/> child element:

<iq type='set'
    from='webdav-service.example.com'
    to='pubsub.example.com'
    id='put2'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='webdav|http://example.com/foo/bar'>
      <item>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='PUT'
            resource='http://example.com/foo/bar'>
          <diff 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload:diff'>
            base64
          </diff>
        </webdav>
      </item>
    </publish>
  </pubsub>
</iq>
          

If no errors occur during processing of the foregoing XML stanza, the XMPP pubsub service then sends a pubsub notification to each XMPP entity that has a subscription of type "items" to the "bar" node (or at depth='all' to any of its ancestor nodes).

<message from='pubsub.example.com'
         to='trackerbot@example.com'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='webdav|http://example.com/foo/bar'>
      <item id='mod-id'>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='PUT'
            resource='http://example.com/foo/bar'>
          <diff 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload:diff'>
            base64
          </diff>
        </webdav>
      </item>
     </items>
  </event>
</message>
          

4.7. Resource Unlocked

Next, a WebDAV client unlocks the "bar" resource by means of an UNLOCK operation.

Once the WebDAV service successfully unlocks the "bar" resource, it publishes an XMPP pubsub item to the "foo/bar" node at the XMPP pubsub service, including an empty <webdav/> wrapper element specifying an UNLOCK method:

<iq type='set'
    from='webdav-service.example.com'
    to='pubsub.example.com'
    id='unlock1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='webdav|http://example.com/foo/bar'>
      <item>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='UNLOCK'
            resource='http://example.com/foo/bar'/>
      </item>
    </publish>
  </pubsub>
</iq>
          

If no errors occur during processing of the foregoing XML stanza, the XMPP pubsub service then sends a pubsub notification to each XMPP entity that has a subscription of type "items" to the "bar" node (or at depth='all' to any of its ancestor nodes).

<message from='pubsub.example.com'
         to='trackerbot@example.com'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='webdav|http://example.com/foo/bar'>
      <item id='unlock-id'>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='UNLOCK'
            resource='http://example.com/foo/bar'/>
      </item>
     </items>
  </event>
</message>
          

4.8. Resource Deleted

Next, a WebDAV client deletes the "newbar" resource by means of a DELETE operation.

Once the WebDAV service successfully deletes the "newbar" resource, it publishes an XMPP pubsub item to the "foo/newbar" node at the XMPP pubsub service, including an empty <webdav/> wrapper element specifying a DELETE method:

<iq type='set'
    from='webdav-service.example.com'
    to='pubsub.example.com'
    id='delete1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <publish node='webdav|http://example.com/foo/newbar'>
      <item>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='DELETE'
            resource='http://example.com/foo/newbar'/>
      </item>
    </publish>
  </pubsub>
</iq>
          

If no errors occur during processing of the foregoing XML stanza, the XMPP pubsub service then sends a pubsub notification to each XMPP entity that has a subscription of type "items" to the "newbar" node (or at depth='all' to any of its ancestor nodes).

<message from='pubsub.example.com'
         to='trackerbot@example.com'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='webdav|http://example.com/foo/newbar'>
      <item id='delete-id'>
        <webdav 
            xmlns='urn:ietf:params:xml:ns:webdav-event:payload'
            method='DELETE'
            resource='http://example.com/foo/newbar'/>
      </item>
     </items>
  </event>
</message>
          

It might be assumed that it would be enough to delete the pubsub node when the corresponding WebDAV resource is deleted. However, there is not necessarily a one-to-one correspondence between WebDAV resources and pubsub nodes, and there may be good reasons to delete the pubsub node even if the WebDAV resource has not been deleted (e.g., "publish events" might be a property that can be set via PROPPATCH, and setting that property to "false" might result in deletion of the associated pubsub node). However, once the resource is deleted, the WebDAV service SHOULD also delete the associated pubsub node:

<iq type='set'
    from='webdav-service.example.com'
    to='pubsub.example.com'
    id='delete1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <delete id='webdav|http://example.com/foo/newbar'/>
  </pubsub>
</iq>
          

Subscribers will then be notified that the node has been deleted:

<message from='pubsub.example.com'
         to='trackerbot@example.com'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <delete id='webdav|http://example.com/foo/newbar'/>
  </event>
</message>
          

5. Security Considerations

Detailed security considerations for the relevant protocols profiled in this memo are given in [WEBDAV], [XMPP-CORE], and [XMPP-PUBSUB].

As far as possible, a WebDAV service SHOULD synchronize authorization between the WebDAV service and the XMPP pubsub service, using the subscription authorization protocol described in [XMPP-PUBSUB]; for example, a WebDAV service SHOULD NOT allow an entity to receive diffs via XMPP if such an entity would not be authorized to retrieve the resource via HTTP and its WebDAV extensions.

6. References

6.1. Normative References

[BASE64]
Josefsson, S., “The Base16, Base32, and Base64 Data Encodings”, RFC 3548, July 2003.
[HTTP]
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.
[TERMS]
Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997.
[WEBDAV]
Dusseault, L. and J. Crawford, “HTTP Extensions for Distributed Authoring - WebDAV RFC2518 bis”, Internet-Draft draft-ietf-webdav-rfc2518bis-06 (work in progress), July 2004.
[XMPP-CORE]
Saint-Andre, P., “Extensible Messaging and Presence Protocol (XMPP): Core”, Internet-Draft draft-ietf-xmpp-core-24 (work in progress), May 2004.
[XMPP-PUBSUB]
Millard, P., “Publish-Subscribe”, JSF JEP 0060, July 2004.

6.2. Informative References

[GDIFF]
Hoff, A. and J. Payne, “Generic Diff Format Specification”, W3C NOTE NOTE-gdiff-19970901, September 1997.
[PATCH]
Dusseault, L., “Partial Document Changes (PATCH Method) for HTTP”, Internet-Draft draft-dusseault-http-patch-04 (work in progress), August 2004.
[SMTP]
Klensin, J., “Simple Mail Transfer Protocol”, RFC 2821, April 2001.
[VCDIFF]
Korn, D., MacDonald, J., Mogul, J., and K. Vo, “The VCDIFF Generic Differencing and Compression Data Format”, RFC 3284, June 2002.

Authors' Addresses

Joe Hildebrand
Jabber, Inc.
EMail: jhildebrand@jabber.com
Peter Saint-Andre
Jabber Software Foundation
EMail: stpeter@jabber.org

Full Copyright Statement

Copyright © The Internet Society (2004).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an “AS IS” basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.