RFC 5875
An Extensible Markup Language (XML) Configuration Access Protocol (XCAP) Diff Event Package
An Extensible Markup Language (XML) Configuration Access Protocol (XCAP) Diff Event Package ๐
bestie, this is RFC 5875 and it's a Standards Track doc, so it's the real deal ๐ It came out in May 2010. The authors are J. Urpalainen from Nokia and D. Willis (the Ed. one, which means editor) from Softarmor Systems LLC. The ISSN is 2070-1721. The title block doesn't list anything it obsoletes or updates, so it's giving independent main character energy ๐
Abstract โจ
okay so this doc describes an xcap-diff SIP (Session Initiation Protocol) event package for the SIP Event Notification Framework ๐ฆ Clients use it to get notified when XCAP (Extensible Markup Language (XML) Configuration Access Protocol) resources change. The first sync info exchange and the document updates are both based on the XCAP Diff format ๐
Status of This Memo ๐ธ
This is an Internet Standards Track document ๐ฅ
It's a product of the Internet Engineering Task Force (IETF), so it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). If you want more on Internet Standards, check out Section 2 of RFC 5741 ๐ง
Info about the current status of this document, any errata, and how to give feedback lives at http://www.rfc-editor.org/info/rfc5875 ๐
Copyright Notice ๐ฆ
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), as in effect on the date this document was published. Read these carefully, because they spell out your rights and restrictions for this document. Code Components pulled out of this document must include the Simplified BSD License text described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as the Simplified BSD License describes ๐ซถ
This document may contain material from IETF Documents or IETF Contributions that were published or made publicly available before November 10, 2008. The people controlling the copyright in some of that material might not have granted the IETF Trust the right to allow modifications outside the IETF Standards Process. So unless you get an adequate license from whoever controls that copyright, this document may not be modified outside the IETF Standards Process, and derivative works of it may not be created outside the IETF Standards Process ๐ The exceptions are formatting it for publication as an RFC, or translating it into languages other than English.
Table of Contents ๐
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 4
3. Definitions . . . . . . . . . . . . . . . . . . . . . . . . . 4
4. XCAP Diff Event Package . . . . . . . . . . . . . . . . . . . 4
4.1. Overview of Operation with Basic Requirements . . . . . . 4
4.2. Event Package Name . . . . . . . . . . . . . . . . . . . . 5
4.3. 'diff-processing' Event Package Parameter . . . . . . . . 5
4.4. SUBSCRIBE Bodies . . . . . . . . . . . . . . . . . . . . . 6
4.5. Subscription Duration . . . . . . . . . . . . . . . . . . 8
4.6. NOTIFY Bodies . . . . . . . . . . . . . . . . . . . . . . 8
4.7. Notifier Generation of NOTIFY Requests . . . . . . . . . . 8
4.8. Subscriber Processing of NOTIFY Requests . . . . . . . . . 11
4.9. Handling of Forked Requests . . . . . . . . . . . . . . . 13
4.10. Rate of Notifications . . . . . . . . . . . . . . . . . . 13
4.11. State Agents . . . . . . . . . . . . . . . . . . . . . . . 13
5. An Initial Example NOTIFY Document . . . . . . . . . . . . . . 13
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14
7. Security Considerations . . . . . . . . . . . . . . . . . . . 15
8. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 15
9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 16
9.1. Normative References . . . . . . . . . . . . . . . . . . . 16
9.2. Informative References . . . . . . . . . . . . . . . . . . 17
Appendix A. Informative Examples . . . . . . . . . . . . . . . . 18
A.1. Initial Documents on an XCAP Server . . . . . . . . . . . 18
A.2. An Initial Subscription . . . . . . . . . . . . . . . . . 18
A.3. A Document Addition into a Collection . . . . . . . . . . 19
A.4. A Series of XCAP Component Modifications . . . . . . . . . 20
A.5. An XCAP Component Subscription . . . . . . . . . . . . . . 23
A.6. A Conditional Subscription . . . . . . . . . . . . . . . . 26
1. Introduction ๐
okay so the SIP events framework [RFC3265] is where the subscription and notification rules for the Session Initiation Protocol (SIP) [RFC3261] live. Then you've got XCAP [RFC4825], which lets a client read, write, and modify XML-formatted application usage data stored on an XCAP server, with XML defined in [W3C.REC-xml-20060816] ๐ง
here's the tea โ XCAP lets authorized users or devices modify the same XML document, but it doesn't have a good way (other than polling) to keep resources in sync between a server and a client. so this memo defines an xcap-diff event package. Together with the SIP event notification framework [RFC3265] and the XCAP diff format [RFC5874], it lets a user subscribe to changes in an XML document and get notified every time that document changes ๐
this event package does three main things โจ
First, a client can subscribe to a list of XCAP document URLs in a collection on an XCAP server. The subscriber compares the server's resources with its local ones using the URLs and the strong entity tag (ETag) values of the XCAP documents, which show up in the XCAP diff format, and then syncs them up ๐ฆ
Second, the package can signal changes to those documents in one of three ways ๐ The first mode only says what kind of event happened and doesn't include document contents, so the subscriber uses HTTP [RFC2616] to fetch the updated document. The second mode puts document content changes right in the notification messages, using the XML-Patch-Ops [RFC5261] format, and keeps the notification as small as possible. The third mode also puts content changes in the notifications with the same XML-Patch-Ops format, but it's wordier because it shows the full HTTP version history ๐
Third, a client can subscribe to specific XML elements or attributes (XCAP components) and get their current contents in the XCAP diff format notification messages ๐ซถ If the component you asked for doesn't exist yet but gets created later, the notifier sends a notification with the component's content. The notifier also sends notifications when the subscribed XCAP components get removed, for example after a successful HTTP DELETE request ๐
2. Terminology ๐
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 RFC 2119, BCP 14 [RFC2119], and they indicate requirement levels for compliant implementations ๐ฅ
3. Definitions ๐
these are the terms this doc uses โจ
- XCAP component: An XML element or an attribute, which can be updated, removed, or retrieved with XCAP.
- Aggregating: An XCAP client can only update a single XCAP component at a time using HTTP. However, a notifier may be able to combine a series of these modifications into a single notification using XML-Patch-Ops semantics encoded in the XCAP diff format ๐
This document reuses terminology mostly defined in XCAP [RFC4825], and some terminology from WebDAV [RFC4918] ๐ฆ
4. XCAP Diff Event Package ๐
4.1. Overview of Operation with Basic Requirements ๐
okay so to get the xcap-diff features, the subscriber says what it's interested in by including a URI list in the subscription body sent to the notifier ๐ Each URL in this list MUST be an HTTP URL that identifies a collection, an XCAP document, or an XCAP component. Collection URLs MUST have a trailing forward slash /, following the WebDAV [RFC4918] conventions. A collection selection covers all the documents in that collection and, recursively, all the documents in its sub-collections ๐ง The URL of an XCAP component is the document URL with the XCAP Node Selector added. Even though the XCAP Node Selector lets you request all in-scope namespaces of an element, the client MUST NOT subscribe to namespaces ๐
The notifier MUST support XCAP component subscriptions ๐ฅ It sends the first notification in response to the subscription, and that first notification MUST contain the URLs of the documents and the XCAP component contents that are part of the subscription. The subsequent notifications MAY contain patches to these documents โจ The subscriber can pick how the notifier signals document changes by using the 'diff-processing' event package parameter, which is covered in Section 4.3. Just know that whether the diff-processing parameter exists, or what its value is, has no influence on XCAP component subscriptions ๐
4.2. Event Package Name ๐ธ
The name of this event package is xcap-diff. As [RFC3265] specifies, this value shows up in the Event header field in SUBSCRIBE and NOTIFY requests ๐ฆ
4.3. 'diff-processing' Event Package Parameter ๐ โจ
Okay so the optional "diff-processing" Event header field parameter lets the subscriber say what vibe they want for how the notifier SHOULD tell them about document changes ๐ฆ. There are three options: "no-patching", "xcap-patching", and "aggregate". All three give the subscriber enough info to sync its local cache, but only "xcap-patching" shows the in-between states of the version history ๐ฐ๏ธ. The notifier SHOULD use the mode the subscriber asked for if it actually understands it, because that cuts down on network traffic and still fits what the receiver can handle ๐ธ.
"no-patching" means the notifier only tells you the document and the event type (creation, modification, and removal) ๐. It doesn't have to show the full HTTP ETag change history, so don't expect the whole story here.
Notifiers MUST support "no-patching" as a base-line for interoperability ๐ซถ. The other, more complex modes are optional.
"xcap-patching" means the notifier includes all the updated XCAP component contents and entity tag (ETag) changes that XCAP clients made over HTTP ๐. The client gets the full (HTTP) ETag change history of a document, which is giving completeness ๐.
"aggregate" means the notifier MAY squish several individual XCAP component updates into one XCAP diff <document> element ๐ง. How it decides whether to aggregate, or how many updates to bundle, is up to the notifier locally ๐.
The notifier SHOULD support "xcap-patching" and "aggregate", which means it implements XML-Patch-Ops [RFC5261] diff-generation ๐ฅ. This is lowkey a big deal because it can seriously reduce how many notifications and transmissions are needed ๐.
If the subscription doesn't have the "diff-processing" header field parameter, the notifier MUST default to "no-patching" ๐.
Note: To see the difference between "xcap-patching" and "aggregate", picture a document with versions "a", "b", and "c", with ETag values "1", "2", and "3" ๐ฆ. "xcap-patching" sends the change from "a" to "b" (ETags "1" and "2") first, then the change from "b" to "c" (ETags "2" and "3") โจ. "aggregate" optimizes it and sends just one combined change from "a" to "c", with old ETag "1" and new ETag "3" ๐. If the changes are closely related, meaning the same element got updated a bunch of times, the bandwidth savings are even bigger ๐ญ.
This "diff-processing" parameter is just a hint from the subscriber to the notifier ๐ . The notifier may respond using a simpler mode, but not a more complex one. How the notifier picks a mode is covered in Section 4.7 ๐. During re-subscriptions, the subscriber MAY change the diff-processing parameter ๐ซถ.
The formal grammar [RFC5234] of the "diff-processing" parameter is:
diff-processing = "diff-processing" EQUAL (
"no-patching" /
"xcap-patching" /
"aggregate" /
token )
where EQUAL and token are defined in RFC 3261 [RFC3261].
4.4. SUBSCRIBE Bodies ๐ธ
The URI list is described by the XCAP resource list format [RFC4826], and it goes in as a body of the initial SUBSCRIBE request ๐ง. Only a simple subset of that format is required: a flat list of XCAP request URIs ๐. The "uri" attribute of the <entry> element holds these URI values โจ. The subscriber MUST NOT use hierarchical lists or <entry-ref> references, etc. ๐ (though in the future, the semantics might get expanded thanks to the functionality in the resource list format ๐ฎ). In later SUBSCRIBE requests, like the ones used to refresh the expiration timer, the subscribed URI list MAY change ๐ฆ. If it does, the notifier MUST use the new list ๐.
The SUBSCRIBE request MAY contain an Accept header field ๐ . If there's no Accept header field, the default value is "application/xcap-diff+xml" ๐. If the header field is there, it MUST include "application/xcap-diff+xml", and it MAY include any other types ๐.
The SUBSCRIBE request MAY contain the Suppress-If-Match header field [RFC5839] ๐. It tells the notifier to suppress either the body of a later notification or the whole notification if the ETag value matches ๐ซถ.
If the SUBSCRIBE body has elements or attributes the notifier doesn't understand, the notifier MUST ignore them ๐.
Subscribers need to fill in the Request-URI of the SUBSCRIBE request properly, usually set to the URI of the notifier ๐ง. This document doesn't constrain that URI ๐. It's assumed the subscriber was provisioned with the URI of the notifier for this event package, or has learned it ๐ธ.
The XCAP server is usually co-located with the SIP notifier, so the subscriber MAY use relative XCAP Request-URIs ๐ฆ. Since relative Request-URIs are allowed, the notifier MUST know how to resolve them against the correct XCAP Root URI value ๐.
Figure 1 shows a SUBSCRIBE request and body covering several XCAP resources: a "resource-list" document, a specific element (XCAP component) in an "rls-services" document, and a collection in the "pidf-manipulation" application usage ๐ . The "Content-Type" header of this SUBSCRIBE request is "application/resource-lists+xml" ๐.
SUBSCRIBE sip:tests@xcap.example.com SIP/2.0
...
Accept: application/xcap-diff+xml
Event: xcap-diff; diff-processing=aggregate
Content-Type: application/resource-lists+xml
Content-Length: [XXX]
Expires: 4200
<?xml version="1.0" encoding="UTF-8"?>
<resource-lists xmlns="urn:ietf:params:xml:ns:resource-lists">
<list>
<entry uri="resource-lists/users/sip:joe@example.com/index"/>
<entry uri="rls-services/users/sip:joe@example.com/index/
~~/*/service%5b@uri='sip:marketing@example.com'%5d"/>
<entry uri="pidf-manipulation/"/>
</list>
</resource-lists>
Figure 1: Example subscription body
When subscribing to XCAP components, namespace prefixes of XCAP Node Selectors MUST be properly resolved to namespace URIs ๐ฅ. Section 6.4 of RFC 4825 [RFC4825] describes the conventions for using prefixes in XCAP Node Selectors ๐ค. If only the XCAP Default Document Namespace is used, like in the previous example (where a <service> element is selected), the query component of the "uri" value isn't required ๐ซถ.
4.5. Subscription Duration โฐ
The default expiration time for subscriptions in this package is 3600 seconds ๐. As per RFC 3265 [RFC3265], the subscriber MAY specify an alternative expiration timer in the Expires header field โจ.
4.6. NOTIFY Bodies ๐ฌ
The NOTIFY message body is either the default "application/xcap-diff+xml" or a format listed in the Accept header field of the SUBSCRIBE ๐ง.
In this event package, notification messages contain an XCAP diff document [RFC5874] ๐ฆ.
The XCAP diff format [RFC5874] can include the subscribed XCAP component contents ๐. For documents, the format can also include corresponding URIs, ETag values, and patching instructions from version "a" to "b" ๐ธ. Removal events (of documents, elements, or attributes) can be identified too ๐. Except for collection selections, the "sel" selector values of the XCAP diff format MUST be octet-by-octet equivalent to the relevant "uri" parameter values of the <entry> element of the "resource-list" document ๐ฅ.
With XCAP component subscriptions, XCAP Node Selectors can contain namespace prefixes ๐. A notifier MUST then resolve these prefixes to namespace URIs according to RFC 4825 [RFC4825] conventions ๐. In other words, notifiers MUST be aware of XCAP Default Document Namespaces for Application Usages when they locate unprefixed qualified XCAP elements ๐
. Note that the namespace resolving rules of Patch operation elements <add>, <replace>, and <remove> are described in Section 4.2.1 of [RFC5261] โจ.
4.7. Notifier Generation of NOTIFY Requests โจ
okay so this is where the notifier gets to do the real work ๐
. During the initial subscription, or if the URI list changes in SUBSCRIBE refresh requests, the notifier MUST resolve the requested XCAP resources and their privileges ๐. If there are superfluous resource selections in the requested URI list, the notifier SHOULD NOT provide overlapping similar responses for these resources. A resource for which an authenticated user does not have a read privilege MUST NOT be included in the XCAP diff format. Also, an XCAP component that can't be located with XCAP semantics does NOT throw an error ๐
โโ๏ธ. Instead, the request just chills in a "pending" state, which means it's waiting for that resource to be created (or for read access to be granted, if XCAP Application Usages use dynamic access control lists). Subscriptions to collections work the same way: once a new document is created in the subscribed collection, the creation of the new resource gets signaled with the next NOTIFY request.
After the notifier knows the list of authorized XCAP resources, it generates the first NOTIFY. This one contains URI references to all the subscribed, existing documents the subscriber has read privileges for, and typically the XCAP component(s) of the existing content ๐ฆ.
After sending that initial notification, the notifier picks a diff-processing mode for reporting changes. If the subscriber suggested a mode in the diff-processing parameter of the SUBSCRIBE, the notifier MAY use that requested mode or MAY fall back to a simpler operational mode, but the notifier MUST NOT use a more complex mode than the one the subscriber chose. From least to most complex, the modes go like this: "no-patching", "xcap-patching", "aggregate". So the notifier may respond to an "aggregate" request using any mode, but it cannot reply to an "xcap-patching" subscription using the "aggregate" mode ๐คฏ. Naturally, the notifier MUST handle a "no-patching" request with the "no-patching" mode.
In all modes, the notifier MUST maintain the chronological order of XCAP changes. If several changes to a given resource show up in a single notification, the chronological update order MUST be preserved in the XML document order of the notification body. Chronological order is kept so the subscriber's implementation logic stays simple ๐ง .
The "aggregate" mode uses bandwidth most efficiently, but it comes with its own drama ๐ญ. Initial synchronization might fail with rapidly changing resources, because "aggregate" mode messages might not include the full version history of a document, and the base XCAP protocol doesn't support version history retrievals of documents. When new documents get created in subscribed collections and the notifier is aggregating patches, the same issue can happen. In a corner case (like when the XML prolog changes), the notifier may not be able to provide patches with the XML-Patch-Ops [RFC5261] semantics.
If the notifier has to temporarily disable diff generation and send only the URI references of some changed documents to the subscriber, it MUST continue with the "xcap-patching" mode afterwards for these resources, if the initial subscription also started with the "xcap-patching" mode.
Note: The diff-generation may be disabled when the NOTIFY body becomes impractically large or an intermediate error has happened. As the subscriber loses track of the patching operations, it must refresh to a "known good" state by downloading current documents. Once it has done so, it can re-subscribe, for example, with the "aggregate" mode.
In the "aggregate" mode, the notifier chooses how long to wait for multiple patches to combine, and how that combination is done โณ.
In the "xcap-patching" mode, the notifier MAY try to optimize the diff-generation, for example by eliminating redundant information, since some XCAP clients will probably not have completely optimized their HTTP PUT request ๐งน.
Note: It is straightforward to change the XCAP client's change requests: PUT and DELETE (sent via HTTP) to use XML-Patch-Ops semantics. While XCAP does not support patching of all XML node types (for example, namespace declarations cannot be added separately), efficient utilization of XML-Patch-Ops can sometimes significantly reduce the bandwidth requirements at the expense of extra processing.
After the notifier has reported the existence of an XCAP component, it MUST also report its removal consistently. For example, removing the parent element of the subscribed element requires the same signaling, since the subscribed element ceases to exist ๐. To signal the removal of an XCAP component, the notifier sets the Boolean "exist" attribute value of the <element> or <attribute> elements to false. Even with rapidly changing resources, the notifier MUST signal only the latest state: for example, whether or not the XCAP component exists ๐ฏ.
When the notifier receives a re-subscription, it MUST re-send the current full XML diff content, unless the subscriber has requested a conditional subscription [RFC5839] by using the header field Suppress-If-Match: [ETag value]. With a conditional re-subscription, the notifier MUST also inspect the subscription body when determining the current subscription state. Since the subscription is based on a list of XCAP request URIs, it is RECOMMENDED that the notifier does not consider the order of these URIs when determining equivalence to "stored" previous states. If a match to the previous state is not found, the NOTIFY message MUST contain the full XML diff state (similar to the initial notification). The notifiers SHOULD implement the conditional subscription handling with this event package ๐.
During re-subscriptions, the subscriber may change the value of the diff-processing parameter. That value change only influences subsequent notifications, not the notification (if generated) that follows immediately after the (re-)SUBSCRIBE request.
Event packages like this one require reliable transfer of NOTIFY messages. This means all messages MUST successfully be transferred, or the document will become out of sync, and then patches will most likely fail (or worse, have unintended consequences) ๐ฑ. This "xcap-diff" event package requires, similar to Partial-PIDF-Notify RFC 5263 [RFC5263], that a notifier MUST NOT send a new NOTIFY request to the same dialog unless a successful 200-response has been received for the last sent NOTIFY request. If the NOTIFY request fails due to a timeout, the notifier MUST remove the subscription.
Note: This requirement ensures that out-of-order events will not happen, or that the dialog will terminate after non-resolvable NOTIFY request failures. In addition, some of the probable NOTIFY error responses (for example, 401, 407, 413) can possibly be handled gracefully without tearing down the dialog.
If, for example, the subscriber has selected too many elements to subscribe to, such that the notification body would be impractically large (that is, an intermediate NOTIFY failure), the notifier MAY discard the <element> element content. The existence of elements is then indicated with an empty <element> element, and the content is not shown for those resources. In other words, the <element> element does not have a child element that would show the subscribed "full" element content ๐ซง.
4.8. Subscriber Processing of NOTIFY Requests ๐
The first NOTIFY request will usually contain references to HTTP resources, including their strong ETag values. If the subscriber doesn't have similar locally cached versions, it'll typically start an unconditional HTTP GET request for those resources. During this HTTP retrieval time, the subscriber MAY also receive patches to these documents, if it has requested them and the documents are changing rapidly ๐ฌ. It can happen that the version retrieved by HTTP is not the same as what was indicated in the initial notification. A subscriber can then chain the modification list for each document and locate the position where the previous ETag value is equal to the one retrieved via HTTP. If an ETag match is not found from the first change, a subscriber MUST omit all changes up to the point where it is the same. From that change onwards, the subscriber applies all reported patches. If the version received via HTTP is newer than any received via the notifications, the subscriber may not find an equivalent match of an ETag value from the chain of patches.
This can happen because notifications are reported after HTTP changes, and preferably at some minimum intervals. Also, document removals can be reported in notifications, and/or HTTP retrievals may fail because of nonexistent resources (when they're changing rapidly) ๐โโ๏ธ. In any case, the subscriber can re-fetch the possibly out-of-sync document, wait for subsequent notifications, or refresh the subscription (with "xcap-patching"), and repeat the described "sync" algorithm until a "full" sync is achieved ๐.
If the notifier aggregates patches, the previous modification list may not contain the ETag value retrieved by HTTP, simply because of aggregation optimizations. A similar out-of-sync cycle can happen when new (subscribed) documents are created that change rapidly. To avoid such difficulties, the subscriber MAY start the subscription with the "xcap-patching" mode, and then refresh the subscription with the "aggregate" mode after the initial sync is achieved. Naturally, the subscriber can revert from "aggregate" back to "xcap-patching" mode at any time, and vice versa ๐.
If the subscriber has received a "full" sync and has detected that some of the resources are being served with the "xcap-patching" mode while others are in the "aggregate" mode, it SHOULD refresh the subscription to the "aggregate" mode.
The notifier MAY at any time temporarily use the "no-patching" mode for some resources, so the subscriber receives only URI references of modifications ๐. When the notifier is acting in this mode, several cycles MAY be needed before an initial "full" sync is achieved. As the notifier MAY change modes in the middle of a dialog, the subscriber is always responsible for taking appropriate actions. Also, as the last resort, the subscriber MAY always disable the usage of diff-processing by setting the "diff-processing" parameter to "no-patching" ๐.
If a diff format cannot be applied due to patch processing and/or programming errors (for a list, see Section 5.1 of [RFC5261]), the subscriber SHOULD refresh the subscription and disable patching by setting the "diff-processing" parameter to "no-patching". The subscriber SHOULD NOT reply with a non-200 response, since the notifier cannot make corrections ๐
โโ๏ธ.
During unconditional re-subscriptions, the subscriber MUST stamp the received state of all previous resources as stale. However, if a conditional [RFC5839] re-subscription is successful, the subscriber MUST preserve the current state of resources unless the subscribed URI list has changed. That is, the subscriber MUST fetch the resource's state, for example from some local cache ๐.
4.9. Handling of Forked Requests โจ
bestie, this spec only lets a single dialog get built from an initial SUBSCRIBE ๐ฆ So if the subscriber gets forked responses to a SUBSCRIBE, it MUST apply the procedures in Section 4.4.9 of RFC 3265 [RFC3265] for handling non-allowed forked requests ๐
4.10. Rate of Notifications ๐ซถ
Notifiers of an "xcap-diff" event package SHOULD NOT generate notifications for a single subscription at a rate of more than once every five seconds โจ no spamming your subscriber, periodt ๐
4.11. State Agents ๐ธ
State agents play no role in this package ๐ they just chill on the sidelines, no job here.
5. An Initial Example NOTIFY Document ๐
okay so Figure 2 is an example initial XCAP diff format document ๐ It's the first NOTIFY that comes back from the SUBSCRIBE in Figure 1. Here's the Event header field for that SUBSCRIBE request:
Event: xcap-diff; diff-processing=aggregate
The subscriber asks the notifier's aggregate XCAP component to keep the updates coming, and it expects the notifications after that to carry aggregated patches to these documents ๐ฅ
<?xml version="1.0" encoding="UTF-8"?>
<d:xcap-diff xmlns:d="urn:ietf:params:xml:ns:xcap-diff"
xmlns:s="urn:ietf:params:xml:ns:rls-services"
xcap-root="http://xcap.example.com/root/">
<d:document new-etag="7ahggs"
sel="resource-lists/users/sip:joe@example.com/index"/>
<d:document new-etag="30376adf"
sel="pidf-manipulation/users/sip:joe@example.com/index"/>
<d:element sel="rls-services/users/sip:joe@example.com/index/
~~/*/service%5b@uri='sip:marketing@example.com'%5d"
xmlns:rl="urn:ietf:params:xml:ns:resource-lists"
><s:service uri="sip:marketing@example.com">
<s:list name="marketing">
<rl:entry uri="sip:joe@example.com"/>
<rl:entry uri="sip:sudhir@example.com"/>
</s:list>
<s:packages>
<s:package>presence</s:package>
</s:packages>
</s:service></d:element>
</d:xcap-diff>
Figure 2: An example initial XCAP diff format document
Peep the resource-list "index" document ๐ it only carries the new ETag value, because it already existed when the subscription started. Over in the "pidf-manipulation" collection there's just one document Joe has read privileges for. The <service> element lives inside the rls-services "index" document, and its content is shown right there. Also, the <service> element was found using the Default Document Namespace (no prefix in the XCAP Node Selector value), even though it has an "s" prefix in the source document ๐ง
6. IANA Considerations ๐
IANA has added a new event package to the SIP Event Types Namespace registry, and it looks like this ๐
Package Name Type Contact Reference
------------- -------- ------- ---------
xcap-diff package IETF Real-time Applications [RFC5875]
<rai@ietf.org>
7. Security Considerations ๐
okay this section is SERIOUS bestie, so read it like it's your group chat's most important announcement ๐ญ
This document defines a new SIP event package for the SIP event notification framework specified in RFC 3265 [RFC3265]. Because of that, all the security considerations of RFC 3265 apply ๐ The configuration data can hold sensitive info, so both the client and the server need to authenticate each other ๐
The notifiers MUST authenticate the "xcap-diff" event package subscriber using the normal SIP authentication mechanisms, like Digest as defined in Section 22 of RFC 3261 [RFC3261]. The notifiers MUST also be aware of XCAP User Identifiers (XUI) and how to map the authenticated SIP identities unambiguously with XUIs ๐ซถ
Since XCAP [RFC4825] provides a basic authorization policy for resources, and since notifications carry content that looks a lot like XCAP resources, the security considerations of XCAP also apply โจ The notifiers MUST obey the XCAP authorization rules when signalling resource changes. In practice, that means following the read privilege rules of XCAP resources ๐ฆ
Denial-of-service attacks against notifiers deserve special mention ๐ These can cause denial of service due to intensive processing: subscriptions to a long list of URIs, "pending" subscriptions to non-existent documents or XCAP components, and diff-generation algorithms that try to optimize the required bandwidth usage to extremes.
The mechanism used for conveying xcap-diff event information MUST ensure integrity and SHOULD ensure confidentially of the information ๐ An end-to-end SIP encryption mechanism, like S/MIME described in Section 26.2.4 of RFC 3261 [RFC3261], SHOULD be used. If that's not available, it is RECOMMENDED that TLS [RFC5246] be used between elements, to provide the hop-by-hop authentication and encryption mechanisms described in Sections 26.2.2 ("SIPS URI Scheme") and 26.3.2.2 ("Interdomain Requests") of RFC 3261 [RFC3261] ๐
8. Acknowledgments ๐ท
The author would like to thank Jonathan Rosenberg for his valuable comments and for providing the initial event package ๐ฅน Big thanks also to Aki Niemi, Pekka Pessi, Miguel Garcia, Pavel Dostal, Krisztian Kiss, Anders Lindgren, Sofie Lassborn, Keith Drage, Stephen Hinton, Byron Campen, Avshalom Houri, Ben Campbell, Paul Kyzivat, Spencer Dawkins, Pasi Eronen, and Chris Newman for their valuable comments ๐ Lisa Dusseault critiqued the document during IESG review, raising numerous issues that resulted in improved document quality ๐ฅ And technical writer A. Jean Mahoney devoted countless hours to integrating Lisa's comments and cleaning up the technical English usage ๐
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.
- [RFC3261] Rosenberg, J., Schulzrinne, H., Camarillo, G., Johnston, A., Peterson, J., Sparks, R., Handley, M., and E. Schooler, "SIP: Session Initiation Protocol", RFC 3261, June 2002.
- [RFC3265] Roach, A., "Session Initiation Protocol (SIP)-Specific Event Notification", RFC 3265, June 2002.
- [RFC4825] Rosenberg, J., "The Extensible Markup Language (XML) Configuration Access Protocol (XCAP)", RFC 4825, May 2007.
- [RFC4826] Rosenberg, J., "Extensible Markup Language (XML) Formats for Representing Resource Lists", RFC 4826, May 2007.
- [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008.
- [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, August 2008.
- [RFC5261] Urpalainen, J., "An Extensible Markup Language (XML) Patch Operations Framework Utilizing XML Path Language (XPath) Selectors", RFC 5261, September 2008.
- [RFC5839] Niemi, A. and D. Willis, "An Extension to Session Initiation Protocol (SIP) Events for Conditional Event Notification", RFC 5839, May 2010.
- [RFC5874] Rosenberg, J. and J. Urpalainen, "An Extensible Markup Language (XML) Document Format for Indicating a Change in XML Configuration Access Protocol (XCAP) Resources", RFC 5874, May 2010.
9.2. Informative References ๐ง
- [RFC4918] Dusseault, L., "HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)", RFC 4918, June 2007.
- [RFC5263] Lonnfors, M., Costa-Requena, J., Leppanen, E., and H. Khartabil, "Session Initiation Protocol (SIP) Extension for Partial Notification of Presence Information", RFC 5263, September 2008.
- [W3C.REC-xml-20060816] Paoli, J., Bray, T., Yergeau, F., Maler, E., and C. Sperberg-McQueen, "Extensible Markup Language (XML) 1.0 (Fourth Edition)", World Wide Web Consortium FirstEdition REC-xml-20060816, August 2006,
http://www.w3.org/TR/2006/REC-xml-20060816.
Appendix A. Informative Examples ๐งโโ๏ธ
These examples show off the basic features of the xcap-diff event package ๐ Only the relevant header fields are shown. Also, the SIP request URIs in these examples don't correspond to reality, so don't go trying to call them ๐ญ
A.1. Initial Documents on an XCAP Server ๐ธ
The following documents exist on an XCAP server (xcap.example.com) with an imaginary "tests" application usage. There's no Default Document Namespace defined in this imaginary application usage โจ
http://xcap.example.com/tests/users/sip:joe@example.com/index:
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<note>This is a sample document</note>
</doc>
and then
http://xcap.example.com/tests/users/sip:john@example.com/index:
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<note>This is another sample document</note>
</doc>
A.2. An Initial Subscription ๐ฆ
The following shows the listing of collection contents, and it only shows resources where the user has read privileges ๐ Joe, whose XUI is "sip:joe@example.com", sends an initial subscription:
SUBSCRIBE sip:tests@xcap.example.com SIP/2.0
...
Accept: application/xcap-diff+xml
Event: xcap-diff; diff-processing=aggregate
Content-Type: application/resource-lists+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<resource-lists xmlns="urn:ietf:params:xml:ns:resource-lists">
<list>
<entry uri="tests/users/sip:joe@example.com/"/>
</list>
</resource-lists>
In addition to the 200 (OK) response, the notifier sends the first NOTIFY ๐
NOTIFY sip:joe@userhost.example.com SIP/2.0
...
Event: xcap-diff
Content-Type: application/xcap-diff+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<xcap-diff xmlns="urn:ietf:params:xml:ns:xcap-diff"
xcap-root="http://xcap.example.com/">
<document new-etag="7ahggs"
sel="tests/users/sip:joe@example.com/index"/>
</xcap-diff>
The subscriber learns that the document on this "tests" application usage is equivalent to its locally cached version, so it does not act ๐ If the local version had been different, the subscriber would most likely re-fetch the document ๐
If the subscriber had requested the "tests/users/" collection, the notification body would have been the same, since Joe has no read privileges to John's resources (XCAP default behavior) ๐
If the Expires header field had a value "0", the request would be similar to the PROPFIND method of WebDAV โจ The syntax and responses differ, however ๐ซถ
A.3. A Document Addition into a Collection
Okay so Joe adds a brand new document to his collection ๐โจ. He could use the same client or a different one on another device, bestie, it doesn't matter ๐ . He does an HTTP PUT to his application usage collection:
PUT /tests/users/sip:joe@example.com/another_document HTTP/1.1
Host: xcap.example.com
....
Content-Type: application/xcap-el+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<doc>
<note>This is another sample document</note>
</doc>
This HTTP PUT request results in the XCAP client receiving a strong HTTP ETag "terteer" for this new document ๐ท๏ธ.
Then the subscriber gets a notification afterwards ๐:
NOTIFY sip:joe@userhost.example.com SIP/2.0
...
Event: xcap-diff
Content-Type: application/xcap-diff+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<xcap-diff xmlns="urn:ietf:params:xml:ns:xcap-diff"
xcap-root="http://xcap.example.com/">
<document new-etag="terteer"
sel="tests/users/sip:joe@example.com/another_document"/>
</xcap-diff>
Note that the result is "additive" ๐ฆ. It doesn't indicate the already indicated "index" document. Only the initial (or refreshed) notification contains all document URI references ๐.
If Joe's client both modifies the documents and refreshes the subscriptions, it would typically ignore this notification, since its modifications had caused the notification ๐. If the client that received this NOTIFY hadn't submitted the document change, it would probably fetch this new document โจ.
If Joe's client refreshes the subscription with the same request body as in the initial subscription, the result will include these two documents: "index" and "another_document" with their ETags ๐.
A.4. A Series of XCAP Component Modifications
Now Joe's client uses its XCAP patching capability ๐ง by doing the following:
PUT /tests/users/sip:joe@example.com/index/~~/doc/foo HTTP/1.1
Host: xcap.example.com
....
Content-Type: application/xcap-el+xml
Content-Length: [XXX]
<foo>this is a new element</foo>
Since the insertion of the element is successful, Joe's client receives the new HTTP ETag "fgherhryt3" of the updated "index" document ๐ฅณ.
Immediately thereafter, Joe's client issues another HTTP request (this request could even be pipe-lined) ๐:
PUT /tests/users/sip:joe@example.com/index/~~/doc/bar HTTP/1.1
Host: xcap.example.com
....
Content-Type: application/xcap-el+xml
Content-Length: [XXX]
<bar>this is a bar element
</bar>
The reported new HTTP ETag of "index" is now "dgdgdfgrrr" ๐.
And Joe's client issues yet another HTTP request ๐ค:
PUT /tests/users/sip:joe@example.com/index/~~/doc/foobar HTTP/1.1
Host: xcap.example.com
....
Content-Type: application/xcap-el+xml
Content-Length: [XXX]
<foobar>this is a foobar element</foobar>
The reported new ETag of "index" is now "63hjjsll" ๐ธ.
After awhile, Joe's client receives a notification with an embedded patch ๐ฉน. It has requested "aggregate" diff-processing, and the notifier is capable of producing them ๐:
NOTIFY sip:joe@userhost.example.com SIP/2.0
...
Event: xcap-diff
Content-Type: application/xcap-diff+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<d:xcap-diff xmlns:d="urn:ietf:params:xml:ns:xcap-diff"
xcap-root="http://xcap.example.com/">
<d:document previous-etag="7ahggs3"
sel="tests/users/sip:joe@example.com/index"
new-etag="63hjjsll">
<d:add sel="*"
><foo>this is a new element</foo><bar>this is a bar element
</bar><foobar>this is a foobar element</foobar></d:add>
</d:document>
</d:xcap-diff>
Joe's client applies this patch to the locally cached "index" document, detects the ETag update, and stores the last ETag value ๐. Note how several XCAP component modifications were aggregated โจ.
Note also that, if Joe's client did not have a locally cached version of the reference document, it would have needed to do an HTTP GET request after the initial notification ๐ซฃ. If the ETag of the received resource by HTTP did not match either the previous or new ETag of this aggregated patch, an out-of-sync condition would be probable. This issue is not typical, but it can happen ๐. To resolve the issue, the client could re-fetch the "index" document and/or wait for subsequent notifications to detect a match. A better and simpler way to avoid the issue is to refresh the subscription with the "xcap-patching" mode and later refresh with the "aggregate" mode ๐ง .
Alternatively, if the notifier's operational mode had been "xcap-patching", the NOTIFY could have been the following ๐:
NOTIFY sip:joe@userhost.example.com SIP/2.0
...
Event: xcap-diff
Content-Type: application/xcap-diff+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<d:xcap-diff xmlns:d="urn:ietf:params:xml:ns:xcap-diff"
xcap-root="http://xcap.example.com/">
<d:document previous-etag="7ahggs"
sel="tests/users/sip:joe@example.com/index"
new-etag="fgherhryt3">
<d:add sel="*"
><foo>this is a new element</foo></d:add></d:document>
<d:document previous-etag="fgherhryt3"
sel="tests/users/sip:joe@example.com/index"
new-etag="dgdgdfgrrr">
<d:add sel="*"
><bar>this is a bar element
</bar></d:add></d:document>
<d:document previous-etag="dgdgdfgrrr"
sel="tests/users/sip:joe@example.com/index"
new-etag="63hjjsll">
<d:add sel="*"
><foobar>this is a foobar element</foobar></d:add></d:document>
</d:xcap-diff>
If the client had to re-fetch the "index" document after the initial notification, it could have skipped some or all of these patches, depending on whether the HTTP ETag matched some of these ETags in the chain of patches ๐งฉ. If the HTTP ETag did not match and the received HTTP version is a newer version indicated in later notification(s), the sync may then be achieved, since the notifier provided the full change history in the "xcap-patching" mode ๐.
Last, the notifier could (temporarily) fall back to the "no-patching" mode, which allows the notifier to keep the dialog alive when there are too many updates ๐ซถ:
NOTIFY sip:joe@userhost.example.com SIP/2.0
...
Event: xcap-diff
Content-Type: application/xcap-diff+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<xcap-diff xmlns="urn:ietf:params:xml:ns:xcap-diff"
xcap-root="http://xcap.example.com/">
<document previous-etag="7ahggs3"
sel="tests/users/sip:joe@example.com/index"
new-etag="63hjjsll"/>
</xcap-diff>
At any time, the notifier may fall back to the "no-patching" mode for some or all of the subscribed documents ๐.
A.5. An XCAP Component Subscription
The user Joe sends an initial subscription for the "id" attribute of a <doc> element ๐. The "index" document exists, but the <doc> root element does not contain the "id" attribute at the time of the subscription ๐.
SUBSCRIBE sip:tests@xcap.example.com SIP/2.0
...
Accept: application/xcap-diff+xml
Event: xcap-diff
Content-Type: application/resource-lists+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<resource-lists xmlns="urn:ietf:params:xml:ns:resource-lists">
<list>
<entry uri="tests/users/sip:joe@example.com/index/~~/doc/@id"/>
</list>
</resource-lists>
The first NOTIFY looks like the following, since there is nothing to indicate ๐ซง:
NOTIFY sip:joe@userhost.example.com SIP/2.0
...
Event: xcap-diff
Content-Type: application/xcap-diff+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<xcap-diff xmlns="urn:ietf:params:xml:ns:xcap-diff"
xcap-root="http://xcap.example.com/"/>
Note that if the "index" document hadn't existed, the first NOTIFY request would have been the same. The XCAP diff document format doesn't indicate reasons for non-existing resources ๐คทโโ๏ธ.
Afterwards, Joe's client updates the whole document root element, including the attribute "id". This is not a typical XCAP operation, or a preferred one, just an illustration here ๐ง:
PUT /tests/users/sip:joe@example.com/index/~~/doc HTTP/1.1
Host: xcap.example.com
....
Content-Type: application/xcap-el+xml
Content-Length: [XXX]
<doc id="bar">This is a new root element</doc>
The new HTTP ETag of the "index" document is now "dwawrrtyy" ๐ท๏ธ.
Then Joe's client gets a notification ๐:
NOTIFY sip:joe@userhost.example.com SIP/2.0
...
Event: xcap-diff
Content-Type: application/xcap-diff+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<xcap-diff xmlns="urn:ietf:params:xml:ns:xcap-diff"
xcap-root="http://xcap.example.com/">
<attribute sel="tests/users/sip:joe@example.com/index/~~/doc/@id"
>bar</attribute>
</xcap-diff>
Note that the HTTP ETag value of the new document is not shown, as it is irrelevant for this use-case ๐.
Then Joe's client removes the "id" attribute ๐๏ธ:
DELETE /tests/users/sip:joe@example.com/index/~~/doc/@id HTTP/1.1
Host: xcap.example.com
....
Content-Length: 0
And the subscriber gets a notification ๐ณ:
NOTIFY sip:joe@userhost.example.com SIP/2.0
...
Event: xcap-diff
Content-Type: application/xcap-diff+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<xcap-diff xmlns="urn:ietf:params:xml:ns:xcap-diff"
xcap-root="http://xcap.example.com/">
<attribute sel="tests/users/sip:joe@example.com/index/~~/doc/@id"
exists="0"/>
</xcap-diff>
The notification indicates that the subscribed attribute was removed from the document โจ. Naturally, attributes are "removed" if the element where they belong is removed, for example, by an HTTP DELETE request ๐ . The component selections indicate only the existence of attributes or elements ๐ธ.
A.6. A Conditional Subscription ๐
Okay, the last example is a conditional subscription ๐ฆ, and it's lowkey the coolest one. You can skip a full refresh when nothing in the resources has changed โจ. Joe's client starts with an initial subscription:
SUBSCRIBE sip:tests@xcap.example.com SIP/2.0
...
Accept: application/xcap-diff+xml
Event: xcap-diff; diff-processing=xcap-patching
Content-Type: application/resource-lists+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<resource-lists xmlns="urn:ietf:params:xml:ns:resource-lists">
<list>
<entry uri="tests/users/sip:joe@example.com/"/>
</list>
</resource-lists>
Now there are two documents in the repository ๐, so the first NOTIFY looks like this ๐:
NOTIFY sip:joe@userhost.example.com SIP/2.0
...
Event: xcap-diff
SIP-ETag: xggfefe54
Content-Type: application/xcap-diff+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<xcap-diff xmlns="urn:ietf:params:xml:ns:xcap-diff"
xcap-root="http://xcap.example.com/">
<document new-etag="63hjjsll"
sel="tests/users/sip:joe@example.com/index"/>
<document new-etag="terteer"
sel="tests/users/sip:joe@example.com/another_document"/>
</xcap-diff>
Look at that SIP-ETag xggfefe54 in the NOTIFY ๐. It gets copied into the Suppress-If-Match header field of the conditional subscription, and that's the whole trick ๐ง. The diff-processing mode also changes (or gets requested to change) ๐:
SUBSCRIBE sip:tests@xcap.example.com SIP/2.0
...
Suppress-If-Match: xggfefe54
Accept: application/xcap-diff+xml
Event: xcap-diff; diff-processing=aggregate
Content-Type: application/resource-lists+xml
Content-Length: [XXX]
<?xml version="1.0" encoding="UTF-8"?>
<resource-lists xmlns="urn:ietf:params:xml:ns:resource-lists">
<list>
<entry uri="tests/users/sip:joe@example.com/"/>
</list>
</resource-lists>
If the notifier finds a match to the previous stored state when it checks this request, it replies with 204 (No Notification) ๐
โโ๏ธ. If there are no reportable changes as per [RFC5839], NOTIFY request generation is suppressed, so nothing gets sent at all ๐คซ. When the notifier can aggregate several modifications, this re-subscription turns on that mode from then on ๐ฅ. Heads up though: the re-subscription can be kinda process-intensive ๐ญ, especially when there are a large number of relevant reported resources.
Authors' Addresses ๐
Two lovely people wrote this one, so here are their contact details ๐:
Jari Urpalainen
Nokia
Itamerenkatu 11-13
Helsinki 00180
Finland
Phone: +358 7180 37686
EMail: jari.urpalainen@nokia.com
Dean Willis (editor)
Softarmor Systems LLC
3100 Independence Pk #311-164
Plano, TX 75075
USA
Phone: +1 214 504 19876
EMail: dean.willis@softarmor.com
๐ฆ where this page comes from
- ietf: rfc5875 2010-05
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms