<abstract>This specification defines an XMPP protocol extension for generic publish-subscribe functionality. The protocol enables XMPP entities to create nodes (topics) at a pubsub service and publish information at those nodes; an event notification (with or without payload) is then broadcasted to all entities that have subscribed to the node. Pubsub therefore adheres to the classic Observer design pattern and can serve as the foundation for a wide variety of applications, including news feeds, content syndication, rich presence, geolocation, workflow systems, network management systems, and any other application that requires event notifications.</abstract>
<li>Described the use of Result Set Management to return some but not all published items.</li>
<li>More clearly defined terminology related to deployment scenarios for collection nodes, with some borrowings from graph theory.</li>
<li>Corrected syntax for associating with and disassociating from a collection node so that it is possible to perform these tasks in relation to the root collection node.</li>
<li>Added note about ignoring delivery options set for configuration of a collection node and instead applying delivery options as configured for the publishing leaf node.</li>
<li>Defined handling of collection node deletion for various deployment scenarios.</li>
<remark><p>For collection nodes, changed name of node child element to associate and added disassociate child element to handle disassociation use case; corrected SHIM examples to conform to XEP-0131; modified lease expiry notification for consistency with other subscription-related notifications (i.e., not using SHIM header); renamed SHIM headers to Collection and SubID for consistency with HTTP and Email headers.</p></remark>
<li>In accordance with XMPP Council consensus, moved the auto-create, auto-subscribe, filtered-notifications, and last-published features from XEP-0163 to this specification</li>
<li>Clarified implications of auto-subscribe feature for handling of account owners, stable presence subscribers, and transient presence sharers</li>
<li>Updated filtered-notifications text and examples to track changes to XEP-0115</li>
<li>Added publish-options functionality</li>
<li>Added developer-friendly How It Works section</li>
<li>Replaced boolean send_item_subscribe node configuration option with more comprehensive send_last_published_item option per list discussion</li>
<li>Added deliver_notifications node configuration option to enable quiet nodes without notifications, if desired enabling pull-model item retrieval only.</li>
<li>Modified subscription and affiliation retrieval to return empty element if no results.</li>
</ul>
</remark>
</revision>
<revision>
<version>1.8</version>
<date>2006-06-27</date>
<initials>psa</initials>
<remark>
<ul>
<li>Defined five access models: open, presence, roster, authorize, and whitelist</li>
<li>Renamed pubsub#subscription_model feature to pubsub#access_model</li>
<li>Separated affiliations retrieval from subscriptions retrieval</li>
<li>Removed subscription information from affiliations management</li>
<li>Changed <entity/> element to <subscription/> element in response to subscription request</li>
<li>Clarified batch processing of item publication and item deletion</li>
<li>Added basic example to introduction</li>
<li>More fully specified node creation flows</li>
<li>More fully specified recommended behavior for caching last published item, including use of jabber:x:delay protocol</li>
<li>Specified that semantic meaning of NodeIDs must not be used to encapsulate hierarchy</li>
<li>More fully specified error conditions</li>
<li>Changed some feature-related conditions to <unsupported/> plus feature attribute</li>
<li>Changed some error conditions from <not-authorized/> to <forbidden/></li>
<li>Harmonized error conditions for unsubscribe if entity is not subscribed (unexpected-request rather than not-found)</li>
<li>Further defined error conditions related to item publication</li>
<li>Specified structure of <affiliations/>, <delete/>, <purge/>, and <subscriptions/> elements qualified by pubsub#owner namespace</li>
<li>Changed retrieval of default configuration options to use <default/> element, not <configure/> element</li>
<li>Allowed caching of last published item</li>
<li>Added pubsub#deliver subscription option</li>
<li>Added meta-data fields for pubsub#owners and pubsub#contact</li>
<li>Changed element for retrieval of default node configuration options from <configure/> to <default/> to prevent ambiguity related to configuration of root collection node</li>
<li>Specified conformance with Resourceprep for nodes addressable as JIDs</li>
<li>Added pubsub#modify-affiliations feature</li>
<li>Added pubsub#digest_frequency field to subscribe_options FORM_TYPE</li>
<li>Added pubsub#roster_groups_allowed field to node_config FORM_TYPE</li>
<li>More clearly specified the requirements level (MUST, SHOULD, MAY) for each service discovery feature</li>
<li>Defined pubsub#include_body subscription option and the pubsub#body_xslt node configuration option to transform payload format into an XMPP message body, and clarified rules for inclusion of message bodies</li>
<li>Clarified nature of collections and association of a node to a collection</li>
<li>Specified that simultaneous subscriptions of type nodes and items are allowed to collection nodes</li>
<li>Added examples and further explanation of time-based and content-based subscriptions</li>
<li>Reinstated pubsub#subscribe feature (deleted in error)</li>
<li>Added type attribute for the <create/> and <configure/> elements to differentiate between leaf nodes and collection nodes</li>
<li>In Section 8.1.7, changed affiliations retrieval support to SHOULD and added pubsub#retrieve-affiliations feature</li>
<li>In Section 8.1.10, removed two duplicate examples</li>
<li>In Section 8.1.12, clarified relationship between normal disco#info data and node meta-data (which uses a service discovery extension)</li>
<li>In Section 8.2.4, specified that node purgation MUST result in one event notification, not a notification per item</li>
<li>In Section 8.1.8, further specified handling of SubIDs</li>
<li>Clarified nature of the pubsub#type field</li>
<li>Mentioned that the forbidden error should be returned in response to certain operations requested by an outcast</li>
<li>Corrected datatype of max_items attribute from xs:string to xs:positiveInteger</li>
<li>Corrected <requesting-entity-not-subscribed/> error to <not-subscribed/> since the subscribed JID need not be that of the requesting entity</li>
<li>Added service discovery features for more optional use cases: retracting items, purging nodes, deleting nodes</li>
<li>Updated relevant registries</li>
</ul>
</remark>
</revision>
<revision>
<version>1.6</version>
<date>2004-07-13</date>
<initials>pgm/psa</initials>
<remark><p>Added service discovery features for pubsub#meta-data, and pubsub#retrieve-items. Added pubsub#subscription_depth configuration option. Specified pubsub-specific error condition elements qualified by pubsub#errors namespace.</p></remark>
<remark><p>Fixed typos. Added more details to the section on collections. Added paragraph to create node use case to allow the service to change the requested node-id to something which it creates. Added text about bouncing publish requests when the request does not match the event-type for that node. Added disco features for the jabber registrar. Changed affiliation verbiage to allow publishers to remove any item. Tweaked verbiage for create node, eliminated extra example. Fully defined XMPP Registrar submissions. Corrected schemas.</p></remark>
<remark><p>Added subid syntax in a variety of places. Added more information about disco#info and disco#items support. Added more info about subscription options. Added collection information. Added implementation notes about subscription leases, and content-based pubsub services.</p></remark>
</revision>
<revision>
<version>1.3</version>
<date>2004-04-25</date>
<initials>psa</initials>
<remark><p>Editorial review; added one implementation note.</p></remark>
<remark><p>Per a vote of the Jabber Council, advanced status to Draft.</p></remark>
</revision>
<revision>
<version>0.16</version>
<date>2003-10-23</date>
<initials>pgm</initials>
<remark><p>Clarified JID addressing usage for nodes. Added specific MAY requirement for disco usage. Added sentence about implementations verifying that an entity has a subscription before getting the current items.</p></remark>
</revision>
<revision>
<version>0.15</version>
<date>2003-10-21</date>
<initials>pgm</initials>
<remark><p>Fixed invalid XML in examples for subscription deny/allow.</p></remark>
</revision>
<revision>
<version>0.14</version>
<date>2003-10-21</date>
<initials>pgm</initials>
<remark><p>Clarified restrictions on addressing nodes by JID. Added section on Approving and Denying Subscription Requests. Changed get-pending to use Ad-Hoc Commands. Changed semantics when sending in a form type='cancel' for pending subscriptions.</p></remark>
</revision>
<revision>
<version>0.13</version>
<date>2003-09-30</date>
<initials>pgm</initials>
<remark><p>Removed item as a possible child of subscribe and unsubscribe and pubsub in the schemas. Removed retract as a possible child of item in the pubsub#event schema. Added verbiage to requirements for addressing nodes either via JIDs or disco nodes.</p></remark>
<remark><p>Defined public vs. private nodes; described how changes to existing nodes might trigger meta-node events (e.g., configuration changes); changed <x/> to <event/> for #events namespace; added meta-data about meta-nodes; fully defined XMPP Registrar considerations.</p></remark>
<remark><p>Removed subscription notifications since they have inherent issues. Removed empty implementation note sub-section.</p></remark>
</revision>
<revision>
<version>0.10</version>
<date>2003-06-11</date>
<initials>pgm</initials>
<remark><p>Fixed error example when returning 501 from an items-get request. Added note about receiving subscription requests when an entity is already subscribed. Fixed some entity elements in various subscription examples. Many were missing the node attribute. Added subscription change notification verbiage and example. Added verbiage and example of subscription state notification being sent to the requesting entity. Added disco#items information for getting a list of item identifiers for a single node. Added verbiage for returning the current entity element when a curent subscriber attempts to subscribe again.</p></remark>
</revision>
<revision>
<version>0.9</version>
<date>2003-04-30</date>
<initials>pgm</initials>
<remark><p>Include JID attributes in the entity elements when receiving your affiliations. Changed error code 406 (which was wrong) to 404, which is correct. Changed many 405 errors to 401, and modified the error table to make it more implementable (rules are more concrete). Added subscribe-options element for indicating subscriptions may be configured.</p></remark>
<remark><p>Clarified the affiliations table and the semantics around subscribing and unsubscribing. Added protocol to get all of your affiliations in the service. Added protocol for services informing subscribers that configurable subscription options are available. Added protocol for obtaining existing node configuration settings and for concatenating configuration and node creation requests into a single stanza. Added meta-node implementation notes and specified the interaction with the XMPP Registrar and the meta NodeIDs. Added authorization notes to subscription options.</p></remark>
<remark><p>Clarified requirements around what affiliations must be supported. Moved requirements about specifying entities which can subscribe and publish out of the MUSTs to MAYs. Changed SHOULD to MAY when talking about allowing entities to create nodes. Added ability to send configuration requests in the same stanza as a creation request.</p></remark>
</revision>
<revision>
<version>0.6</version>
<date>2003-02-06</date>
<initials>pgm</initials>
<remark><p>Added more details and an example about publishing without NodeID. Added more implementation notes about NodeIDs and persistent storage.</p></remark>
</revision>
<revision>
<version>0.5</version>
<date>2003-01-22</date>
<initials>pgm</initials>
<remark><p>Fixed header for delete item example. Added examples showing subscribers being notified of deleted items. Added examples for notification of node deletion, and configuration for node deletion. Added Subscriber option semantics and examples. Added examples for 402 and 407 errors on subscribe and create respectively. Added clarification about ItemID handling to impl notes.</p></remark>
<remark><p>Clarified in-band and out-of-band configuration requirement. Added Delete Item privilege for all affiliations to the table. Added Delete item protocol for publishers and owners. Added 401 error case for subscribing to an illegal jid. Changed subscription request form. Added defaults to configuration form, and clarified role of the XMPP Registrar for the features show. Added text explaining the max_items attribute. Changed "last items" to "most recent items". Removed default configuration acceptance -- owners should just cancel. Added the notify_retract configuration option. Clarified error handling for affiliation modifications. </p></remark>
<remark><p>Added subscription attribute for entities. Removed subscriber from the affiliations table. Clarified configuration details. Clarified JabberID usages. Added XMPP Registrar Considerations. Added link to XEP-0068 about the FORM_TYPE element in subscription request notifications. Fixed some typos in examples. Added unsupported configuration namespace to example. Added a default configuration example. </p></remark>
<remark><p>Added numerous implementation notes; added get-pending action with regard to subscriptions; added error table; changed purge and delete to use IQ type='set'.</p></remark>
<p>As Jabber/XMPP technologies have matured, the need for a generic publish-subscribe ("pubsub") mechanism has arisen in a number of domains. These include (but are not limited to): news feeds, content syndication, extended presence, geolocation, avatar management, shared bookmarks, auction and trading systems, workflow systems, network management systems, NNTP gateways, profile management, and any other application that requires event notifications.</p>
<p>In all of these domains, it is desirable for data communication to follow the classic "publish-subscribe" or "observer" design pattern: a person or application publishes information, and an event notification (with or without payload) is broadcasted to all authorized subscribers. In general, the relationship between the publisher and subscriber is mediated by a service that receives publication requests, broadcasts event notifications to subscribers, and enables privileged entities to manage lists of people or applications that are authorized to publish or subscribe. In most pubsub services, the focal point for publication and subscription is a "topic" or "node" to which publishers send data and from which subscribers receive notifications. Additionally, some nodes may also maintain a history of events and provide other services that supplement the pure pubsub model.</p>
<p>This document defines a single, cohesive, generic protocol that all forms of pubsub can use. While compliant implementations are not required to implement all of the features defined herein, this document addresses most use cases that may be requested of a pubsub service. (For information about which features are required and which are recommended or optional, consult the <linkurl='#features'>Feature Summary</link>.) Other specifications may define "subsets" or "profiles" of publish-subscribe for use in specialized contexts, but such profiles are out of scope for this document.</p>
<section2topic='How It Works'anchor='intro-howitworks'>
<p>This specification is large. However, the basic idea behind pubsub is rather simple (see <linkurl='#publisher-publish'>Publish an Item to a Node</link>):</p>
<ol>
<li>An entity publishes information to a node at a publish-subscribe service.</li>
<li>The pubsub service pushes a notification to all entities that are authorized to learn about the published information.</li>
</ol>
<p>Perhaps the most popular application of pubsub-like functionality is content syndication, which has become familiar from the RSS and Atom (&rfc4287;) feeds associated with weblogs, news sites, and other frequently-updated information available on the Internet. Consider the example of a weblog published by <hamlet@denmark.lit>. When Hamlet writes a new weblog entry, his blogging software publishes the entry to a pubsub node hosted at <pubsub.shakespeare.lit>:</p>
<p>Naturally, the entities involved may need to complete other use cases in order to enable full pubsub functionality -- for example, the publisher may need to create the node (see <linkurl='#owner-create'>Create a Node</link>) and subscribers may need to sign up for notifications (see <linkurl='#subscriber-subscribe'>Subscribe to a Node</link>). These use cases are fully described in the remainder of this document. (For information about which features are required and which are recommended or optional, consult the <linkurl='#features'>Feature Summary</link>.)</p>
<p>The following terms are used throughout this document to refer to elements, objects, or actions that occur in the context of a pubsub service. (Note: Some of these terms are specified in greater detail within the body of this document.)</p>
<tablecaption='Publish-Subscribe Terms'>
<tr><td>Authorize Access Model</td><td>A node access model under which an entity can subscribe only through having a subscription request approved by a node owner (subscription requests are accepted but only provisionally) and only subscribers may retrieve items.</td></tr>
<tr><td>Collection Node</td><td>A type of node that contains nodes and/or other collections but no published items. Collections make it possible to represent hierarchial node structures.</td></tr>
<tr><td>Event</td><td>A change in the state of a node.</td></tr>
<tr><td>Instant Node</td><td>A node whose NodeID is automatically generated by a pubsub service.</td></tr>
<tr><td>Item</td><td>An XML fragment which is published to a node, thereby generating an event.</td></tr>
<tr><td>ItemID</td><td>A unique identifier for an item in the context of a specific node.</td></tr>
<tr><td>Leaf Node</td><td>A type of node that contains published items only. It is NOT a container for other nodes.</td></tr>
<tr><td>Node</td><td>A virtual location to which information can be published and from which event notifications and/or payloads can be received (in other pubsub systems, this may be labelled a "topic").</td></tr>
<tr><td>NodeID</td><td>The unique identifier for a node within the context of a pubsub service. The NodeID is either supplied by the node creator or generated by the pubsub service (if the node creator requests an Instant Node). The NodeID MAY have semantic meaning, but such meaning is OPTIONAL.</td></tr>
<tr><td>Notification</td><td>A message sent to a subscriber informing them of an event.</td></tr>
<tr><td>Outcast</td><td>An entity that is disallowed from subscribing or publishing to a node.</td></tr>
<tr><td>Owner</td><td>The manager of a node, of which there may be more than one; often but not necessarily the node creator.</td></tr>
<tr><td>Payload</td><td>The full data associated with an event rather than just the event notification itself.</td></tr>
<tr><td>Open Access Model</td><td>A node access model under which any entity may subscribe and retrieve items without approval.</td></tr>
<tr><td>Personal Eventing</td><td>A simplified subset of Publish-Subscribe for use in the context of instant messaging and presence applications, whereby each IM user's JID is a virtual pubsub service; for details, see &xep0163;.</td></tr>
<tr><td>Presence Access Model</td><td>A node access model under which any entity that is subscribed to the owner's presence with a subscription of type "from" or "both" (see &rfc3921;) may subscribe to the node and retrieve items from the node; this access model applies mainly to instant messaging systems.</td></tr>
<tr><td>Publisher</td><td>An entity that is allowed to publish items to a node.</td></tr>
<tr><td>Pubsub Service</td><td>An XMPP server or component that adheres to the protocol defined herein.</td></tr>
<tr><td>Roster Access Model</td><td>A node access model under which any entity that is subscribed to the owner's presence and in the specified roster group(s) may subscribe to the node and retrieve items from the node; this access model applies mainly to instant messaging systems.</td></tr>
<tr><td>Subscriber</td><td>An entity that is subscribed to a node.</td></tr>
<tr><td>Whitelist Access Model</td><td>A node access model under which an entity may subscribe and retrieve items only if explicitly allowed to do so by the node owner (subscription requests from unauthorized entities are rejected).</td></tr>
<p>Requirements for a pubsub service can be driven by end-user needs as well as the needs of other components and services which can use the service. First, a pubsub service implemented using Jabber MUST provide the basic features that implement a pure publish-subscribe pattern:</p>
<li>An entity MUST be able to publish events to a service such that all subscribers to a node receive notification of the event. See <linkurl='#publisher-publish'>Publish an Item to a Node</link>.</li>
<li>An entity MUST be able to subscribe to a node (or be informed that subscription is not allowed). See <linkurl='#subscriber-subscribe'>Subscribe to a Node</link>.</li>
<li>An entity MUST be allowed to be affiliated with a node. Allowable affiliations are owner, publisher, none, and outcast. Implementations MUST support affiliations of owner and none, and MAY support affiliations of outcast and publisher. See <linkurl='#affiliations'>Affiliations</link>.</li>
<li>An entity MUST be allowed to query the pubsub service (or a specific node) to determine what optional features of this specification the service (or node) implements. This query MUST use the Service Discovery (disco#info) protocol. See <linkurl='#entity-info'>Discover Node Information</link>.</li>
<!-- =================== MAYS and SHOULDS =================== -->
<p>Some of the possible uses of a Jabber-based pubsub service will require other features, but these features are OPTIONAL and therefore not mandatory for compliance with this specification. However, if these features are implemented, they MUST adhere to the protocol described herein in to be compliant. These features include:</p>
<li>A service MAY cache the last item published to a node (even if the "persistent-items" option is set to false); if it does default "cache-last-item" to true, it SHOULD send the last published item (or notification thereof) to subscribed entities based on configuration of the "send_last_published_item" field.</li>
<p>Support for the "owner" and "none" affiliations is REQUIRED. Support for all other affiliations is RECOMMENDED. For each non-required affiliation supported by an implementation, it SHOULD return a service discovery feature of "name-affiliation" where "name" is the name of the affiliation, such as "member", "outcast", or "publisher" (see the <linkurl='#features'>Feature Summary</link>). Particular kinds of pubsub services MAY enforce additional requirements (e.g., requiring support for a given non-required affiliation or for all affiliations).</p>
<p>* Note: A service MAY allow any publisher to delete any item once it has been published to that node instead of allowing only the original publisher to remove it (this is discoverable via the "pubsub#delete-any" feature).</p>
<p>The ways in which an entity changes its affiliation with a node are well-defined. Typically, action by an owner is required to make an affiliation state transition. Affiliation changes and their triggering actions are specified in the following table.</p>
<p>Subscriptions to a node may exist in several states.</p>
<tablecaption='Subscription States'>
<tr>
<th>Subscription State</th>
<th>Description</th>
</tr>
<tr>
<td>None</td>
<td>The node MUST NOT send event notifications or payloads to the Entity.</td>
</tr>
<tr>
<td>Pending</td>
<td>An entity has requested to subscribe to a node and the request has not yet been approved by a node owner. The node MUST NOT send event notifications or payloads to the entity while it is in this state.</td>
</tr>
<tr>
<td>Unconfigured</td>
<td>An entity has subscribed but its subscription options have not yet been configured. The node MAY send event notifications or payloads to the entity while it is in this state. The service MAY timeout unconfigured subscriptions.</td>
<td>An entity is subscribed to a node. The node MUST send all event notifications (and, if configured, payloads) to the entity while it is in this state (subject to subscriber configuration and content filtering).</td>
<p>The requirements for the publish-subscribe protocol imply that there are two major dimensions along which we can measure events: persistent vs. transient, and pure notification vs. inclusion of payload. An implementation SHOULD enable an owner to configure a node along both of these dimensions.</p>
<p>No matter whether a node is configured for persistent or transient events, a service MAY cache the last item published to the node, in which case it SHOULD send that item to subscribers based on configuration of the "send_last_published_item" option (see the <linkurl='#impl-caching'>Item Caching</link> section of this document); if the service supports the "http://jabber.org/protocol/pubsub#last-published" feature then the value of this option MUST default to "on_sub_and_presence" (though the service SHOULD allow the node owner to override the default).</p>
<p>A pubsub service MUST validate publish requests against the configuration of the node along both of these dimensions (see the <linkurl='#publisher-publish'>Publish An Item to a Node</link> section of this document for the relevant error conditions).</p>
<p>The node configuration and desired event type determine whether an item must be provided by the publisher, whether the item includes a payload in the publish request or notification, and whether an item ID is provided by the publisher or generated by the pubsub service. We can summarize the relevant rules as follows:</p>
<td>Publish request MUST include an &ITEM; element, which MAY be empty or MAY contain a payload; even if publish request contains a payload, pubsub service MUST NOT include the payload in notifications; if publish request did not include item ID, pubsub service MUST generate item ID</td>
<td>Publish request MUST include an &ITEM; element, which SHOULD contain a payload; if publish request included a payload, notifications MUST include the payload; if publish request did not include item ID, pubsub service MUST generate item ID</td>
<td>Publish request MUST NOT include an &ITEM; element; payload is not included in publish request or notifications, although notifications MUST include an empty &ITEMS; element; item ID is neither provided in publish request nor generated by pubsub service</td>
<td>Publish request MUST include an &ITEM; element, which SHOULD contain a payload; if publish request included a payload, notifications MUST include the payload; pubsub service MAY generate an item ID</td>
<td>A node that contains published items only. It is NOT a container for other nodes. This is the most common node type.</td>
</tr>
<tr>
<td>Collection</td>
<td>A node that contains nodes and/or other collections but no published items. Collections make it possible to represent hierarchial node structures.</td>
<p>In order to make node creation simpler for clients, we define the following node access models (in order of openness):</p>
<tablecaption='Node Access Models'>
<tr>
<th>Access Model</th>
<th>Description</th>
</tr>
<tr>
<td>Open</td>
<td>Any entity may subscribe to the node (i.e., without the necessity for subscription approval) and any entity may retrieve items from the node (i.e., without being subscribed); this SHOULD be the default access model for generic pubsub services.</td>
</tr>
<tr>
<td>Presence</td>
<td>Any entity with a subscription of type "from" or "both" may subscribe to the node and retrieve items from the node; this access model applies mainly to instant messaging systems (see <cite>RFC 3921</cite>).</td>
</tr>
<tr>
<td>Roster</td>
<td>Any entity in the specified roster group(s) may subscribe to the node and retrieve items from the node; this access model applies mainly to instant messaging systems (see <cite>RFC 3921</cite>).</td>
</tr>
<tr>
<td>Authorize</td>
<td>The node owner must approve all subscription requests, and only subscribers may retrieve items from the node.</td>
<td>An entity may subscribe or retrieve items only if on a whitelist managed by the node owner. The node owner MUST automatically be on the whitelist. In order to add entities to the whitelist, the node owner SHOULD use the protocol specified in the <linkurl='#owner-affiliations'>Manage Affiliated Entities</link> section of this document, specifically by setting the affiliation to "member".</td>
<p>A generic publish-subscribe implementation SHOULD support all of the defined access models, although specialized publish-subscribe implementations MAY support only a subset of the access models. Which access models are provided in a particular deployment is a matter of service provisioning (e.g., some restricted deployments may wish to lock down permissions so that only the "authorize" and "whitelist" access models are provided, or even only the "whitelist" access model).</p>
<p>A node creator or owner can override the default access model by specifying an appropriate value for the 'pubsub#access_model' configuration field (see the <linkurl='#owner-create'>Create a Node With Default Configuration</link> and <linkurl='#owner-configure'>Configure a Node</link> sections of this document).</p>
<p>If a pubsub node is addressable, it MUST be addressable either (1) as a JID or (2) as the combination of a JID and a node. <note>These nodes are equivalent to those used in <cite>XEP-0030: Service Discovery</cite>.</note></p>
<p>If a pubsub node is addressable as a JID, the NodeID MUST be the resource identifier, and MUST NOT be specified by the "user" portion (node identifier) of the JID (e.g. "domain.tld/NodeID" and "user@domain.tld/NodeID" are allowed; "NodeID@domain.tld" is not allowed <note>This rule does not apply to the root collection node, if any.</note>). JID addressing SHOULD be used when interacting with a pubsub node using a protocol that does not support the node attribute. For example, when a service makes it possible for entities to subscribe to nodes via presence, it would address nodes as JIDs. If a pubsub node is addressable as a JID, the pubsub service MUST ensure that the NodeID conforms to the Resourceprep profile of Stringprep as described in <cite>RFC 3920</cite>.</p>
<p>If a pubsub node is addressable as a JID plus node, the NodeID MUST be the value of both the Service Discovery 'node' attribute and the pubsub 'node' attribute; i.e., for discovery purposes, a pubsub node is equivalent to a Service Discovery node. If a pubsub node is addressable as a JID plus node, the pubsub service SHOULD ensure that the NodeID conforms to the Resourceprep profile of Stringprep as described in <cite>RFC 3920</cite>.</p>
<p>Consider the following example, in which the (virtual) pubsub service is located at hamlet@denmark.lit.</p>
<examplecaption='Node addressed as JID+NodeID'><![CDATA[
<iqto='hamlet@denmark.lit'>
<querynode='princely_musings'/>
</iq>
]]></example>
</section3>
</section2>
</section1>
<section1topic='Entity Use Cases'anchor='entity'>
<p>This section defines the use cases for and protocols to be used by any entity that wishes to interact with a publish-subscribe service, mainly focused on Service Discovery use cases.</p>
<p>A service MUST respond to service discovery information requests qualified by the 'http://jabber.org/protocol/disco#info' namespace. The "disco#info" result returned by a pubsub service MUST indicate the identity of the service and indicate which pubsub features are supported.</p>
<examplecaption='Entity Queries Pubsub Service Regarding Supported Features'><![CDATA[
<p>The possible pubsub features are noted throughout this document and have been registered as described in the <linkurl='#registrar'>XMPP Registrar Considerations</link> section of this document. For information regarding which features are required, recommended, and optional, see the <linkurl='#features'>Feature Summary</link> section of this document.</p>
<p>If a service implements a hierarchy of nodes (by means of <linkurl='#collections'>Collection Nodes</link>), it MUST also enable entities to discover the nodes in that hierarchy by means of the <strong>Service Discovery</strong> protocol, subject to the recommendations in <cite>XEP-0030</cite> regarding large result sets (for which &xep0055; or some other protocol SHOULD be used). The following examples show the use of service discovery in discovering the nodes available at a hierarchical pubsub service.</p>
<p>Note: Node hierarchies and collection nodes are OPTIONAL. For details, refer to the <linkurl='#impl-semantics'>NodeID Semantics</link> and <linkurl='#collections'>Collection Nodes</link> sections of this document.</p>
<p>In the first example, an entity sends a service discovery items ("disco#items") request to the root node (i.e., the service itself), which is a <linkurl='#collections'>Collection Node</link>:</p>
<p>If a node is a leaf node rather than a collection node and items have been published to the node, the service MAY return one &ITEM; element for each published item as described in the <linkurl='#entity-discoveritems'>Discover Items for a Node</link> section of this document, however such items MUST NOT include a 'node' attribute (since they are published items, not nodes).</p>
<p>A pubsub service MUST allow entities to query individual nodes for the information associated with that node. The Service Discovery protocol MUST be used to discover this information. The "disco#info" result MUST include an identity with a category of "pubsub" and a type of either "leaf" or "collection".</p>
<p>Note: If a node has an identity type of "leaf", then it MUST NOT contain other nodes or collections (only items); if a node has an identity type of "collection", then it MUST NOT contain items (only other nodes or collections).</p>
<examplecaption='Entity queries collection node for information'><![CDATA[
<p>The "disco#info" result MAY include detailed meta-data about the node, encapsulated in the &xep0004; format as described in &xep0128;, where the data form context is specified by including a FORM_TYPE of "http://jabber.org/protocol/pubsub#meta-data" in accordance with &xep0068;. If meta-data is provided, it SHOULD include values for all configured options as well as "automatic" information such as the node creation date, a list of publishers, and the like.</p>
<fieldvar='pubsub#contact'label='People to contact with questions'>
<value>bard@shakespeare.lit</value>
</field>
<fieldvar='pubsub#owner'label='Node owners'>
<value>hamlet@denmark.lit</value>
</field>
<fieldvar='pubsub#publisher'label='Publishers to this node'>
<value>hamlet@denmark.lit</value>
</field>
<fieldvar='pubsub#num_subscribers'label='Number of subscribers to this node'>
<value>1066</value>
</field>
</x>
</query>
</iq>
]]></example>
<p>Note: Node meta-data can be set in many ways. Some of it is based on node configuration (e.g., the owner's JID) whereas some of it may be dynamic (e.g., the number of subscribers). Any static information to be provided in the node meta-data SHOULD be provided as fields in the node configuration form.</p>
<p>Much of the meta-data provided about a node maps directly to selected &DUBLINCORE; meta-data attributes; specifically:</p>
<tr><td>pubsub#creation_date</td><td>Date <note>The value SHOULD be a DateTime as defined in <cite>XEP-0082</cite>, and MUST conform to one of the profiles defined therein.</note></td></tr>
<tr><td>pubsub#type</td><td>Type <note>The pubsub type SHOULD be the namespace that defines the payload (such as 'http://www.w3.org/2005/Atom'), if payloads are supported.</note></td></tr>
</table>
</section2>
<section2topic='Discover Items for a Node'anchor='entity-discoveritems'>
<p>To discover the published items which exist on the service for a specific node, an entity MAY send a "disco#items" request to the node itself, and the service MAY return each item as a Service Discovery &ITEM; element. The 'name' attribute of each Service Discovery item MUST contain its ItemID and the item MUST NOT possess a 'node' attribute. This ItemID MAY then be used to retrieve the item using the protocol defined in the <linkurl='#subscriber-retrieve'>Retrieve Items from a Node</link> section of this document.</p>
<examplecaption='Entity requests all of the items for a node'><![CDATA[
<p>An entity may want to query the service to retrieve its subscriptions for all nodes at the service. Support for this feature ("retrieve-subscriptions") is RECOMMENDED.</p>
<p>In order to make the request, the requesting entity MUST send an IQ-get whose &PUBSUB; child contains an empty <subscriptions/> element with no attributes.</p>
<p>If the service returns a list of subscriptions, it MUST return all subscriptions for all JIDs that match the bare JID &BAREJID; portion of the 'from' attribute on the request.</p>
<p>For each subscription, a <subscription/> element is returned specifying the NodeID, the JID that is affiliated (which MAY include a resource, depending on how the entity subscribed), and the current subscription state. If subscription identifiers are supported by the service, the 'subid' attribute MUST be present as well.</p>
<examplecaption='Service returns all current subscriptions'><![CDATA[
<p>If the requesting entity has no subscriptions, the pubsub service MUST return an empty <subscriptions/> element.</p>
<examplecaption='No subscriptions'><![CDATA[
<iqtype='result'
from='pubsub.shakespeare.lit'
to='francisco@denmark.lit/barracks'
id='subscriptions1'>
<pubsubxmlns='http://jabber.org/protocol/pubsub'>
<subscriptions/>
</pubsub>
</iq>
]]></example>
<p>If the service does not support subscriptions retrieval, the service MUST respond with a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "retrieve-subscriptions".</p>
<examplecaption='Subscriptions retrieval not supported'><![CDATA[
<p>An entity MAY also request its subscriptions at a specific node (e.g., if it has subscriptions with multiple SubIDs) by including a 'node' attribute on the <subscriptions/> element.</p>
<examplecaption='Entity requests current subscriptions from a specific node'><![CDATA[
<iqtype='get'
from='francisco@denmark.lit/barracks'
to='pubsub.shakespeare.lit'
id='subscriptions2'>
<pubsubxmlns='http://jabber.org/protocol/pubsub'>
<subscriptionsnode='princely_musings'/>
</pubsub>
</iq>
]]></example>
<p>The service would then return only the subscriptions to that node.</p>
<examplecaption='Service returns all current subscriptions'><![CDATA[
<p>An entity may want to query the service to retrieve its affiliations for all nodes at the service. Support for this feature ("retrieve-affiliations") is RECOMMENDED.</p>
<p>In order to make the request, the requesting entity includes an empty <affiliations/> element with no attributes.</p>
<p>If the service returns a list of affiliations, it MUST return all affiliations for all JIDs that match the bare JID &BAREJID; portion of the 'from' attribute on the request.</p>
<p>For each affiliation, an <affiliation/> element is returned containing the NodeID and the affiliation state (owner, publisher, or outcast).</p>
<examplecaption='Service replies with all current affiliations'><![CDATA[
<iqtype='result'
from='pubsub.shakespeare.lit'
to='francisco@denmark.lit'
id='affil1'>
<pubsubxmlns='http://jabber.org/protocol/pubsub'>
<affiliations>
<affiliationnode='node1'affiliation='owner'/>
<affiliationnode='node2'affiliation='publisher'/>
<affiliationnode='node5'affiliation='outcast'/>
<affiliationnode='node6'affiliation='owner'/>
</affiliations>
</pubsub>
</iq>
]]></example>
<p>If the requesting entity has no affiliations, the pubsub service MUST return an empty <affiliations/> element.</p>
<examplecaption='No affiliations'><![CDATA[
<iqtype='result'
from='pubsub.shakespeare.lit'
to='francisco@denmark.lit/barracks'
id='affil1'>
<pubsubxmlns='http://jabber.org/protocol/pubsub'>
<affiliations/>
</pubsub>
</iq>
]]></example>
<p>If the service does not support affiliations retrieval, the service MUST respond with a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "retrieve-affiliations".</p>
<examplecaption='Affiliations retrieval not supported'><![CDATA[
<section1topic='Subscriber Use Cases'anchor='subscriber'>
<p>This section defines the use cases for and protocols to be used by potential and actual subscribers. (Note: The <linkurl='#impl'>Implementation Notes</link> section of this document describes many important factors and business rules which a pubsub service MUST observe. In addition, the examples throughout assume the existence of a separate pubsub component and include any relevant 'from' addresses as stamped by a server or network edge.)</p>
<section2topic='Subscribe to a Node'anchor='subscriber-subscribe'>
<p>When a Jabber entity wishes to subscribe to a node, it sends a subscription request to the pubsub service. The subscription request is an IQ-set where the <pubsub/> element contains one and only one <subscribe/> element. The <subscribe/> element SHOULD possess a 'node' attribute specifying the node to which the entity wishes to subscribe. The <subscribe/> element MUST also possess a 'jid' attribute specifying the exact XMPP address to be used as the subscribed JID -- often a bare JID &BAREJID; or full JID &FULLJID;.</p>
<p>If the subscription request is successfully processed, the server MUST inform the requesting entity that it is now subscribed (which MAY include a service-generated SubID).</p>
<examplecaption='Service replies with success'><![CDATA[
<p>These error cases are described more fully in the following sections.</p>
<section4topic='JIDs Do Not Match'anchor='subscriber-subscribe-error-nomatch'>
<p>If the specified JID is a bare JID or full JID, the service MUST at a minimum check the bare JID portion against the bare JID portion of the 'from' attribute on the received IQ request to make sure that the requesting entity has the same identity as the JID which is being requested to be added to the subscriber list.</p>
<p>If the bare JID portions of the JIDs do not match as described above and the requesting entity does not have some kind of admin or proxy privilege as defined by the implementation, the service MUST return a &badrequest; error, which SHOULD also include a pubsub-specific error condition of <invalid-jid/>.</p>
<p>Note: An implementation MAY enable the service administrator to configure a list of entities that are excluded from this check; those entities may be considered "trusted proxies" that are allowed to subscribe on behalf of other entities. In the same way, implementations MAY enable blacklisting of entities that are not allowed to perform specific operations (such as subscribing or creating nodes).</p>
<p>For nodes with an access model of "presence", if the requesting entity is not subscribed to the owner's presence then the pubsub service MUST respond with a ¬authorized; error, which SHOULD also include a pubsub-specific error condition of <presence-subscription-required/>.</p>
<examplecaption='Entity is not authorized to create a subscription (presence subscription required)'><![CDATA[
<section4topic='Not in Roster Group'anchor='subscriber-subscribe-error-rostergroup'>
<p>For nodes with an access model of "roster", if the requesting entity is not in one of the authorized roster groups then the pubsub service MUST respond with a ¬authorized; error, which SHOULD also include a pubsub-specific error condition of <not-in-roster-group/>.</p>
<examplecaption='Entity is not authorized to create a subscription (not in roster group)'><![CDATA[
<section4topic='Not on Whitelist'anchor='subscriber-subscribe-error-whitelist'>
<p>For nodes with a node access model of "whitelist", if the requesting entity is not on the whitelist then the service MUST return a ¬allowed; error, specifying a pubsub-specific error condition of <closed-node/>.</p>
<examplecaption='Node has whitelist access model'><![CDATA[
<p>Commercial deployments may wish to link subscribers to a database of paying customers. If the subscriber needs to provide payment in order to subscribe to the node (e.g., if the subscriber is not in the customer database or the customer's account is not paid up), the service SHOULD return a &payment; error to the subscriber.</p>
<examplecaption='Payment is required for a subscription'><![CDATA[
<section4topic='Anonymous Subscriptions Not Allowed'anchor='subscriber-subscribe-error-anonymous'>
<p>Some XMPP servers may allow authentication using SASL ANONYMOUS; however, because the resulting entity is unstable (the assigned JID may not be owned by the same principal in a persistent manner), a service MAY prevent anonymous entities from subscribing to nodes and SHOULD use service discovery to determine if an entity has an identity of "account/anonymous". If a requesting entity is anonymous but the service does not allow anonymous entities to subscribe, the service SHOULD return a &forbidden; error to the subscriber.</p>
<examplecaption='Requesting entity is anonymous'><![CDATA[
<p>If the requesting entity has a pending subscription, the service MUST return a ¬authorized; error to the subscriber, specifying a pubsub-specific error condition of <pending-subscription/>.</p>
<examplecaption='Requesting entity has pending subscription'><![CDATA[
<p>If the requesting entity is blocked from subscribing (e.g., because having an affiliation of outcast), the service MUST return a &forbidden; error to the subscriber.</p>
<examplecaption='Requesting entity is blocked'><![CDATA[
<section4topic='Subscriptions Not Supported'anchor='subscriber-subscribe-error-unsupported'>
<p>If the node does not allow entities to subscribe, the service SHOULD return a &feature; error to the subscriber, specifying a pubsub-specific error condition of <unsupported/> and a feature of "subscribe".</p>
<examplecaption='Subscribing not supported'><![CDATA[
<section4topic='Node Has Moved'anchor='subscriber-subscribe-error-redirect'>
<p>If the node has, the service SHOULD return a &gone; error (if the node has moved permanently) or a &redirect; error (if the node has moved temporarily).</p>
<p>For nodes with an access model of "authorize", subscription requests MUST be approved by one of the node owners; therefore the pubsub service sends a message to the node owner(s) requesting authorization (see the <linkurl='#owner-subreq'>Manage Subscription Requests</link> section of this document). Because the subscription request may or may not be approved, the service MUST return a pending notification to the subscriber.</p>
<examplecaption='Service replies with pending'><![CDATA[
<p>If the entity must configure its subscription options (see the <linkurl='#subscriber-configure'>Configure Subscription Options</link> section of this document) before receiving notifications, the service MUST so inform the entity. It SHOULD do so by returning an IQ-result to the requesting entity with a notation that configuration of subscription options is required.</p>
<examplecaption='Service replies with success and indicates that subscription configuration is required'><![CDATA[
<p>Note: The node shall include the <required/> child element only if the subscriber must configure the subscription before receiving any notifications. A service MAY time out subscription requests if configuration is required and a configuration request is not submitted within a reasonable amount of time (which shall be determined by the service or node configuration).</p>
<p>Alternatively, if the service is unable to create the subscription without simultaneous configuration, the service MAY return a ¬acceptable; error, specifying a pubsub-specific error condition of <configuration-required/>.</p>
<examplecaption='Service returns error specifying that subscription configuration is required'><![CDATA[
<p>If the <required/> element is not included and no error is returned, the subscription takes effect immediately and the entity may configure the subscription at any time (the service MAY indicate that subscription options are supported by including an empty <subscribe-options/> element in the IQ-result, as shown in the following example).</p>
<examplecaption='Service replies with success and indicates that subscription options are supported but not required'><![CDATA[
<p>An entity may wish to subscribe using different subscription options, which it can do by subscribing multiple times to the same node. Support for this feature ("multi-subscribe") is OPTIONAL.</p>
<p>If multiple subscriptions for the same JID are allowed, the service MUST use the 'subid' attribute to differentiate between subscriptions for the same entity (therefore the SubID MUST be unique for each node+JID combination and the SubID MUST be present on the entity element any time it is sent to the subscriber). It is NOT RECOMMENDED for clients to generate SubIDs, since collisions might result; therefore a service SHOULD generate the SubID on behalf of the subscriber and MAY overwrite SubIDs if they are provided by subscribers. If the service does not allow multiple subscriptions for the same entity and it receives an additional subscription request, the service MUST return the current subscription state (as if the subscription was just approved).</p>
<p>When a subscription request is successfully processed, the service MAY send the last published item to the new subscriber. The message containing this item SHOULD be stamped with extended information qualified by the 'urn:xmpp:delay' namespace (see &xep0203;) to indicate it is sent with delayed delivery. (Note that in this example the message notification is sent to the bare JID since that is the subscribed JID.)</p>
<p>If the service sends the last published item by default for all nodes (subject to overriding by node configuration), it MUST return a feature of "http://jabber.org/protocol/pubsub#last-published" in its responsess to disco#info requests.</p>
<p>To unsubscribe from a node, the subscriber sends an IQ-set whose &PUBSUB; child contains an <unsubscribe/> element that specifies the node and the subscribed JID.</p>
<examplecaption='Entity unsubscribes from a node'><![CDATA[
<p>If the requesting entity has multiple subscriptions to the node but does not specify a subscription ID, the service MUST return a &badrequest; error, which SHOULD also include a pubsub-specific error condition of <subid-required/>.</p>
<examplecaption='Entity did not specify SubID'><![CDATA[
<section4topic='No Such Subscriber'anchor='subscriber-unsubscribe-error-nosub'>
<p>If the value of the 'jid' attribute does not specify an existing subscriber, the pubsub service MUST return an error stanza, which SHOULD be &unexpected; and which SHOULD also include a pubsub-specific error condition of <not-subscribed/>.</p>
<examplecaption='Requesting entity is not a subscriber'><![CDATA[
<p>If the requesting entity is prohibited from unsubscribing the specified JID, the service MUST return a &forbidden; error. The service MUST validate that the entity making the request is authorized to unsubscribe the entity. If the subscriber's JID is of the form &FULLJID;, a service MUST perform this check by comparing the &BAREJID; part of the two JIDs to ensure that they match. If the bare JID portions of the JIDs do not match and the requesting entity is not authorized to unsubscribe the JID (e.g., because it is not a service-wide admin or authorized proxy), the service MUST return a &forbidden; error.</p>
<examplecaption='Requesting entity is prohibited from unsubscribing entity'><![CDATA[
<p>If a subscription identifier is associated with the subscription, the unsubscribe request MUST include an appropriate 'subid' attribute. If the unsubscribe request includes a SubID but SubIDs are not supported for the node (or the subscriber did not subscribe using a SubID in the first place), the service SHOULD ignore the SubID and simply unsubscribe the entity. If the subscriber originally subscribed with a SubID but the unsubscribe request includes a SubID that is not valid or current for the subscriber, the service MUST return a ¬acceptable; error, which SHOULD also include a pubsub-specific error condition of <invalid-subid/>.</p>
<p>An implementation MAY allow subscribers to configure subscription options. Implementations SHOULD use the <cite>Data Forms</cite> protocol to accomplish this configuration (however, an out-of-band mechanism such as a web interface could be offered as well).</p>
<p>If a service supports subscription options it MUST advertise that fact in its response to a "disco#info" query by including a feature whose 'var' attribute is "pubsub#subscription-options".</p>
<examplecaption='Pubsub service indicates support for subscription options'><![CDATA[
<p>Note: The foregoing example shows some (but by no means all) of the possible configuration options that MAY be provided. If an implementation provides these options using the <strong>Data Forms</strong> protocol, it MUST use the field variables that are registered with the XMPP Registrar in association with the 'http://jabber.org/protocol/pubsub' namespace (a preliminary representation of those field variables is shown above and in the <linkurl='#registrar-formtypes-subscribe'>pubsub#subscribe_options FORM_TYPE</link> section of this document, but MUST NOT be construed as canonical since the XMPP Registrar may standardize additional fields at a later date without changes to this document).</p>
<p>Note: Many of the relevant data form fields are of type "boolean" and MUST be handled accordingly. &BOOLEANNOTE;</p>
<p>When requesting subscription options, the subscriber MUST specify the JID that is subscribed to the node and SHOULD specify a node (if no node is specified, the service MUST assume that the requesting entity wishes to request subscription options for its subscription to the root collection node; see the <linkurl='#collections-root'>Root Collection Node</link> section of this document for details).</p>
<p>The service MUST validate that the entity making the request is authorized to set the subscription options for the subscribed entity. If the subscriber's JID is of the form &FULLJID;, a service MUST perform this check by comparing the &BAREJID; part of the two JIDs to ensure that they match. If the bare JID portions of the JIDs do not match and the requesting entity is not authorized to modify subscription options for the JID (e.g., because it is not a service-wide admin or authorized proxy), the service MUST return a &forbidden; error.</p>
<examplecaption='Requesting entity does not have sufficient privileges to modify subscription options'><![CDATA[
<section4topic='No Such Subscriber'anchor='subscriber-configure-error-nosub'>
<p>If the requesting entity (or specified subscriber, if different) is not subscribed, the service MUST return an &unexpected; error, which SHOULD also include a pubsub-specific error condition of <not-subscribed/>.</p>
<p>If the subscriber does not specify a JID, the service MUST return a &badrequest; error, which SHOULD also include a pubsub-specific error condition of <jid-required/>.</p>
<examplecaption='Subscriber JID not specified'><![CDATA[
<section4topic='Subscription ID Required'anchor='subscriber-configure-error-subid'>
<p>If a subscription identifier is associated with the subscription, the 'subid' attribute MUST be present on the request in order for the service to differentiate subscriptions for the same entity. If the 'subid' is required but not provided, the service MUST return a &badrequest; error, which SHOULD also include a pubsub-specific error condition of <subid-required/>.</p>
<p>If a subscription identifier is associated with the subscription but the request includes a SubID that is not valid or current for the subscriber, the service MUST return a ¬acceptable; error, which SHOULD also include a pubsub-specific error condition of <invalid-subid/>.</p>
<section4topic='Subscription Options Not Supported'anchor='subscriber-configure-error-options'>
<p>If the node or service does not support subscription options, the service MUST respond with a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "subscription-options".</p>
<examplecaption='Subscription options not supported'><![CDATA[
<p>After receiving the configuration form, the requesting entity SHOULD submit the form in order to update the entity's subscription options for that node.</p>
<p>As noted, if a service supports subscription options, an entity MAY subscribe and provide the subscription options in the same stanza.</p>
<p>Note: The <options/> element MUST follow the <subscribe/> element and MUST NOT possess a 'node' attribute or 'jid' attribute, since the value of the <subscribe/> element's 'node' attribute specifies the desired NodeID and the value of the <subscribe/> element's 'jid' attribute specifies the subscriber's JID; if any of these rules are violated, the service MUST return a &badrequest; error.</p>
<examplecaption='Entity subscribes to node and sets configuration options'><![CDATA[
<p>When the service informs the client of success, it SHOULD include a data form of type "result" informing the client of the resulting configuration options.</p>
<examplecaption='Service replies with success (including configuration options)'><![CDATA[
<p>Implementations of pubsub that choose to persist items MAY allow entities to request existing items from a node (e.g., an entity may wish to do this after successfully subscribing in order to receive all the items in the publishing history for the node).</p>
<p>The service MUST conform to the node's access model in determining whether to return items to the entity that requests them. Specifically:</p>
<ul>
<li><p>If the access model is "open", the service SHOULD allow any entity (whether or not it is subscribed) to retrieve items.</p></li>
<li><p>If the access model is "presence", the service SHOULD allow any entity that is subscribed to the owner's presence to retrieve items.</p></li>
<li><p>If the access model is "roster", the service SHOULD allow any entity that is subscribed to the owner's presence and contained in the relevant roster group(s) to retrieve items.</p></li>
<li><p>If the access model is "authorize" or "whitelist", the service MUST allow only subscribed entities to retrieve items.</p></li>
</ul>
<p>The only exception foreseen to the SHOULD requirements for the foregoing access models is the enforcement of local privacy and security policies as specified more fully in the <linkurl='#security'>Security Considerations</link> section of this document. (In addition, a service MUST always allow the node owner to retrieve items from a node and SHOULD always allow a publisher to do so.)</p>
</section3>
<section3topic='Requesting All Items'anchor='subscriber-retrieve-requestall'>
<p>The subscriber may request all items by specifying only the Node ID without restrictions.</p>
<examplecaption='Subscriber requests all items'><![CDATA[
<p>The service then SHOULD return all items published to the node, although it MAY truncate the result set if a large number of items has been published (see next section).</p>
<section3topic='Returning Some Items'anchor='subscriber-retrieve-returnsome'>
<p>A node may have a large number of items associated with it, in which case it may be problematic to return all of the items in response to an items request. In this case, the service SHOULD return some of the items and note that the list of items has been truncated by including a &xep0059; notation.</p>
<examplecaption='Service returns some items via result set management'><![CDATA[
<iqtype='result'
from='pubsub.shakespeare.lit'
to='francisco@denmark.lit/barracks'
id='items1'>
<pubsubxmlns='http://jabber.org/protocol/pubsub'>
<itemsnode='princely_musings'>
<itemid='368866411b877c30064a5f62b917cffe'>
<entryxmlns='http://www.w3.org/2005/Atom'>
<title>The Uses of This World</title>
<summary>
O, that this too too solid flesh would melt
Thaw and resolve itself into a dew!
</summary>
<linkrel='alternate'type='text/html'
href='http://denmark.lit/2003/12/13/atom03'/>
<id>tag:denmark.lit,2003:entry-32396</id>
<published>2003-12-12T17:47:23Z</published>
<updated>2003-12-12T17:47:23Z</updated>
</entry>
</item>
<itemid='3300659945416e274474e469a1f0154c'>
<entryxmlns='http://www.w3.org/2005/Atom'>
<title>Ghostly Encounters</title>
<summary>
O all you host of heaven! O earth! what else?
And shall I couple hell? O, fie! Hold, hold, my heart;
<p>A service MAY return event notifications without payloads (e.g., to conserve bandwidth). If so, the client MAY request a specific item (using the ItemID) in order to retrieve the payload. When an entity requests items by ItemID, implementations MUST allow multiple items to be specified in the request.</p>
<examplecaption='Subscriber requests specific items by ItemID'><![CDATA[
<section3topic='Requesting Some Items'anchor='subscriber-retrieve-requestsome'>
<p>A service MAY allow entities to request the most recent N items by using the 'max_items' attribute. When max_items is used, implementations SHOULD return the N most recent (as opposed to the N oldest) items. (Note: A future version of this specification may recommend the use of &xep0059; instead of the 'max_items' attribute.)</p>
<examplecaption='Subscriber requests two most recent items'><![CDATA[
<iqtype='get'
from='francisco@denmark.lit/barracks'
to='pubsub.shakespeare.lit'
id='items2'>
<pubsubxmlns='http://jabber.org/protocol/pubsub'>
<itemsnode='princely_musings'max_items='2'/>
</pubsub>
</iq>
]]></example>
<examplecaption='Service returns two most recent items'><![CDATA[
<p>There are several reasons why the items retrieval request might fail:</p>
<ol>
<li>The requesting entity has multiple subscriptions to the node but does not specify a subscription ID.</li>
<li>The requesting entity is subscribed but specifies an invalid subscription ID.</li>
<li>The node does not return items to unsubscribed entities and the requesting entity is not subscribed.</li>
<li>The service or node does not support persistent items and does not return the last published item.</li>
<li>The service or node does not support item retrieval.</li>
<li>The node has an access model of "presence" and the requesting entity is not subscribed to the owner's presence.</li>
<li>The node has an access model of "roster" and the requesting entity is not in one of the authorized roster groups.</li>
<li>The node has an access model of "whitelist" and the requesting entity is not on the whitelist.</li>
<li>The service or node requires payment for item retrieval.</li>
<li>The requesting entity is blocked from retrieving items from the node (e.g., because having an affiliation of outcast).</li>
<li>The node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section4topic='Subscription ID Required'anchor='subscriber-retrieve-error-subid'>
<p>If the requesting entity has multiple subscriptions to the node but does not specify a subscription ID, the service MUST return a &badrequest; error to the subscriber, which SHOULD also include a pubsub-specific error condition of <subid-required/>.</p>
<examplecaption='Entity did not specify SubID'><![CDATA[
<p>If the requesting entity is subscribed but specifies an invalid subscription ID, the service MUST return a ¬acceptable; error to the subscriber, which SHOULD also include a pubsub-specific error condition of <invalid-subid/>.</p>
<section4topic='Entity Not Subscribed'anchor='subscriber-retrieve-error-notsubscribed'>
<p>If the node does not return items to unsubscribed entities and the requesting entity is not subscribed (which includes having a pending subscription), the service MUST return a ¬authorized; error to the subscriber, which SHOULD also include a pubsub-specific error condition of <not-subscribed/>.</p>
<examplecaption='Entity is not subscribed'><![CDATA[
<section4topic='Persistent Items Not Supported'anchor='subscriber-retrieve-error-persistent'>
<p>If the service or node does not support persistent items and does not return the last published item, the service MUST return a &feature; error to the subscriber, specifying a pubsub-specific error condition of <unsupported/> and a feature of "persistent-items".</p>
<examplecaption='Persistent items not supported'><![CDATA[
<section4topic='Item Retrieval Not Supported'anchor='subscriber-retrieve-error-notsupported'>
<p>If the service or node does not support item retrieval (e.g., because the node is a collection node), the service MUST return a &feature; error to the subscriber, specifying a pubsub-specific error condition of <unsupported/> and a feature of "retrieve-items".</p>
<examplecaption='Item retrieval not supported'><![CDATA[
<p>For nodes with an access model of "presence", if the requesting entity is not subscribed to the owner's presence then the pubsub service MUST respond with a ¬authorized; error, which SHOULD also include a pubsub-specific error condition of <presence-subscription-required/>.</p>
<examplecaption='Entity is not authorized to retrieve items (presence subscription required)'><![CDATA[
<section4topic='Not in Roster Group'anchor='subscriber-retrieve-error-rostergroup'>
<p>For nodes with an access model of "roster", if the requesting entity is not in one of the authorized roster groups then the pubsub service MUST respond with a ¬authorized; error, which SHOULD also include a pubsub-specific error condition of <not-in-roster-group/>.</p>
<examplecaption='Entity is not authorized to retrieve items (not in roster group)'><![CDATA[
<section4topic='Not on Whitelist'anchor='subscriber-retrieve-error-whitelist'>
<p>For nodes with a node access model of "whitelist", if the requesting entity is not on the whitelist then the service MUST return a ¬allowed; error, specifying a pubsub-specific error condition of <closed-node/>.</p>
<examplecaption='Node has whitelist access model'><![CDATA[
<p>Commercial deployments may wish to link subscribers to a database of paying customers. If the subscriber needs to provide payment in order to retrieve items from the node (e.g., if the subscriber is not in the customer database or the customer's account is not paid up), the service SHOULD return a &payment; error to the subscriber.</p>
<examplecaption='Payment is required to retrieve items'><![CDATA[
<p>If the requesting entity is blocked from subscribing (e.g., because having an affiliation of outcast), the service MUST return a &forbidden; error to the subscriber.</p>
<examplecaption='Requesting entity is blocked'><![CDATA[
<p>Any entity that is allowed to publish items to a node (i.e., a publisher or an owner) may do so at any time by sending an IQ-set to the service containing a pubsub element with a <publish/> child.</p>
<p>The syntax is as follows:</p>
<ul>
<li>The <publish/> element MUST possess a 'node' attribute, specifying the NodeID of the node.</li>
<li>Depending on the node configuration, the <publish/> element MAY contain no &ITEM; elements, one &ITEM; element, or (for <linkurl='#impl-batch'>Batch Processing</link>) more than one &ITEM; element. <note>It is not necessary for a publication request to include a payload or even an &ITEM; element in order to trigger a notification. For example, the result of publishing to a transient, notification-only node will be a notification that does not include even an &ITEM; element. However, for the sake of convenience we refer to the act of publication as "publishing an item" (rather than, say, "triggering a notification") even though a publication request will not always contain an &ITEM; element.</note></li>
<li>The <item/> element provided by the publisher MAY possess an 'id' attribute, specifying a unique ItemID for the item. If an ItemID is not provided in the publish request, the pubsub service MUST generate one and MUST ensure that it is unique for that node.</li>
<p>If the pubsub service can successfully process the request, it MUST inform the publisher of success. If the publish request did not include an ItemID, the IQ-result SHOULD include an empty &ITEM; element that specifies the ItemID of the published item.</p>
<p>Note: If the publisher previously published an item with the same ItemID, successfully processing the request means that the service MUST overwrite the old item with the new item and then proceed as follows.</p>
<p>The pubsub service MUST then send one &MESSAGE; stanza containing a pubsub event notification to each entity that meets the criteria for receiving a notification (typically to each approved subscriber, although there are other contexts in which an entity may receive a notification as summarized under <linkurl='#impl-notify'>Notification Triggers</link>). Each &MESSAGE; stanza generated by a pubsub service SHOULD possess an 'id' attribute with a unique value so that the service can properly track any notification-related errors that may occur (see the <linkurl='#impl-errors'>Handling Notification-Related Errors</link> section of this document). Depending on the node configuration, the event notification either will or will not contain the payload, as shown below.</p>
<p>Note: In order to facilitate authorization for item removal as described in the <linkurl='#publisher-delete'>Delete an Item from a Node</link> section of this document, implementations that support persistent items SHOULD store the item (if the node is so configured) and maintain a record of the publisher.</p>
<p>Note: If the service or node is configured so that there is a maximum number of items cached at the node and the maximum is reached when an item is published, the service MUST delete one of the existing items. It is RECOMMENDED for the service to follow the "first in, first out" rule and delete the oldest item. Depending on node configuration, deletion of an existing item MAY result in sending of a delete notification to the subscribers.</p>
<section4topic='Notification Without Payload'anchor='publisher-publish-success-withoutpayload'>
<p>If the node is configured to not include payloads, the subscribers will receive event notifications only. (If payloads are not included, subscribers may request the published item via the protocol defined in the <linkurl='#subscriber-retrieve'>Retrieve Items from a Node</link> section of this document.)</p>
<section4topic='Inclusion of Subscription ID'anchor='publisher-publish-success-subid'>
<p>If a single entity is subscribed to a node multiple times, the service SHOULD notate the event notification so that the entity can determine which subscription identifier(s) generated this event. If these notations are included, they MUST use the &xep0131; format and SHOULD be included after the event notification information (i.e., as the last child of the &MESSAGE; stanza).</p>
<p>There are several reasons why the publish request might fail:</p>
<ol>
<li>The requesting entity does not have sufficient privileges to publish.</li>
<li>The node does not support item publication.</li>
<li>The node does not exist.</li>
<li>The payload size exceeds a service-defined limit.</li>
<li>The item contains more than one payload element or the namespace of the root payload element does not match the configured namespace for the node.</li>
<li>The request does not match the node configuration.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<p>Note: If a publisher publishes an item with an Item ID and the ItemID matches that of an existing item, the pubsub service MUST NOT fail the publication but instead MUST overwrite the existing item and generate a new event notification (i.e., re-publication is equivalent to modification).</p>
<section4topic='Item Publication Not Supported'anchor='publisher-publish-error-notsupported'>
<p>If the node does not support item publication (because it is a <linkurl='#collections'>Collection Node</link>), the service MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "publish".</p>
<examplecaption='Node does not support item publication'><![CDATA[
<section4topic='Node Does Not Exist'anchor='publisher-publish-error-node'>
<p>If the requesting entity attempts to publish an item to a node that does not exist and the service does not support the "auto-create" feature (see <linkurl='#publisher-publish-autocreate'>Automatic Node Creation</link>), the service MUST return an ¬found; error.</p>
<examplecaption='Entity attempts to publish to a non-existent node'><![CDATA[
<section4topic='Payload Too Big'anchor='publisher-publish-error-bigpayload'>
<p>If the payload size exceeds a service-defined limit, the service MUST return a ¬acceptable; error, which SHOULD also include a pubsub-specific error condition of <payload-too-big/>.</p>
<examplecaption='Entity attempts to publish very large payload'><![CDATA[
<p>If the &ITEM; element contains more than one payload element or the namespace of the root payload element does not match the configured namespace for the node, the service MUST bounce the request with a &badrequest; error, which SHOULD also include a pubsub-specific error condition of <invalid-payload/>.</p>
<examplecaption='Entity attempts to publish item with multiple payload elements or namespace does not match'><![CDATA[
<section4topic='Request Does Not Match Configuration'anchor='publisher-publish-error-badrequest'>
<p>If the request does not conform to the configured <linkurl='#events'>event type</link> for the node, the service MAY bounce the request with a &badrequest; error, which SHOULD also include a pubsub-specific error condition. The following rules apply:</p>
<ul>
<li>If the event type is persistent (either notification or payload) and the publisher does not specify an ItemID, the service MUST generate the ItemID and MUST NOT bounce the publication request.</li>
<li>If the event type is persistent (either notification or payload) and the publisher does not include an item, the service MUST bounce the publication request with a &badrequest; error and a pubsub-specific error condition of <item-required/>.</li>
<li>If the event type is payload (either persistent or transient) and the publisher does not include a payload, the service SHOULD bounce the publication request with a &badrequest; error and a pubsub-specific error condition of <payload-required/>.</li>
<li>If the event type is notification + transient and the publisher provides an item, the service MUST bounce the publication request with a &badrequest; error and a pubsub-specific error condition of <item-forbidden/>.</li>
</ul>
<p>Examples of these errors are shown below.</p>
<examplecaption='Publisher attempts to publish to persistent node with no item'><![CDATA[
<p>A pubsub service MAY automatically create a node when it receives a publish request sent to a node that does not exist (instead of returning an ¬found; error). When doing so, the service SHOULD apply the default node configuration. If a service supports this functionality, it MUST advertise that fact by including a feature of "http://jabber.org/protocol/pubsub#auto-create" in its disco#info responses.</p>
<p>A pubsub service MAY support the ability to specify options along with a publish request (if so, it MUST advertise support for the "http://jabber.org/protocol/pubsub#publish-options" feature). Here is an example:</p>
<p>The <publish-options/> element SHOULD contain a data form (see <cite>XEP-0004</cite>), whose FORM_TYPE SHOULD be "http://jabber.org/protocol/pubsub#publish-options" (see <cite>XEP-0068</cite>).</p>
<p>How the fields are to be handled is up to the the pubsub service, which in the language of XEP-0004 functions as a form-processing entity.</p>
<p>For example, the service may treat the field as a precondition, in which case the service should proceed as follows:</p>
<li>If the node exists and the precondition is not met, then the publish shall fail with a &conflict; error condition and a pubsub-specific condition of <precondition-not-met/>.</li>
<li>If the node exists and the precondition is met, then the publish succeeds.</li>
<li>If the node does not exist and the service supports the "auto-create" feature, then the service shall auto-create the node with default configuration in all respects except those specified in the preconditions, and the publish succeeds.</li>
<li>If the node does not exist and the service does not support the "auto-create" feature, then the publish shall fail.</li>
<p>A publisher may want to delete an item once it has been published to a node that supports persistent items. Support for this feature ("delete-any") is RECOMMENDED.</p>
<p>To delete an item, the publisher sends a retract request as shown in the following examples. The <retract/> element MUST possess a 'node' attribute, MAY possess a 'notify' attribute, and SHOULD contain one &ITEM; element (but MAY contain more than one &ITEM; element for <linkurl='#impl-batch'>Batch Processing</link> of item retractions); the &ITEM; element MUST be empty and MUST possess an 'id' attribute.</p>
<examplecaption='Entity deletes an item from a node'><![CDATA[
<p>If no error occurs and the <retract/> element included a 'notify' attribute with a value of "true" or "1" &BOOLEANNOTE;, then the service MUST delete the item and MUST send message notifications to all subscribers as shown below. The syntax is identical to publish notifications except that instead of an &ITEM; element, the notification includes a <retract/> element.</p>
<section4topic='Inclusion of Subscription ID'anchor='publisher-delete-success-subid'>
<p>If a single entity is subscribed to the node multiple times, the service SHOULD notate the notification of item deletion so that the entity can determine which subscription identifier(s) generated this event. As above, if these notations are included, they MUST use the <cite>Stanza Headers and Internet Metadata (SHIM)</cite> protocol and SHOULD be included after the event notification information (i.e., as the last child of the &MESSAGE; stanza).</p>
<p>If the request does not specify a node, the service MUST return a &badrequest; error, which SHOULD also include a pubsub-specific error condition of <node-required/>.</p>
<examplecaption='Request does not specify a node'><![CDATA[
<section4topic='Item or ItemID Required'anchor='publisher-delete-error-itemid'>
<p>If the request does not include an &ITEM; element or the &ITEM; element does not specify an ItemID, the service MUST return a &badrequest; error, which SHOULD also include a pubsub-specific error condition of <item-required/>.</p>
<examplecaption='Request does not specify an item'><![CDATA[
<section4topic='Persistent Items Not Supported'anchor='publisher-delete-error-persistent'>
<p>If the node does not support persistent items (e.g., because it is a collection node or a transient node that does not deliver payloads), the service MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "persistent-items".</p>
<examplecaption='Node does not support persistent items'><![CDATA[
<section4topic='Item Deletion Not Supported'anchor='publisher-delete-error-notsupported'>
<p>If the service does not support item deletion, it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "delete-nodes".</p>
<examplecaption='Service does not support item deletion'><![CDATA[
<p>An entity may want to create a new node. Support for this feature ("create-nodes") is RECOMMENDED. However, a service MAY disallow creation of nodes based on the identity of the requesting entity, or MAY disallow node creation altogether (e.g., reserving that privilege to a service-wide administrator).</p>
<li>Create a node with default configuration for the specified node type.</li>
<li>Create and configure a node simultaneously.</li>
</ol>
<p>These methods, along with method-specific error conditions, are explained more fully in the following sections.</p>
<p>In addition to method-specific error conditions, there are several general reasons why the node creation request might fail:</p>
<ul>
<li>The service does not support node creation.</li>
<li>Only entities that are registered with the service are allowed to create nodes but the requesting entity is not registered.</li>
<li>The requesting entity does not have sufficient privileges to create nodes.</li>
<li>The requested NodeID already exists.</li>
<li>The request did not include a NodeID and "instant nodes" are not supported.</li>
</ul>
<p>These general error cases are described more fully below.</p>
<p>If the service does not support node creation, it MUST respond with a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "create-nodes".</p>
<examplecaption='Service does not support node creation'><![CDATA[
<p>If only entities that are registered with the service may create nodes but the requesting entity has not yet registered, the service MUST respond with a ®istration; error.</p>
<p>If the node creator does not specify a NodeID but the service does not support instant nodes, the service MUST return a ¬acceptable; error, specifying a pubsub-specific error condition of <nodeid-required/>.</p>
<examplecaption='Service does not support instant nodes'><![CDATA[
<p>If the node creator does not specify a NodeID but the service supports instant nodes, the service SHOULD generate a NodeID that is unique within the context of the service on behalf of the node creator.</p>
<examplecaption='Entity requests an instant node'><![CDATA[
<iqtype='set'
from='hamlet@denmark.lit/elsinore'
to='pubsub.shakespeare.lit'
id='create2'>
<pubsubxmlns='http://jabber.org/protocol/pubsub'>
<create/>
<configure/>
</pubsub>
</iq>
]]></example>
<p>If no error occurs, the pubsub service SHOULD create the node, generate a NodeID that is unique within the context of that service, and inform the user of success (including the NodeID in the response).</p>
<examplecaption='Service replies with success and generated NodeID'><![CDATA[
<p>Note: When a service successfully creates a node on behalf of the requesting entity, it MUST return an IQ result. If the node creation request did not specify a NodeID and the service supports creation of instant nodes, the service MUST specify the created NodeID in the IQ result. Similarly, if the node creation request specified a NodeID but the service modified the NodeID before creating the node as described in the <linkurl='#collections'>Collection Nodes</link> section of this document, the service MUST also specify the modified node in the IQ result. In all other cases, the service MUST NOT specify the NodeID in the IQ result (since the node creator can determine which node was created by tracking the 'id' attribute that it specified for the IQ-set).</p>
</section3>
<section3topic='Create a Node With Default Configuration'anchor='owner-create-default'>
<p>As explained above, each node type has its own default configuration. By asking the service to create a node with default configuration, the node creator accepts the default configuration. If the service allows node configuration, the owner may reconfigure the node after creating the node (as described in the <linkurl='#owner-configure'>Configure a Node</link> section of this document). In addition, a service MAY allow entities to determine the default configuration options for a given node type before creating a node (as described in the <linkurl='#owner-default'>Request Default Configurations</link> section of this document).</p>
<p>In order to create a node with default configuration, the node creator MUST include an empty <configure/> child element in the creation request. The node creator MAY specify values for the 'pubsub#node_type' and 'pubsub#access_model' configuration fields or MAY accept the defaults, which are "leaf" for the 'pubsub#node_type' field and the value represented by the 'pubsub#access_model' field (i.e., "authorize", "open", "presence", "roster", or "whitelist").</p>
<p>In the following example, the node creator requests a leaf node (the default type) with an open access model (assumed to be the default type for this service).</p>
<examplecaption='Entity requests leaf node with (default) open access model'><![CDATA[
<iqtype='set'
from='hamlet@denmark.lit/elsinore'
to='pubsub.shakespeare.lit'
id='create1'>
<pubsubxmlns='http://jabber.org/protocol/pubsub'>
<createnode='princely_musings'/>
<configure/>
</pubsub>
</iq>
]]></example>
<p>In order to request an access model other than the default for the service, the node creator MUST include a Data Form in the node creation request that specifies a non-default value for the 'pubsub#node_type' field.</p>
<examplecaption='Entity requests leaf node with non-default access model'><![CDATA[
<p>If the access model is supported and none of the general or method-specific errors has occurred, the service SHOULD create the node and inform the requesting entity of success.</p>
<examplecaption='Service informs requesting entity of success'><![CDATA[
<iqtype='result'
from='pubsub.shakespeare.lit'
to='hamlet@denmark.lit/elsinore'
id='create1'/>
]]></example>
<p>If service does not support the specified access model, it MUST return a ¬acceptable; error, specifying a pubsub-specific error condition of <unsupported-access-model/>.</p>
<examplecaption='Service does not support specified access model'><![CDATA[
<p>(For error handling if the service does not support the specified node type, see the <linkurl='#collections'>Collection Node</link> section of this document.)</p>
</section3>
<section3topic='Create and Configure a Node'anchor='owner-create-and-configure'>
<p>If an implementation allows node configuration (see the <linkurl='#owner-configure'>Configure a Node</link> section of this document), it SHOULD allow node creation requests to contain the desired node configuration in the node creation request.</p>
<p>Note: The <configure/> element MUST follow the <create/> element and MUST NOT possess a 'node' attribute, since the value of the <create/> element's 'node' attribute specifies the desired NodeID; if any of these rules are violated, the service MUST return a &badrequest; error.</p>
<examplecaption='Entity requests a new node with non-default configuration.'><![CDATA[
<examplecaption='Service replies with success'><![CDATA[
<iqtype='result'
from='pubsub.shakespeare.lit'
to='hamlet@denmark.lit/elsinore'
id='create1'/>
]]></example>
<p>If a service supports this "create-and-configure" feature, it MUST advertise that fact by returning a feature of "http://jabber.org/protocol/pubsub#create-and-configure" in response to service discovery information requests. If the create-and-configure option is not supported but the requesting entity sends such a request anyway, the service SHOULD ignore the configuration part of the request and proceed as if it had not been included.</p>
</section3>
</section2>
<section2topic='Configure a Node'anchor='owner-configure'>
<p>If no error occurs, the server MUST return a configuration form to the node owner, which SHOULD contain the current node configuration as the default values.</p>
<p>Note: The following example shows some of the possible configuration options that MAY be provided. If an implementation implements these features using the <strong>Data Forms</strong> protocol, that implementation MUST use the fields that are registered with the XMPP Registrar in association with the 'http://jabber.org/protocol/pubsub' namespace (a preliminary representation of those field variables is shown below and in the <linkurl='#registrar-formtypes-config'>pubsub#node_config FORM_TYPE</link> section of this document, but MUST NOT be construed as canonical, since the XMPP Registrar may standardize additional fields at a later date without changes to this document). An implementation MAY choose to specify different labels, values, and even field types, but MUST conform to the defined variable naming scheme.</p>
<section4topic='Node Configuration Not Supported'anchor='owner-configure-error-notsupported'>
<p>If the service does not support node configuration, the service MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "config-node".</p>
<examplecaption='Service does not support node configuration'><![CDATA[
<p>If the request did not specify a node, the service SHOULD return a &badrequest; error. It is possible that by not including a NodeID, the requesting entity is asking to configure the root node; however, if the requesting entity is not a service-level admin, it makes sense to return &badrequest; instead of &forbidden;.</p>
<examplecaption='Request did not specify a node'><![CDATA[
<p>If no configuration options are available (e.g., because node configuration is "locked down"), the service MUST return a ¬allowed; error to the owner.</p>
<examplecaption='Node has no configuration options'><![CDATA[
<p>If the requested node configuration change cannot be processed (e.g., because the node owner has attempted to change the configuration so that there are no node owners), the service MUST return a ¬acceptable; error to the owner.</p>
<examplecaption='Configuration change cannot be processed'><![CDATA[
<section4topic='Success With Notifications'anchor='owner-configure-process-notify'>
<p>If the "pubsub#notify_config" option is set to true, the service MUST send a notification of configuration change to all subscribers. (A service SHOULD support this option for leaf nodes and MUST support it for <linkurl='#collection'>Collection Nodes</link>.) If the node configuration is set to event notifications only, the notification MUST consist of an empty <configuration/> element whose 'node' attribute is set to the NodeID of the node; if the node configuration is set to full payloads, the <configuration/> element MUST in addition contain the node configuration as represented via the <strong>Data Forms</strong> protocol.</p>
<p>An entity may want to request information about the default node configuration, e.g. in order to determine whether to perform create-and-configure as previously described. Support for this feature is OPTIONAL.</p>
<p>To get the options, the entity MUST send an empty <default/> element to the service with no NodeID; in response, the service SHOULD return the default node options.</p>
<section4topic='Node Configuration Not Supported'anchor='owner-default-error-noconfig'>
<p>If the service does not support node configuration, it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "config-node".</p>
<examplecaption='Service does not support node configuration'><![CDATA[
<section4topic='Default Configuration Retrieval Not Supported'anchor='owner-default-error-notsupported'>
<p>If the service does not support retrieval of default node configuration options, it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "retrieve-default".</p>
<examplecaption='Service does not support retrieval of default configuration options'><![CDATA[
<p>The default configuration options may be different for a collection node vs. a leaf node. In order to specifically request the default configuration options for collection nodes, an entity MUST include a Data Form with a 'pubsub#node_type' field whose value is "collection" in the request (since the default value for the 'pubsub#node_type' field is "leaf").</p>
<examplecaption='Entity requests default configuration options for collection nodes'><![CDATA[
<p>If the service does not support collection nodes, it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "collections".</p>
<section2topic='Delete a Node'anchor='owner-delete'>
<p>If a service supports node creation, it MUST support node deletion. If an implementation persists items, it MUST remove all items from persistent storage before the node itself is deleted.</p>
<p>In order to delete a node, a node owner MUST send a node deletion request, consisting of a <delete/> element whose 'node' attribute specifies the NodeID of the node to be deleted.</p>
<p>In addition, the service MUST also send notification of node deletion to all subscribers (which SHOULD include pending and unconfigured subscriptions).</p>
<examplecaption='Subscribers are notified of node deletion'><![CDATA[
<p>If the node to be deleted is a collection node, the service should follow the recommendations provided under <linkurl='#collections-delete'>Collection Node Deletion</link>.</p>
<p>If the requesting entity does not have sufficient privileges to delete the node (e.g., is not an owner), the service MUST return a &forbidden; error.</p>
<examplecaption='Entity is not an owner'><![CDATA[
<p>If a service persists published items, a node owner may want to purge the node of all published items (thus removing all items from the persistent store, with the exception of the last published item, which MAY be cached). It is OPTIONAL for a service to implement this feature.</p>
<p>In order to purge a node of all items, a node owner sends a node purge request consisting of a <purge/> element whose 'node' attribute specifies the NodeID of the node to be purged.</p>
<examplecaption='Owner purges all items from a node'><![CDATA[
<p>If the node or service has been configured to notify subscribers on deletion of items, a purge request MUST NOT result in sending the same notifications as are sent when deleting items (since purging a node with many persisted items could result in a large number of notifications); instead, the node MUST send a single notification to each subscriber, containing an empty <purge/> child element.</p>
<examplecaption='Subscribers are notified of node purge'><![CDATA[
<section4topic='Node Purging Not Supported'anchor='owner-purge-error-notsupported'>
<p>If the node or service does not support node purging, it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "purge-nodes".</p>
<examplecaption='Service does not support node purging'><![CDATA[
<p>If the requesting entity does not have sufficient privileges to purge the node (e.g., because it is not a node owner), the service MUST return a &forbidden; error.</p>
<examplecaption='Entity is not an owner'><![CDATA[
<section4topic='Node Does Not Persist Items'anchor='owner-purge-error-nopersist'>
<p>If the service or node does not persist items (e.g., because the node is a collection node), it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "persistent-items".</p>
<examplecaption='Node is not configured for persistent items'><![CDATA[
<p>A service MAY send subscription approval requests to the node owner(s) at any time. An approval request consists of a message stanza containing a Data Form scoped by the "http://jabber.org/protocol/pubsub#subscribe_authorization" FORM_TYPE. The form MUST contain a boolean field that has a 'var' attribute of "pubsub#allow", which is the field that designates whether or not to allow the subscription request. The form SHOULD include fields that specify the node identifier, the subscription id (if applicable), and the JID of the pending subscriber. The message MAY include a &BODY; element that contains natural-language text explaining that the message contains a pending subscription form.</p>
<examplecaption='Service sends authorization request to node owner'><![CDATA[
label='Allow this JID to subscribe to this pubsub node?'>
<value>false</value>
</field>
</x>
</message>
]]></example>
<p>In order to approve the request, the owner shall submit the form and set the "pubsub#allow" field to a value of "1" or "true"; for tracking purposes the message MUST reflect the 'id' attribute originally provided.</p>
<p>The service then SHOULD send notification to the approved subscriber (see the <linkurl='#impl-subchange'>Notification of Subscription State Changes</link> section of this document).</p>
<p>In order to deny the request, the owner shall submit the form and set the "pubsub#allow" field to a value of "0" or "false"; as above, the message MUST reflect the 'id' attribute originally provided.</p>
<p>The service then SHOULD send notification to the denied subscriber (see the <linkurl='#impl-subchange'>Notification of Subscription State Changes</link> section of this document).</p>
<p>The service MUST check the "pubsub#allow" field to see if the subscription should be allowed or denied. If the owner cancels the Data Form, then the subscription request MUST remain in the pending state.</p>
<p>A node owner may want to request all of the pending subscription requests for all of their nodes at a service. It is OPTIONAL for a service to implement this feature.</p>
<p>This feature MUST be implemented using the &xep0050; protocol, where the command name ('node' attribute of the command element) MUST have a value of "http://jabber.org/protocol/pubsub#get-pending".</p>
<p>If no error occurs, the service SHOULD return a data form for managing subscription requests, which MUST contain a single field with a 'var' attribute value of "node" whose <option/> elements specify the nodes for which the requesting entity has subscription approval privileges (as an optimization, the service MAY specify only the nodes that have subscription requests pending).</p>
<examplecaption='Service responds with data form to be populated'><![CDATA[
<section4topic='Get-Pending Not Supported'anchor='owner-subreq-error-getpending'>
<p>If the service does not support the "get-pending" feature, it MUST respond with a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "get-pending".</p>
<examplecaption='Service responds with node not found'><![CDATA[
<p>If the requesting entity does not have sufficient privileges to approve subscription requests, the service MUST respond with a &forbidden; error.</p>
<examplecaption='Entity does not have sufficient privileges to approve subscription requests'><![CDATA[
<p>Upon receiving the data form for managing subscription requests, the owner then MAY request pending subscription approval requests for a given node.</p>
<examplecaption='Owner requests all pending subscription requests for a node'><![CDATA[
<p>If no error occurs, the service shall respond with success.</p>
<examplecaption='Service responds with success'><![CDATA[
<iqtype='result'
from='pubsub.shakespeare.lit'
to='hamlet@denmark.lit/elsinore'
id='pending2'/>
]]></example>
<p>The service shall then send one subscription approval message for each pending subscription request, as shown above for a single pending subscription request.</p>
<p>Note: A service SHOULD conform to its affiliation policies in maintaining the list of pending subscriptions. In particular, if the affiliation of an entity with a pending subscription is modified to owner or publisher, the service SHOULD automatically approve the subscription request and remove the entity's previous request from the pending list. Similarly, if the affiliation of an entity with a pending subscription is modified to outcast, the service SHOULD automatically reject the subscription request and remove the entity's previous request from the pending list. (If an entity's subscription request is denied, the service SHOULD send a &MESSAGE; to the entity, where the message conforms to the format described in the <linkurl='#impl-unsub'>Notification of Subscription Denial or Cancellation</link> section of this document.)</p>
<p>A node owner may want to edit the list of subscriptions associated with a given node. Support for this feature ("pubsub#manage-subscriptions") is OPTIONAL.</p>
<p>In order to request a list of all subscriptions, a node owner MUST send a subscriptions request, consisting of a <subscriptions/> element whose 'node' attribute specifies the NodeID of the relevant node.</p>
<examplecaption='Owner requests all subscriptions'><![CDATA[
<p>If no error occurs, the service MUST return the list of subscriptions for entities whose subscription state is "subscribed" or "unconfigured" (it MUST NOT return entities whose subscription state is "none" and SHOULD NOT return entities whose subscription state is "pending"). The result MAY specify multiple <subscription/> elements for the same entity (JID), but each element MUST possess a distinct value of the 'subid' attribute (as shown below).</p>
<examplecaption='Service returns list of subscriptions'><![CDATA[
<p>There are several reasons why the manage subscriptions request might fail:</p>
<ol>
<li>The service does not support subscription management.</li>
<li>The requesting entity does not have sufficient privileges to manage subscriptions.</li>
<li>The specified node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section5topic='Subscription Management Not Supported'anchor='owner-subscriptions-retrieve-error-notsupported'>
<p>If an implementation does not support subscription management, it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "manage-subscriptions".</p>
<examplecaption='Node or service does not support subscription management'><![CDATA[
<p>Upon receiving the subscriptions list, the node owner MAY modify subscription states. The owner MUST send only modified subscription states (i.e., a "delta"), not the complete list. (Note: If the 'subscription' attribute is not specified in a modification request, then the value MUST NOT be changed.)</p>
<p>There are several reasons why the modify subscriptions request might fail:</p>
<ol>
<li>The service does not support subscription management.</li>
<li>The requesting entity does not have sufficient privileges to manage subscriptions.</li>
<li>The specified node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section5topic='Subscription Management Not Supported'anchor='owner-subscriptions-modify-error-notsupported'>
<p>If an implementation does not support subscription management, it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "manage-subscriptions".</p>
<examplecaption='Node or service does not support subscription management'><![CDATA[
<p>The owner MAY change multiple subscriptions in a single request. If one of the entity elements specified is invalid, the service MUST return an IQ error (which SHOULD be ¬acceptable;) with the invalid entries, where the subscription returned is the original, un-altered subscription.</p>
<examplecaption='Owner sets subscription for multiple entities'><![CDATA[
<p>If errors occur during a modification request for multiple entities, the pubsub service MUST return any <subscription/> element(s) which caused the error. Returned entities which failed to be modified MUST include the existing 'subscription' attribute. Any entity elements which are not returned in an IQ error case MUST be treated as successful modifications. The owner MAY specify multiple <subscription/> elements for the same entity, but each element MUST possess a distinct value of the 'subid' attribute.</p>
</section4>
</section3>
<section3topic='Delete a Subscriber'anchor='owner-subscriptions-delete'>
<p>In order to remove an entity from the subscriptions list, the owner MUST set the value of the 'subscription' attribute to "none" and the service MUST remove that entity from the subscriptions list and not return it in response to future list requests.</p>
<p>An implementation SHOULD send notification to an entity whose subscription has changed (see the <linkurl='#impl-subchange'>Notification of Subscription State Changes</link> section of this document).</p>
<examplecaption='Service sends notification of subscription change'><![CDATA[
<p>A node owner may want to manage the affiliations of entities associated with a given node and to set affiliations for new entities. Support for this feature ("pubsub#modify-affiliations") is OPTIONAL.</p>
<p>In order to request a list of all affiliated entities, a node owner MUST send an affiliations request, consisting of an <affiliations/> element whose 'node' attribute specifies the NodeID of the relevant node.</p>
<examplecaption='Owner requests all affiliated entities'><![CDATA[
<p>If no error occurs, the service MUST return the list of entities whose affiliation is "owner", "publisher", or "outcast" (it MUST NOT return entities whose affiliation is "none").</p>
<examplecaption='Service returns list of affiliated entities'><![CDATA[
<p>If an implementation does not support modification of affiliations, it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "modify-affiliations".</p>
<examplecaption='Node or service does not support affiliation management'><![CDATA[
<p>In order to modify an affiliation, a node owner MUST send an IQ set containing the modified affiliation or affiliations. The owner MUST send only modified affiliations (i.e., a "delta"), not the complete list. (Note: If the 'affiliation' attribute is not specified in a modification request, then the value MUST NOT be changed.)</p>
<p>If an implementation does not support modification of affiliations, it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "modify-affiliations".</p>
<examplecaption='Node or service does not support affiliation management'><![CDATA[
<section5topic='Affiliation Not Supported'anchor='owner-affiliations-nosuchaffil'>
<p>If the node or service does not support the requested affiliation, it MUST return a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "member-affiliation", "outcast-affiliation", or "publisher-affiliation" as appropriate.</p>
<examplecaption='Node or service does not support the requested affiliation'><![CDATA[
<p>The owner MAY change multiple affiliations in a single request. If one of the entity elements specified is invalid, the service MUST return an IQ error (which SHOULD be ¬acceptable;) with the invalid entries, where the affiliation returned is the original, un-altered affiliation.</p>
<p>The following example shows an entity attempting to make the owner something other than an affiliation of "owner", an action which MUST NOT be allowed if there is only one owner.</p>
<examplecaption='Owner sets affiliation for multiple entities'><![CDATA[
<p>The state chart at the beginning of this document is a MUST-IMPLEMENT set of rules for checking possible state transitions. Implementations MAY enforce other (more strict) rules. If errors occur during a modification request for multiple entities, the pubsub service MUST return any <affiliation/> element(s) which caused the error. Returned entities which failed to be modified MUST include the existing 'affiliation' attribute. Any entity elements which are not returned in an IQ error case MUST be treated as successful modifications. The owner MUST NOT specify multiple <affiliation/> elements for the same entity; otherwise the service MUST return a &badrequest; error.</p>
<p>In order to remove an entity from the affiliations list, the owner MUST set the value of the 'affiliation' attribute to "none" and the service MUST remove that entity from the affiliations list and not return it in response to future list requests.</p>
<p>An implementation MAY send a message to an entity whose affiliation has changed, which MAY contain a &BODY; element specifying natural-language text regarding the affiliation change and which SHOULD contain the modified affiliation data.</p>
<examplecaption='Service sends notification of affiliation change'><![CDATA[
<p>A pubsub service MAY support collection nodes as well as leaf nodes. Collections enable nodes to be grouped together in many ways. A collection node MUST contain only leaf nodes and/or other collection nodes (similar to the way in which a file system directory can contain both files and subdirectories) and MUST NOT contain published items (therefore a collection MUST NOT support the "publish" feature or related features such as "persistent-items"). If collections are supported, a service MUST advertise that fact in its "disco#info" responses by including a feature of "pubsub#collections" and MUST support service discovery of child nodes as described in the <linkurl='#entity-nodes'>Discover Nodes</link> section of this document.</p>
<p>This section provides background information about collection nodes, with insights from graph theory. <note>See <linkurl='http://en.wikipedia.org/wiki/Graph_(mathematics)'>http://en.wikipedia.org/wiki/Graph_(mathematics)</link>.</note> The intended result is a clearer vocabulary about particular deployment scenarios. The terminology introduced in this section is used mainly in the discussion of <linkurl='collections-delete'>collection node deletion</link>.</p>
<p>In terms of graph theory, the set of nodes hosted at a pubsub service is a directed acyclic graph. <note>See <linkurl='http://en.wikipedia.org/wiki/Directed_acyclic_graph'>http://en.wikipedia.org/wiki/Directed_acyclic_graph</link>.</note> The particular graph types can be further described as follows:</p>
<ol>
<li>If there are no collection nodes, we say that the graph is simply a <strong>flat set</strong> of nodes without connections because there are no arcs between nodes, i.e., no node is the direct predecessor of another node (here we use the less formall phrase that no node is the parent of any other child node).</li>
<li>If there may be multiple paths between between any two given nodes (where the path may include intermediate collection nodes), the graph is a <strong>Directed Acyclic Graph</strong> or "DAG" <note>See <linkurl='http://en.wikipedia.org/wiki/Directed_acyclic_graph'>http://en.wikipedia.org/wiki/Directed_acyclic_graph</link>.</note> because a given node may be the child of multiple parents.</li>
<li>If there is only one path between any two given nodes (where the path may include intermediate collection nodes), the graph is a <strong>Tree</strong><note>See <linkurl='http://en.wikipedia.org/wiki/Tree_(graph_theory)'>http://en.wikipedia.org/wiki/Tree_(graph_theory)</link>.</note> because a given node may be the child of only one collection node.</li>
<li>If there is a root collection node but there are no internal collection nodes, we say informally that the graph has a <strong>depth</strong> of 1 because all of the connections from leaf nodes to the root collection node are direct (i.e., each connection is an arc); this case is equivalent to a flat set with a root collection node and is typically uninteresting.</li>
<li>If there is a root collection node and there are internal collection nodes, we say that the graph has <strong>infinite depth</strong> because there is an unbounded number of arcs between each leaf node and the root collection node; this case is more interesting than a graph of depth=1 since it enables a wide range of trees and hierarchies.</li>
<li>In a tree with collection nodes, deletion of a collection node automatically results in destruction of the arcs to that collection node from leaf nodes or other collection nodes because a child can have only one parent; in this case we say that a child node has a <strong>dependency</strong> on its parent and that the tree is a <strong>Strict Hierarchy</strong>. (This is similar to a strictly hierarchical file system, in which deletion of a directory results in deletion of all its file and subdirectories.)</li>
<li>In a DAG with collection nodes, deletion of a collection node does not automatically result in destruction of the arcs to that collection node from leaf nodes or other collection nodes because a child can have multiple parents (but if the last parent is deleted, the last remaining arc is destroyed); in this case we say that the tree is a <strong>Loose Hierarchy</strong>. (This is similar to a loosely hierarchical file system that is mostly hierarchical but that allows multiple soft links.)</li>
<li>If a graph is made up of directed acyclic graphs but there is no single root collection node for all the DAGs, we say that the graph is a <strong>Dag Set</strong> (i.e., a set of directed acyclic graphs).</li>
<li>If a graph is made up of trees but there is no single root collection node for all the trees, the graph is a <strong>Forest</strong> (i.e., a set of trees).</li>
<li>If each tree in a forest is a Strict Hierarchy, we say that the graph is a <strong>Strict Hierarchy Set</strong>.</li>
<li>If each DAG in a set is a Loose Hierarchy, we say that the graph is a <strong>Loose Hierarchy Set</strong>.</li>
</ol>
<p>Finally, in XMPP pubsub, all graphs are <strong>oriented</strong> because any two collection nodes cannot have a bidirectional relationship (i.e., if collection node #1 is a direct predecessor of collection node #2 then #2 cannot also be a direct predecessor of #1).</p>
<p>This terminology is summarized in the following table.</p>
<tablecaption='Node Relationship Models'>
<tr>
<th>Model</th>
<th>Description</th>
<th>Root Node</th>
<th>Multiple Parents</th>
<th>Node Dependency</th>
<th>Depth</th>
</tr>
<tr>
<td>Flat Set</td>
<td>A set of nodes with no parent-child relationships (i.e., there are no collection nodes).</td>
<td>No</td>
<td>N/A</td>
<td>No</td>
<td>0 (zero)</td>
</tr>
<tr>
<td>Directed Acyclic Graph (DAG)</td>
<td>A set of nodes with parent-child relationships, where a child node can have more than one parent.</td>
<td>Yes</td>
<td>Yes</td>
<td>No</td>
<td>1 or infinite</td>
</tr>
<tr>
<td>Dag Set</td>
<td>A set of DAGs with no root node.</td>
<td>No</td>
<td>Yes</td>
<td>No</td>
<td>1 or infinite</td>
</tr>
<tr>
<td>Tree</td>
<td>A set of nodes with parent-child relationships, where a node can be the child of only one parent.</td>
<td>Yes</td>
<td>No</td>
<td>No</td>
<td>1 or infinite</td>
</tr>
<tr>
<td>Forest</td>
<td>A set of trees with no root node.</td>
<td>No</td>
<td>No</td>
<td>No</td>
<td>1 or infinite</td>
</tr>
<tr>
<td>Strict Hierarchy</td>
<td>An infinite tree in which a child node can have only one parent and is dependent on its parent.</td>
<td>Yes</td>
<td>No</td>
<td>Yes</td>
<td>Infinite</td>
</tr>
<tr>
<td>Strict Hierarchy Set</td>
<td>A set of strict hierarchies with no root node.</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
<td>Infinite</td>
</tr>
<tr>
<td>Loose Hierarchy</td>
<td>An infinite DAG in which a child node can have multiple parents but cannot exist without at least one parent.</td>
<td>Yes</td>
<td>Yes</td>
<td>Yes</td>
<td>Infinite</td>
</tr>
<tr>
<td>Loose Hierarchy Set</td>
<td>A set of loose hierarchies with no root node.</td>
<section2topic='Subscribe to a Collection Node'anchor='collections-subscribe'>
<p>A service that implements collection nodes SHOULD allow entities to subscribe to collection nodes (subject to access models and local security policies).</p>
<p>In addition to the subscription configuration options already defined, there are two subscription configuration options specific to collection nodes:</p>
<ul>
<li>
<p><strong>pubsub#subscription_type</strong></p>
<p>This subscription option enables the subscriber to subscribe either to items or to nodes.</p>
<p>If the subscription type is "items", the subscriber shall be notified whenever any node contained in the collection generates a notification (e.g., when an item is published or deleted), as modified by the value of the "pubsub#subscription_depth" option.</p>
<p>If the subscription type is "nodes", the subscriber shall be notified whenever a new node is added to the collection, as modified by the value of the "pubsub#subscription_depth" option.</p>
<p>The default value of this subscription option MUST be "nodes".</p>
</li>
<li>
<p><strong>pubsub#subscription_depth</strong></p>
<p>This subscription option enables the subscriber to specify whether it wants to receive notifications only from first-level children of the collection (a value of "1") or from all descendents (a value of "all").</p>
<p>For subscriptions of type "items", this enables the subscriber to be informed only when an item is published to a leaf node that is a direct child of the collection node to which it has subscribed, or to be informed whenever an item is published to any leaf node in the "tree" that begins at the level of the collection to which it has subscribed.</p>
<p>For subscriptions of type "nodes", this enables the subscriber to be informed only when a new node is added in the specific collection to which it has subscribed, or to be informed whenever a node is added anywhere in the "tree" that begins at the level of the collection to which it has subscribed.</p>
<p>The default value of this subscription option MUST be "1".</p>
</li>
</ul>
<p>In order to subscribe to a collection node, an entity MUST send a subscription request to the node; the subscription request MAY include subscription options, but this is not strictly necessary (especially if the entity does not wish to override the default settings for the "pubsub#subscription_type" and "pubsub#subscription_depth" options).</p>
<examplecaption='Entity subscribes to a collection node (no configuration)'><![CDATA[
<iqtype='set'
from='francisco@denmark.lit/barracks'
to='pubsub.shakespeare.lit'
id='collsub1'>
<pubsubxmlns='http://jabber.org/protocol/pubsub'>
<subscribejid='francisco@denmark.lit'
node='blogs'/>
</pubsub>
</iq>
]]></example>
<p>The subscriber will now receive notification of new first-level nodes created within the "blogs" collection.</p>
<examplecaption='Entity subscribes to a collection node (with configuration)'><![CDATA[
<p>The subscriber will now receive item notifications from nodes at any depth within the "blogs" collection.</p>
<p>Depending on the nature of the node "tree", a subscription type of "items" and depth of "all" may result in an extremely large number of notifications. Therefore, a service MAY disallow such a combination of subscription options, in which case it MUST return a ¬allowed; error to the requesting entity.</p>
<p>A service MAY allow an entity to subscribe to a collection node in two ways, once with a subscription of type "nodes" (to receive notification of any new nodes added to the collection or the entire tree) and once with a subscription of type "items" (to receive all items published within the tree). However, a service SHOULD NOT allow an entity to subscribe twice to a collection node (once with a subscription depth of "1" and once with a subscription depth of "all") for the same subscription type, since two such subscriptions are unnecessary (a depth of "all" includes by definition a depth of "1"); in this case the service SHOULD return a &conflict; error to the requesting entity.</p>
<p>A service that implements collections SHOULD support a root collection. The root collection shall be identified by the lack of a node identifier (i.e., the address of the pubsub service itself, such as "pubsub.shakespeare.lit").</p>
<p>Subscribing to this node with a subscription of type "nodes" and a depth of "1" enables an entity to be notified whenever a new first-level node is created at the pubsub service. Subscribing to this node with a subscription of type "nodes" and a depth of "all" enables an entity to be notified whenever a new node is created anywhere at the pubsub service.</p>
<examplecaption='Entity subscribes to the root collection node'><![CDATA[
<p>In order to send notification of node associations and disassociations, the service shall send an event that contains a <collection/> element that in turns contains an <associate/> element whose 'id' attribute specifies the NodeID of the new node.</p>
<examplecaption='Notification of node association'><![CDATA[
<section2topic='Create a New Collection Node'anchor='collections-createnode'>
<p>To create a new collection node, the requesting entity MUST include a Data Form containing a 'pubsub#node_type' field whose <value/> is "collection".</p>
<examplecaption='Entity requests a new collection node'><![CDATA[
<examplecaption='Service responds with success'><![CDATA[
<iqtype='result'
from='pubsub.shakespeare.lit'
to='bard@shakespeare.lit/globe'
id='create3'/>
]]></example>
<p>In addition to the errors already defined for leaf node creation, there are several reasons why the collection node creation request might fail:</p>
<ol>
<li>The service does not support collection nodes.</li>
<li>The service does not support creation of collection nodes.</li>
<li>The requesting entity does not have sufficient privileges to create collection nodes.</li>
<p>If the service does not support collection nodes, it MUST respond with a &feature; error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "collections".</p>
<examplecaption='Service does not support collection nodes'><![CDATA[
<p>A service MAY offer some node configuration options that are specific to collection nodes and not provided in configuration forms related to leaf nodes. The following are RECOMMENDED:</p>
<ul>
<li>pubsub#children_association_policy -- the policy regarding who may associate child nodes with the collection (values: all, owner, whitelist).</li>
<li>pubsub#children_association_whitelist -- the whitelist of entities that may associate child nodes with the collection.</li>
<li>pubsub#children_max -- the maximum number of child nodes that may be associated with a collection.</li>
</ul>
</section2>
<section2topic='Create a Node Associated with a Collection'anchor='collections-createassociated'>
<p>To create a new node and associate it with an existing collection, the node configuration protocol MUST be used in the node creation request (see the <linkurl='#owner-create-and-configure'>Create and Configure a Node</link> section of this document). In order to specify the associated collection(s), the form MUST include a 'pubsub#collection' field.</p>
<p>Note: Inclusion of the node configuration form is not necessary if the node is being created as a first-level child of the root collection node, since every such child is automatically affiliated with the root collection node (if any).</p>
<p>Note: For the protocol used to associate an existing node with a collection, refer to the <linkurl='#collections-associate'>Associate an Existing Node with a Collection</link> section of this document.</p>
<examplecaption='Entity creates a new node associated with a collection'><![CDATA[
<p>Note: If the node is a collection node and the requesting entity wishes to request the default configuration, the requesting entity MUST include <em>only</em> the "pubsub#collection" and "pubsub#node_type" fields in the configuration form.</p>
<section4topic='Only One Collection Node'anchor='collections-createassociated-error-onenode'>
<p>An implementation MAY allow a node to be associated with more than one collection node and therefore MAY specify a type of "text-multi" for the "pubsub#collection" field. However, in order to reduce the complexity of implementation, it is RECOMMENDED to allow only one parent collection node for each node and therefore it is RECOMMENDED to specify a type of "text-single" for the "pubsub#collection" field. If a service supports associating a node with multiple collections, it MUST advertise support for the "multi-collection" feature (if that feature is not advertised, entities SHOULD assume that the service allows a node to be associated with only one collection). If the request specifies more than one collection node but the service allows a node to be associated with only one collection node, the service MUST return a &badrequest; error.</p>
<examplecaption='Too many collection nodes'><![CDATA[
<p>If the requesting entity does not have sufficient privileges to associate a node with the specified collection node, the service MUST return a &forbidden; error.</p>
<section4topic='No More Nodes'anchor='collections-createassociated-error-nomore'>
<p>If no additional nodes can be associated with the collection node because a configurable limit of associated nodes has been reached, the service MUST return a &conflict; error, which SHOULD also include a pubsub-specific error condition of <max-nodes-exceeded/>.</p>
<p>Deletion of a collection node can introduce a large number of changes to the system, depending on the <linkurl='#collections-models'>node relationship model</link> of the deployed system. This section describes recommended handling of deletion requests in the context of collection nodes.</p>
<p>When the graph of the pubsub system is a Directed Acyclic Graph, a child node can have more than one parent, which may be the root collection node. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>If a child node will still have at least one other parent after deletion of the collection node, the service MUST NOT delete the child node but instead MUST simply sever the relationship between the deleted collection node and the child node.</li>
<li>If a child node will have no other parents after deletion of the collection node, the service MUST associate any orphaned child with the root collection node.</li>
<p>When the graph of the pubsub system is a Dag Set, a child node can have more than one parent but there is no root collection node. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>If a child node will still have at least one other parent after deletion of the collection node, the service MUST NOT delete the child node but instead MUST simply sever the relationship between the deleted collection node and the child node.</li>
<li>If a child node will have no other parents after deletion of the collection node, the service MUST associate any orphaned child with no other node.</li>
<p>When the graph of the pubsub system is a Tree, a child node can have only one parent, which may be the root collection node. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>The service MUST associate any orphaned child with the root collection node.</li>
<p>When the graph of the pubsub system is a Forest, a child node can have only one parent but there is no root collection node. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>The service MUST associate any orphaned child with no other node.</li>
</ul>
</section3>
<section3topic='Strict Hierarchy or Strict Hierarchy Set'anchor='collections-delete-strict'>
<p>When the graph of the pubsub system is a Strict Hierarchy or a Strict Hierarchy Set, a child node can have only one parent node and cannot exist without its parent. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>The service SHOULD delete any orphaned child(ren).</li>
</ul>
<p>Note: This action may introduce cascading changes, since deletion of a child will result in deletion of any grandchildren, great-grandchildren, etc. A service MAY refuse to allow deletion of a collection node if doing so will result in an excessive load on the system. If it so refuses, it MUST return a &constraint; error.</p>
</section3>
<section3topic='Loose Hierarchy or Loose Hierarchy Set'anchor='collections-delete-loose'>
<p>When the graph of the pubsub system is a Loose Hierarchy or a Loose Hierarchy Set, a child node can have multiple parent nodes but a child node cannot exist without at least one parent node. Therefore, when a node owner deletes a collection node the service MUST behave as follows:</p>
<ul>
<li>If a child node will still have at least one other parent after deletion of the collection node, the service MUST NOT delete the child node but instead MUST simply sever the relationship between the deleted collection node and the child node.</li>
<li>If a child node will have no other parents after deletion of the collection node, the service SHOULD delete any orphaned child(ren).</li>
</ul>
<p>Note: This action may introduce cascading changes, since deletion of a child will result in deletion of any grandchildren, great-grandchildren, etc. A service MAY refuse to allow deletion of a collection node if doing so will result in an excessive load on the system. If it so refuses, it MUST return a &constraint; error.</p>
<section2topic='Associate an Existing Node with a Collection'anchor='collections-associate'>
<p>Although a node can be associated with a collection when it is created (as described above), it can also be associated with a collection after it has been created. This can be done in two ways:</p>
<ul>
<li>By modifying the node's "pubsub#collection" configuration field.</li>
<li>By modifying the collection node's "pubsub#children" configuration field.</li>
</ul>
<p>These methods are described below.</p>
<p>In order to modify the (child) node's "pubsub#collection" configuration field, the owner of the node shall submit a request to edit the node's configuration, receive a configuration form from the service, and then submit a modified configuration form:</p>
<p>Note: To associate a node with the root collection node, the node owner MUST submit an empty <value/> element within the 'pubsub#collection' field.</p>
<p>In order to modify the (parent) node's "pubsub#children" configuration field, the owner of the node shall submit a request to edit the node's configuration, receive a configuration form from the service, and then submit a modified configuration form:</p>
<p>If the collection node is configured to send notification of node associations and disassociations, the service shall send an event that contains a <collection/> element that in turns contains an <associate/> element whose 'id' attribute specifies the NodeID of the new node.</p>
<examplecaption='Notification of node association'><![CDATA[
<p>If an entity attempts to associate a node with a collection in a way that would violate the <linkurl='#collections-models'>node relationship model</link> (e.g., adding a second parent to a node in a Tree or Strict Hierarchy or making a child a new parent of its existing parent or other predecessor and thus violating the orientation of the graph), the service MUST return a &conflict; error.</p>
<section2topic='Disassociate a Node from a Collection'anchor='collections-disassociate'>
<p>A node can be disassociated from a collection after it has been associated (whether at creation time or afterward). This can be done in two ways:</p>
<ul>
<li>By modifying the node's "pubsub#collection" configuration field.</li>
<li>By modifying the collection node's "pubsub#children" configuration field.</li>
</ul>
<p>These methods are described below.</p>
<p>In order to modify the (child) node's "pubsub#collection" configuration field, the owner of the node shall submit a request to edit the node's configuration, receive a configuration form from the service, and then submit a modified configuration form:</p>
<p>Note: To disassociate the node from all collection nodes, the node owner MUST submit an empty <field/> element for the 'pubsub#collection' field as shown in the foregoing example.</p>
<p>Note: To disassociate the node from the root collection node, the node owner MUST submit an empty <value/> element within the 'pubsub#collection' field as shown in the foregoing example.</p>
<p>In order to modify the (parent) node's "pubsub#children" configuration field, the owner of the node shall submit a request to edit the node's configuration, receive a configuration form from the service, and then submit a modified configuration form:</p>
<p>If the collection node is configured to send notification of node associations and disassociations, the service shall send an event that contains a <collection/> element that in turns contains an <disassociate/> element whose 'id' attribute specifies the NodeID of the new node.</p>
<examplecaption='Notification of node disassociation'><![CDATA[
<p>If a node is disassociated from a collection node and a new association is not formed, the implementation MAY associate the node with the root collection node or associate it with no collection node.</p>
<p>Note: The combination of associating and disassociating a node with a collection can be used to move a node from one collection to another.</p>
</section2>
<section2topic='Generating Publish Notifications for Collections'anchor='collections-notify'>
<p>If an item is published to a node which is also included by a collection, and an entity is subscribed to that collection with a subscription type of "items", then the notifications generated by the service MUST contain additional information. The &ITEMS; element contained in the notification message MUST specify the node identifier of the node that generated the notification (not the collection) and the &ITEM; element MUST contain a SHIM header that specifies the node identifier of the collection.</p>
<examplecaption='Subscribers receive notifications from a collection'><![CDATA[
<p>Note: The delivery options (such as "pubsub#deliver_payloads") are determined by the publishing leaf node, not by the aggregating collection node. If the owner of a collection node sets delivery options for a collection node, the service SHOULD ignore those options and apply the options set for the leaf node that publishes an item.</p>
<p>Publish-subscribe functionality can be integrated into existing instant messaging and presence services (see <cite>RFC 3921</cite>), such that each registered account functions as a virtual pubsub service (sometimes called "pubsub-on-a-JID"). In such deployments, the root pubsub node for each virtual pubsub service has the same address as the bare JID &BAREJID; of the account, which is typically associated with an IM user (e.g., <hamlet@denmark.lit>). Since an IM user typically has a roster of "buddies" and shares presence information with those buddies, the virtual pubsub service can use roster and presence information to provide some helpful shortcuts for subscribers, in particular the auto-subscribe and filtered-notifications features described in this section.</p>
<p>Note: Because the account owner's bare JID functions as a virtual pubsub service, it is OPTIONAL for the owner to include a 'to' address when sending publish requests and completing other publisher and owner use cases. That is, when the IM server receives a pubsub-related IQ stanza of type "get" or "set" from one of the account owner's resources, the server MUST consider the stanza to be addressed to the account owner's bare JID even if the IQ stanza does not include a 'to' address.</p>
<p>When a contact is affiliated with the account owner through sharing of XMPP presence, the "auto-subscribe" feature greatly simplifies the subscription process. In particular, support for the "auto-subscribe" has the following implications:</p>
<p>Because the account owner itself is implicitly subscribed to its own XMPP presence (e.g., each XMPP resource receives presence information from all of the account owner's resources), a service MUST consider the account owner to have a pubsub subscription to the account owner's root collection node with a subscription_type of "items" and a subscription_depth of "all". This is true for all access models.</p>
<p>If an entity (i.e., an IM contact) has an XMPP presence subscription to the account owner's bare JID &BAREJID;, a service MUST consider the contact to have a pubsub subscription to the account owner's root collection node with a subscription_type of "items" and a subscription_depth of "all" if:</p>
<p>If the contact does not have permission to receive information from any of the account owner's particular nodes below the level of the root collection node (e.g., because a particular node has an access model of "roster" but the contact is not in the specified roster group), the service MUST NOT send notifications regarding that node to the contact and also MUST NOT return any errors to the contact regarding a potential implicit subscription to that node (e.g., the service MUST NOT return a pubsub subscription error to the contact when the contact sends presence to the account owner).</p>
<p>Note: When an IM contact has a subscription to the account owner's presence, the automated pubsub subscription MUST be based on the JID contained in the 'from' address of the presence subscription request, which for an IM contact will be a bare JID &BAREJID;.</p>
<p>If the node has an open access model, the pubsub service SHOULD also consider an entity to be temporarily and implicitly subscribed to the node if the entity sends presence to the account owner in the absence of a presence subscription. In this case, the subscription SHOULD be based on the 'from' address of the presence stanza, which will be a full JID &FULLJID;. When the service receives unavailable presence from the full JID, it MUST consider cancel the temporary subscription.</p>
<p>A contact may not want to receive notifications for all payload types. A contact SHOULD signal its preferences to the account owner's server by including <cite>XEP-0115</cite> information that specifies the namespaces for which the contact wishes to receive notifications (if any). This information is used by a pubsub service that supports the "filtered-notifications" feature to send only those payload types that the subscriber wishes to receive.</p>
<p>In order to make this possible, all possible payload namespaces can be appended with the string "+notify" to indicate that the contact wishes to receive notifications for the payload format. Thus if Romeo wants to receive notifications for location data and tune data but not activity data, his client would advertise support for the following namespaces in the disco#info results it sends: <note>Including, say, the 'http://jabber.org/protocol/geoloc' namespace indicates that the client understands the geolocation namespace, whereas including the 'http://jabber.org/protocol/geoloc+notify' namespace indicates that the client wishes to receive notifications related to geolocation.</note></p>
<p>This set of namespaces would then be advertised by including the namespace in the identity+features hash encapsulated via the 'ver' attribute as described in <cite>XEP-0115</cite>.</p>
<p>It is the responsibility of the account owner's server to cache <cite>XEP-0115</cite> information. When the server receives presence from a contact, it MUST check that presence information for entity capabilities data and correlate that data with the desired namespaces for the contact's client. The server MUST NOT send notifications related to any data formats that the contact's client has not asked for via the relevant "namespace+notify" disco#info feature. This enables a client to turn off all notifications (e.g., because of bandwidth restrictions) and to easily receive all desired data formats simply by adding support for the appropriate "namespace+notify" combination in its disco#info results and client capabililies. However, it also implies that a client can request notifications only on a global basis and cannot request, say, mood information only from certain contacts in the user's roster. Community consensus is that this is an acceptable tradeoff. Also, note that this works only if the account owner has a presence subscription to the contact and the contact has a presence subscription to the account owner.</p>
<p>Some examples may help to illustrate the concept of notification filtering. Here we show presence generated by two of the contacts listed above (benvolio@montague.lit does not have any presence subscriptions to or from juliet@capulet.lit and therefore is not involved in these protocol flows).</p>
<p>We assume that Juliet's server doesn't know anything about these capabilities, so it sends service discovery information requests to each of the clients on Juliet's behalf (realistically, the capulet.lit server will quickly build up a cache of client capabilities, with the result that it will not need to send these service discovery requests):</p>
<p>(As noted in <cite>XEP-0115</cite>, the server MUST check the hash provided in the 'ver' attribute against the generation method to ensure that no poisoning has occurred.)</p>
<p>Now we revisit account owner publication and server generation of notifications, with filtering enabled because the server has caps information:</p>
<ul>
<li><p>If Juliet publishes a tune item to the presence-access "http://jabber.org/protocol/tune" node, her server will send notifications to <nurse@capulet.lit/chamber> and <romeo@montague.lit/orchard> (full JIDs).</p></li>
<li><p>If Juliet publishes an activity item to the presence-access "http://jabber.org/protocol/activity" node, her server will send notifications only to <nurse@capulet.lit/chamber>.</p></li>
<li><p>If Juliet publishes a geolocation item to the roster-access "http://jabber.org/protocol/geoloc" node, her server will send notifications only to <romeo@montague.lit/orchard>.</p></li>
<p>This section summarizes the features described herein, specifies the appropriate requirements level for each feature (REQUIRED, RECOMMENDED, or OPTIONAL), and provides cross-references to the section of this document in which each feature is described.</p>
<p>Note: The feature names are all of the form "http://jabber.org/protocol/pubsub#name", where "name" is the text specified in the first column below.</p>
<td>A single leaf node may be associated with multiple collections.</td>
<td>OPTIONAL</td>
<td><linkurl='#collections-createassociated'>Create a Node Associated with a Collection</link> and <linkurl='#collections-associate'>Associate an Existing Node with a Collection</link></td>
</tr>
<tr>
<td>multi-subscribe</td>
<td>A single entity may subscribe to a node multiple times.</td>
<td>Notification of subscription state changes is supported.</td>
<td>OPTIONAL</td>
<td><linkurl='#impl-subchange'>Notification of Subscription State Changes</link></td>
</tr>
</table>
</section1>
<section1topic='Error Conditions'anchor='errors'>
<tablecaption='Error conditions and typical causes'>
<tr>
<th>Condition</th>
<th>Description</th>
</tr>
<tr>
<td>&conflict;</td>
<td>The node already exists.</td>
</tr>
<tr>
<td>&feature;</td>
<td>The operation being attempted on a node (or the system) has failed because the service or node does not support the operation; the error SHOULD also specify which feature is unsupported.</td>
</tr>
<tr>
<td>&forbidden;</td>
<td>An entity does not have sufficient privileges to perform the action, is requesting an operation for another Jabber ID (e.g., francisco@denmark.lit attempts to subscribe bernardo@denmark.lit to a node), or the requesting entity has an affiliation of "outcast".</td>
</tr>
<tr>
<td>¬found;</td>
<td>The node or item specified for some operation does not exist.</td>
</tr>
<tr>
<td>¬allowed;</td>
<td>An entity has attempted to perform an action which the service implements; however the service-wide admin or the node owner has disabled the action for that service or node.</td>
</tr>
<tr>
<td>¬authorized;</td>
<td>An entity has attempted to subscribe to or retrieve items from a node but is not authorized to see the account owner's presence, is not in the appropriate roster group, or is not on the whitelist for subscriptions.</td>
</tr>
<tr>
<td>&payment;</td>
<td>Subscriptions and item retrieval are based on some kind payment service. Payments would be done out-of-band using some agreed-upon method (not defined herein).</td>
</tr>
<tr>
<td>®istration;</td>
<td>Entities are required to register before node creation is allowed.</td>
<p>There are many possible triggers for sending a notification to an entity for the currently published item or the last published item, as summarized below:</p>
<li>The entity explicitly requests one or more items from the node and is authorized to retrieve items; when the service receives such a request, it sends the items to the entity.</li>
<li>The entity is an authorized subscriber to the node (explicitly via subscription or implicitly based on a role of owner or publisher); when the publisher sends a publish request, the service sends the currently published item to the entity (subject to presence checks and notification filtering if appropriate).</li>
<li>The entity is not subscribed but is eligible to do so and sends presence containing appropriate entity capabilities data to a service that supports filtered notifications (effectively establishing a "temporary subscription"); when the service receives such presence, it sends the last published item to the entity.</li>
<li>The entity is not subscribed but is eligible to do so and has sent presence containing appropriate entity capabilities data to a service that supports filtered notifications (effectively establishing a "temporary subscription"); when the publisher sends a publish request that matches the entity's expressed notification interests, the service sends the currently published item to the entity.</li>
<li>The entity gains access to the node because of a change to the node access model; as a result, the service sends the last published item to the entity.</li>
<li>The entity is added to the roster group associated with a node access model of "roster"; as a result, the service sends the last published item to the entity.</li>
<section2topic='Intended Recipients for Notifications'anchor='impl-recipients'>
<p>When a pubsub service generates notifications, it MUST adhere to the delivery rules implicit in the subscription option configuration for each subscriber. In particular, the 'to' address SHOULD be that of the subscribed JID only. The service SHOULD NOT attempt to guess at the most available resource associated with the subscribed JID (e.g., in the context of instant messaging systems).</p>
<p>As noted above, a pubsub service SHOULD ensure that the &MESSAGE; stanza for each event notification it generates possesses an 'id' attribute with a value. (This notification ID is not to be confused with either the node ID or the item ID.) This ID MUST be unique within the context of the pubsub service in order to ensure proper tracking of any delivery-related errors.</p>
<p>Exactly how a service shall handle delivery-related errors is a matter of implementation. In general, such handling is effectively similar to the bounce processing performed by other message delivery systems, such as mail transfer agents and mailing list software. The following are some suggested guidelines regarding the handling of XMPP-specific error conditions in relation to pubsub event notifications (see <cite>RFC 3920</cite> and <cite>XEP-0086</cite> regarding XMPP error condition semantics):</p>
<li>If the XMPP error is of type "cancel" (e.g., ¬found;), or the error condition is &gone;, the pubsub service SHOULD terminate the subscription of the entity to that node and MAY terminate the subscription of that entity to all nodes hosted at the service.</li>
<li>If the XMPP error is of type "auth" (e.g., ®istration;) or "wait" (e.g., &timeout;), or the error condition is &badrequest;, &redirect;, or ¬acceptable;, the pubsub service SHOULD increment a bounce counter for that entity and MAY attempt to resend the event notification after some configurable amount of time. The service MAY terminate the subscription of the entity to that node if the bounce counter has reached some configurable limit.</li>
</ul>
</section2>
<section2topic='Presence-Based Delivery of Events'anchor='impl-presence'>
<p>Implementations of pubsub MAY deliver event notifications only when the subscriber is online. In these cases, the option may be a node configuration option as shown in the examples above. To facilitate this, the pubsub service needs to subscribe to the subscriber's presence and check the subscriber's current presence information before sending any event notifications (as described in <cite>RFC 3921</cite>). Presence subscriptions MUST be based on the subscribed JID.</p>
</section2>
<section2topic='Not Routing Events to Offline Storage'anchor='impl-offline'>
<p>Sending events to users of existing Jabber servers may force event notifications to be routed to offline storage for later delivery (as described in &xep0160;). This may not always be desirable. The possible ways of preventing this behavior include:</p>
<li>Specify a message type of "headline", which in most existing server implementations will prevent offline storage.</li>
</ul>
</section2>
<section2topic='Including a Message Body'anchor='impl-body'>
<p>If a service understands the semantics for a particular payload type and an entity's subscription is so configured (via the "pubsub#include_body" option), the service SHOULD include an appropriate XMPP &BODY; child element along with the payloads it sends in event notifications for a given node, where the body's XML character data summarizes or represents the information contained in the payload (this enables clients that do not understand the payload format to present the appropriate information to an end user). For example, the Atom <summary/> element (see <cite>RFC 4287</cite>) could be mapped to the XMPP &BODY; element. A service MUST NOT provide the "pubsub#include_body" subscription option for a node if it does not have a defined way to transform part or all of the payload format into a sensible message body. A node owner MAY define an XSLT for transforming the payload format into a message body, via the "pubsub#body_xslt" node configuration option.</p>
<p>If the service does not understand the semantics for a particular payload type, it MAY include a <body/> child whose XML character data informs the subscriber that the message contains an event notification (e.g., text such as "This message contains an event notification" would be appropriate).</p>
</section2>
<section2topic='Node ID and Item ID Uniqueness'anchor='impl-uniqueness'>
<p>NodeIDs MUST be treated as unique identifiers within the context of a particular pubsub service.</p>
<p>If item identifiers are used, they MUST be treated as unique within the scope of the node. The combination of the NodeID + ItemID MUST be unique within a given service, and MUST specify a single published item at a single node.</p>
<p>If a publisher publishes an item and the ItemID matches that of an existing item, the pubsub service MUST overwrite the existing item and generate a new event notification.</p>
<p>Because it is possible for a node's configuration to change such that ItemIDs are required (e.g., a change from transient to persistent), a service SHOULD use ItemIDs for internal tracking purposes even if it does not include them with the notifications it generates prior to the configuration change.</p>
<p>A service MAY cache the last item published to a node, even if the node is configured for transient publication (i.e., configured to not persist items). The last published item SHOULD be sent to new subscribers upon successful processing of a subscription request or approval by a node owner.</p>
<p>Note: If a publisher requests <linkurl='#impl-batch'>Batch Processing</link> of item publications, the concept of "last published item" is undefined; therefore, if information coherence is needed, a publisher SHOULD publish items in separate requests rather than in batch mode.</p>
<p>Note: Particular profiles of the generic publish-subscribe protocol MAY define more stringent requirements regarding the "cache-last-item" feature.</p>
<p>A publisher MAY include multiple &ITEM; elements in a publish request and MAY include multiple &ITEM; elements in a retract request. This results in "batch processing" of publications or retractions.</p>
<p>If the service cannot process any one of the items to be published or retracted, the entire batch MUST fail and the service MUST NOT publish or retract any of the items.</p>
<p>If a batch publish contains so many items that publication of all the items would exceed the maximum number of items for the node, the service MUST return a ¬allowed; error, which SHOULD also include a pubsub-specific error condition of <max-items-exceeded/>.</p>
<p>Note: Batch publication renders the concept of "last published item" problematic; therefore, if information coherence is needed, a publisher SHOULD publish items in separate requests rather than in batch mode.</p>
<section2topic='Auto-Subscribing Owners and Publishers'anchor='impl-autosubscribe'>
<p>A service MUST allow owners and publishers to subscribe to a node, and to retrieve items from a node even if they are not subscribed. A service MAY auto-subscribe owners and publishers if they are not already subscribed, in which case it SHOULD generate a subscription ID if necessary for the subscription and SHOULD send a notification of successful subscription as described in the <linkurl='#impl-subchange'>Notification of Subscription State Changes</link> section of this document.</p>
<li>The service could subscribe to owner presence, and send only to the owners that are online.</li>
<li>All owners vote on the new subscriber.</li>
<li>Any owner is allowed to veto the subscriber.</li>
</ul>
<p>An implementation MAY use any of these methods, or some other method not defined herein.</p>
</section2>
<section2topic='Notification of Subscription State Changes'anchor='impl-subchange'>
<p>Various actions and events may result in changes to a subscription state:</p>
<ul>
<li><p>Approval or denial of a subscription request as described in the <linkurl='#owner-subreq'>Manage Subscription Requests</link> use case</p></li>
<li><p>Cancellation of an existing subscription, for which many "triggers" are possible:</p>
<ul>
<li>The entity simply unsubscribes from the node</li>
<li>The node is of type "presence" and the underlying presence subscription is cancelled</li>
<li>The node is of type "roster" and the entity is moved to an unauthorized roster group</li>
</ul>
</li>
</ul>
<p>When a subscription state change occurs, a service SHOULD send a message to the (new, former, or denied) subscriber informing it of the change, where the message contains an <event/> element with a single <subscription/> child that specifies the node, JID, and subscription state. The notification MAY contain a &BODY; element specifying natural-language text regarding the subscription change. Examples are shown below.</p>
<p>If the service has knowledge of the (former or denied) subscriber's presence, it SHOULD send the message to all of the subscriber's resources; if not, it MUST send the message to the subscriber's affiliated JID.</p>
<p>If a service or node supports this feature, it MUST return a feature of "subscription-notifications" in its response to service discovery information requests.</p>
<p>NodeIDs MAY have semantic meaning in particular profiles, implementations, or deployments of pubsub. However, it is STRONGLY RECOMMENDED that such semantic meaning not be used to encapsulate the hierarchical structure of nodes; instead, node hierarchy SHOULD be encapsulated using collections and their associated child nodes.</p>
<p>A user may publish information that adheres to a certain profile at multiple pubsub nodes, and a potential subscriber may want to discover all of these pubsub nodes. The user may make a list of pubsub nodes publicly available for querying even when the user is offline by using the Service Discovery mechanism for "publishing" items (see Section 4 of <cite>XEP-0030</cite>). The potential subscriber may then send a "disco#items" request to the user's bare JID (<user@host>), including the 'node' attribute set to the value of the namespace to which the desired information adheres. The user's server then returns a list of pubsub nodes that meet that criterion (with each pubsub node being a separate Service Discovery item). Here is an example.</p>
<p>Alternatively, a user may be registered with a server that offers personal eventing services, in which case the user will have one node per namespace as described in <cite>XEP-0163</cite>.</p>
<section2topic='Inclusion of SHIM Headers'anchor='impl-shim'>
<p>When SubIDs are used, <cite>Stanza Headers and Internet Metadata (SHIM)</cite> headers are to be included in order to differentiate notifications sent regarding a particular subscription. The relevant use cases and scenarios are:</p>
<ul>
<li>Sending notifications regarding newly-published items as described in the <linkurl='#publisher-publish'>Publish an Item to a Node</link> use case.</li>
<li>Sending notifications regarding deleted items as described in the <linkurl='#publisher-delete'>Delete an Item from a Node</link> use case.</li>
</ul>
<p>The SHIM headers are generated by the node to which the subscriber has a subscription, which may be either a leaf node or a collection node.</p>
<p>SHIM headers are not to be included when the content does not differ based on subscription ID, e.g., when a node sends notification of a configuration change to the node itself, notification that the node has been purged, or notification that the node has been deleted.</p>
</section2>
<section2topic='Associating Events and Payloads with the Generating Entity'anchor='impl-association'>
<p>An implementation MAY enable the node configuration to specify an association between the event notification and the entity to which the published information pertains, but such a feature is OPTIONAL. Here are some possible examples:</p>
<li>In the context of a geolocation notification service using &xep0080;, the user may generate the geolocation information or the information may be generated by an automated service (e.g., a service offered by a mobile telephony provider), but in either case the information is <em>about</em> the user's geolocation and therefore all replies should go to the user (who is probably the node owner).</li>
<li>In the context of a group weblog, different users might publish to the weblog and replies might go to the publisher of an entry rather than to the weblog owner.</li>
<li>In the context of an integrated pubsub and multi-user chat system, the node owner might be the room owner but all replies need to be sent to the room rather than to the owner.</li>
</ul>
<p>Therefore we define three node configuration options:</p>
<ul>
<li>pubsub#itemreply -- the per-item policy for replies (the value is "owner" or "publisher").</li>
<li>pubsub#replyto -- the specific user JID(s) to which replies should be sent, where the reply-to-JID information is provided by means of a &xep0033; header of type "replyto".</li>
<li>pubsub#replyroom -- the multi-user chat room to which replies should be sent, where the reply-to-room information is provided by means of an <cite>Extended Stanza Addressing</cite> header of type "replyroom".</li>
<p>Alternatively, if a service implements the personal eventing subset of this protocol, the virtual pubsub service is the account owner's bare JID and notifications are sent from that JID; for details, refer to <cite>XEP-0163</cite>.</p>
<p>The word "chaining" refers to the practice of subscribing one node to another node. For instance, consider a scenario in which the node <pubsub@example.net/NewsBroadcaster> wants to distribute information received from the node "NewsFeed" at <pubsub.example.com>. While it is theoretically possible for <pubsub@example.net/NewsBroadcaster> to directly subscribe to the NewsFeed node (since the former node is directly addressable as a JID), implementations MUST NOT chain nodes in this fashion. Instead, implementations MUST subscribe from the address of the pubsub service rather than the node (in the example shown here, the subscription would be sent from <pubsub@example.net> rather than <pubsub@example.net/NewsBroadcaster>).</p>
<p>In some systems it may be desirable to provide a subscription "leasing" feature in order to expire old or stale subscriptions. Leases can be implemented using configurable subscription options; specifically, when an entity subscribes, the service would require configuration of subscription options and the configuration form would contain a field of "pubsub#expire". This field MUST contain a dateTime (as specified in &xep0082;).</p>
<p>The service MAY send a message to the subscriber when the lease is almost over (e.g., 24 hours before the end of the lease term). This MUST be done by sending a &MESSAGE; containing a <subscription/> element qualified by the 'http://jabber.org/protocol/pubsub#event' namespace and including an 'expiry' attribute.</p>
<p>When the subscriber wants to renew the lease, it would get the current subscription options, change the value of the "pubsub#expire" field, and submit the new subscription options back to the service. If the new expire value exceeds the maximum value allowed for subscription leases, the service MUST change the value of the field to be the current date/time plus the maximum allowed lease period.</p>
<p>A service MAY enable entities to subscribe to nodes and apply a filter to notifications (e.g., keyword matching such as "send me all news entries from Slashdot that match the term 'Jabber'"). Such a content-based service SHOULD allow an entity to subscribe more than once to the same node and, if so, MUST use subscription identifiers (SubIDs) to distinguish between multiple subscriptions. In order to prevent collisions, a service that supports content-based subscriptions using SubIDs SHOULD generate SubIDs on behalf of subscribers rather than allowing subscribers to set their own SubIDs. <note>Another way to implement content-based subscriptions is to host one node per keyword or other filter; however, this is likely to require an extremely large number of nodes.</note></p>
<p>Content-based services SHOULD use subscription options to specify the filter(s) to be applied. Because there many possible filtering mechanisms (many of which may be application-specific), this document does not define any such method. However, filtering mechanisms may be defined in separate specifications.</p>
<p>For some nodes, it is desirable to have at most one item associated with the node at any one time (for example, a client may want to store its preferences using a node name that is a namespace controlled by that client). When this pattern is desired, it is RECOMMENDED for the publisher to specify an ItemID of "current" to ensure that the publication of a new item will overwrite the existing item.</p>
<p>The Data Forms shown in this specification include English-language labels for various fields; implementations that will display such forms to human users SHOULD provide localized label text for fields that are defined for the registered FORM_TYPEs.</p>
<p>Because the data published to a pubsub node may contain sensitive information (e.g., a user's geolocation), node owners SHOULD exercise care in approving subscription requests. Security considerations regarding particular kinds of information are the responsbility of the "using protocol".</p>
<p>A service MUST NOT allow non-owners or other unauthorized entities to complete any actions defined under the <linkurl='#owner'>Owner Use Cases</link> section of this document.</p>
<p>A service MUST adhere to the defined access model in determining whether to send event notifications or payloads to an entity, or allow an entity to retrieve items from a node. A service MAY enforce additional privacy and security policies when determining whether an entity is allowed to subscribe to a node or retrieve items from a node; however, any such policies shall be considered specific to an implementation or deployment and are out of scope for this document.</p>
<p>The XMPP Registrar includes a category of "pubsub" in its registry of Service Discovery identities (see &DISCOCATEGORIES;), as well as three specific types within that category:</p>
<td>A pubsub service that supports the functionality defined in XEP-0060. <note>Prior to version 1.5 of XEP-0060, this type was called "generic".</note></td>
<p>The XMPP Registrar maintains a registry of service discovery features (see &DISCOFEATURES;), which includes a number of features that may be returned by pubsub services. The following registry submission has been provided to the XMPP Registrar for that purpose.</p>
<p>XEP-0068 defines a process for standardizing the fields used within Data Forms scoped by a particular namespace, and the XMPP Registrar maintains a registry of such FORM_TYPES (see &FORMTYPES;). Within pubsub, there are four uses of such forms:</p>
<p>Note: There is no requirement that configuration fields need to be registered with the XMPP Registrar. However, as specified in Section 3.4 of <cite>XEP-0068</cite>, names of custom (unregistered) fields MUST begin with the characters "x-" if the form itself is scoped by a registered FORM_TYPE.</p>
<p>The XMPP Registrar includes "Collection" and "SubID" in its registry of SHIM headers (see &SHIMHEADERS;). The registry submission is as follows:</p>
<p>Future submissions to the XMPP Registrar may register additional SHIM headers that can be used in relation to the pubsub protocol, and such submission may occur without updating this specification.</p>
<p>The "pubsub" querytype is defined herein for interaction with pubsub services, with two keys: (1) "action" (whose defined values are "subscribe" and "unsubscribe") and (2) "node" (to specify a pubsub node).</p>
<p>Peter Millard, primary author of this specification from version 0.1 through version 1.7, died on April 26, 2006. The remaining co-authors are indebted to him for his many years of work on publish-subscribe technologies.</p>