JEP-0060: Publish-Subscribe

This JEP defines a generic publish/subscribe framework for use by Jabber entities.


NOTICE: The protocol defined herein is a Draft Standard of the Jabber Software Foundation. Implementations are encouraged and the protocol is appropriate for deployment in production systems, but some changes to the protocol are possible before it becomes a Final Standard.


JEP Information

Status: Draft
Type: Standards Track
Number: 0060
Version: 1.7
Last Updated: 2005-03-03
JIG: Standards JIG
Approving Body: Jabber Council
Dependencies: XMPP Core, JEP-0004, JEP-0030, JEP-0068, JEP-0082
Supersedes: None
Superseded By: None
Short Name: pubsub
XML Schema for pubsub: <http://jabber.org/protocol/pubsub/pubsub.xsd>
XML Schema for pubsub#event: <http://jabber.org/protocol/pubsub/event.xsd>
XML Schema for pubsub#owner: <http://jabber.org/protocol/pubsub/owner.xsd>
Wiki Page: <http://wiki.jabber.org/index.php/Publish-Subscribe (JEP-0060)>

Author Information

Peter Millard

See Author Note

Peter Saint-Andre

Email: stpeter@jabber.org
JID: stpeter@jabber.org

Ralph Meijer

Email: ralphm@ik.nu
JID: ralphm@ik.nu

Legal Notice

This Jabber Enhancement Proposal is copyright 1999 - 2006 by the Jabber Software Foundation (JSF) and is in full conformance with the JSF's Intellectual Property Rights Policy <http://www.jabber.org/jsf/ipr-policy.shtml>. This material may be distributed only subject to the terms and conditions set forth in the Creative Commons Attribution License (<http://creativecommons.org/licenses/by/2.5/>).

Discussion Venue

The preferred venue for discussion of this document is the Standards-JIG discussion list: <http://mail.jabber.org/mailman/listinfo/standards-jig>.

Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 3920) and XMPP IM (RFC 3921) specifications contributed by the Jabber Software Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this JEP has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.

Conformance Terms

The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.


Table of Contents

1. Introduction
2. Terminology
2.1. Publish-Subscribe Terms
3. Requirements
4. Addressing
5. Event Types
6. Affiliations
7. Subscription States
8. Use Cases
8.1. Entity Use Cases
8.1.1. Discover Service Features
8.1.2. Create a New Node
8.1.3. Publish an Item to a Node
8.1.4. Delete an Item from a Node
8.1.5. Subscribe to a Node
8.1.6. Approving and Denying Subscription Requests
8.1.7. Retrieve Current Affiliations
8.1.8. Unsubscribe from a Node
8.1.9. Configure Subscription Options
8.1.10. Get Items for a Node
8.1.11. Discover Nodes
8.1.12. Discover Node Information and Meta-Data
8.1.13. Discover Items for a Node
8.2. Owner Use Cases
8.2.1. Configure a Node
8.2.2. Request Default Configuration Options
8.2.3. Delete a Node
8.2.4. Purge All Node Items
8.2.5. Modifying Entity Affiliations
9. Collection Nodes
9.1. Subscribing to a Collection Node
9.2. Root Collection Node
9.3. Creating New Collection Nodes
9.4. Creating Nodes Affiliated with a Collection
9.5. Generating Publish Notifications for Collections
10. Error Conditions
11. Implementation Notes
11.1. Presence-Based Delivery of Events
11.2. Not Sending Events to Offline Storage
11.3. Node and Item ID Uniqueness
11.4. Authorizing Subscription Requests (Pending Subscribers)
11.5. Handling Node Hierarchies
11.6. Message Bodies
11.7. Multiple Node Discovery
11.8. Associating Events and Payloads with the Generating Entity
11.9. Implementing Time-Based Subscriptions (Leases)
11.10. Implementing Content-Based Pubsub Systems
12. Security Considerations
13. IANA Considerations
14. Jabber Registrar Considerations
14.1. Protocol Namespaces
14.2. Service Discovery Category/Type
14.3. Service Discovery Features
14.4. Field Standardization
14.4.1. pubsub#subscribe_authorization FORM_TYPE
14.4.2. pubsub#subscribe_options FORM_TYPE
14.4.3. pubsub#node_config FORM_TYPE
14.4.4. pubsub#meta-data FORM_TYPE
14.5. SHIM Headers
14.6. URI Query Types
15. XML Schemas
15.1. http://jabber.org/protocol/pubsub
15.2. http://jabber.org/protocol/pubsub#event
15.3. http://jabber.org/protocol/pubsub#owner
15.4. http://jabber.org/protocol/pubsub#errors
Notes
Revision History


1. Introduction

As Jabber technologies have matured, the need for a generic publish-subscribe ("pubsub") mechanism has arisen in a number of problem spaces. These include (but are not limited to): news feeds and content syndacation, avatar management, shared bookmarks, auction and trading systems, online catalogs, workflow systems, network management systems, NNTP gateways, vCard/profile management, and weblogs.

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 or the data itself 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 and/or the data itself 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 and/or data. Additionally, some nodes may also maintain a history of events and provide other services that supplement the pure pubsub model.

This Jabber Enhancement Proposal defines a single, cohesive, generic protocol which all forms of pubsub can utilize. While compliant implementations are not required to implement all of the features defined herein, this JEP documents most usages that may be requested of a pubsub service.

2. Terminology

2.1 Publish-Subscribe Terms

The following terms are used throughout this document to refer to elements, objects, or actions that occur in the context of a pubsub service.

Table 1: Glossary

Address (1) A JID as defined in XMPP Core [1], or (2) the combination of a JID and a Service Discovery [2] node.
Entity A JID-addressable Jabber entity (client, service, application, etc.).
Event A change in the state of a node.
Instant Node A node whose NodeID is automatically generated by a pubsub service.
Item An XML fragment which is published to a node, thereby generating an event.
ItemID A unique identifier for an item in the contect of a specific node.
Node 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").
Leaf A type of node that contains published items only. It is NOT a container for other nodes.
Collection A type of node that contains nodes and/or other collections but no published items. Collections provide the foundation entity to provide a means of representing hierarchial node structures.
NodeID The unique identifier for a node within the context of a pubsub service.
Notification A message sent to a subscriber informing them of an event.
Outcast An entity that is disallowed from subscribing or publishing to a node.
Owner The creator and manager of a node.
Payload The full data associated with an event (e.g., an RSS feed) rather than just the event itself.
Private A node to which subscriptions are limited by means of a whitelist.
Public A node to which any entity may subscribe.
Publisher An entity that is allowed to publish items to a node.
Pubsub Service An XMPP server or component that adheres to the protocol defined herein.
Subscriber An entity that is subscribed to a node.

3. Requirements

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 which implement a pure publish-subscribe pattern:

Some of the possible uses of a Jabber-based pubsub service will require other features, but these features are not mandatory for compliance with this specification. However, if these features are implemented, they MUST follow the protocol described herein to be compliant. These features include:

4. Addressing

If a pubsub node is addressable, it MUST be addressable either as (1) a JID or as (1) the combination of a JID and a Service Discovery node.

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/NodeID" and "user@domain/NodeID" are allowed; "NodeID@domain" is not allowed). 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 nodes via presence, it would address nodes as JIDs.

If a pubsub node is addressable as a Service Discovery 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). Note: A pubsub service MAY enable entities to discover pubsub nodes (and items associated with such nodes) via Service Discovery, but this is OPTIONAL.

5. Event Types

The requirements listed above 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.

A pubsub service MUST validate publish requests against the configuration of the node along both of these dimensions. See the publish use-case for specific error conditions based on a publish versus event-type mismatch. In addition, whether an item must be provided by the publisher, and whether an item ID is provided by the publisher or generated by the pubsub service, depends on the type of event being published. We can summarize the relevant rules as follows:

Table 2: Event Types, Items, and Item IDs

--> Notification Payload
Persistent Publisher MUST include an item element, which MAY be empty or contain a payload; if item ID is not provided by publisher, it MUST be generated by pubsub service Publisher MUST include an item element that contains the payload; if item ID is not provided by publisher, it MUST be generated by pubsub service
Transient Publisher MUST NOT include an item element (therefore item ID is neither provided nor generated) Publisher MUST include an item element that contains the payload, but the item ID is OPTIONAL

6. Affiliations

To manage permissions, the protocol defined herein uses a hierarchy of affiliations, similiar to those introduced in Multi-User Chat [3].

Table 3: Affiliations and their Privileges

Affiliation Subscribe Publish Items Purge Items Configure Node Delete Node Delete Item
Owner Yes Yes Yes Yes Yes Yes
Publisher Yes Yes No No No Yes/No
None Yes No No No No No
Outcast No No No No No No

Pubsub services 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 disoverable via the "pubsub#delete-any" feature. If a publisher is not allowed to delete an item, the service MUST bounce the request using a <not-authorized/> error.

Any Jabber entity which is currently subscribed to a node may unsubscribe from a node. All other entities which attempt to unsubscribe from a node MUST receive a <item-not-found/> error in response.

The ways in which an entity changes its affiliation with a node are well-defined. Typically, an owner action is required to make an affiliation state transition. Affiliation changes and their triggering actions are specified in the following table.

Table 4: Affiliation State Chart

--> Outcast None Publisher Owner
Outcast -- Owner removes ban Owner adds entity to publisher list Owner adds entity to owner list
None Owner bans entity -- Owner adds entity to publisher list Owner adds entity to owner list
Publisher Owner bans entity Owner removes entity from publisher list -- Owner adds entity to owner list
Owner n/a Owner resigns n/a --

7. Subscription States

Subscriptions to a node may exist in several states.

Table 5: Subscription States

Subscription State Description
None The node MUST NOT send event notifications or payloads to the Entity.
Pending 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.
Unconfigured 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.
Subscribed 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.

8. Use Cases

The following sections define the use cases and the protocol to be used by various actors in those use cases. The Implementation Notes section below describes many important factors and business rules which all pubsub services MUST observe. (Note: 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.)

8.1 Entity Use Cases

8.1.1 Discover Service Features

Pubub services MUST respond to feature queries using the Service Discovery protocol and scoped by the http://jabber.org/protocol/disco#info namespace. The disco#info result MUST indicate support for the features by using a feature element with the appropriate 'var' attribute. Throughout this document these features are noted, and have been registered with the Jabber Registrar as described in the Jabber Registrar Considerations section of this document.

8.1.2 Create a New Node

Implementations of pubsub SHOULD allow users and services to create new nodes, which other Jabber entities may then publish to or subscribe to (depending on permissions). However, implementations MAY disallow creation of nodes based on the identity of the entity trying to create the new node, or MAY disallow node creation altogether.

Nodes are created based on a NodeID supplied by the node creator. The NodeID MAY have semantic meaning, but such meaning is not required. If the requested NodeID already exists, the pubsub service MUST respond with a <conflict/> error. If the pubsub service does not support node creation, or the requesting JID does not have authorization to create nodes, the pubsub service MUST respond with a <feature-not-implemented/> error.

Implementations SHOULD allow node creation requests to contain a node configuration request in the same IQ element. (See the Configure a Node section below for more details.) If an entity wishes to accept the default configuration, it SHOULD include an empty <configure/> element in its node creation request.

The NodeID requested in the create node request MAY be modified by the service depending on the node-configuration specified. For example, if the node configuration requests that the new node become associated with a collection node, the service MAY create a node identifier which is not the same as the original ID requested. In this case, the service MUST return the modified NodeID in the IQ result, contained in a <create/> element whose 'node' attribute specifies the modified NodeID.

Some implementations MAY choose to force entities to register with the pubsub service before allowing nodes to be created. In these cases, the service MUST respond to the create request with a <registration-required/> error if the entity is not registered.

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 (i.e., the sender requested an "instant node" as described below), the service MUST specify the created NodeID in the IQ result. If the node creation request specified a NodeID but the service modified the NodeID before creating the node as described under the Collection Nodes 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 sender can determine which node was created by tracking the 'id' attribute that it provided in the IQ set).

Example 1. Entity requests a new node with default configuration.

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="create1">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
        <create node="generic/pgm-mp3-player"/>
        <configure/>
    </pubsub>
</iq>

Example 2. Server replies with success

<iq type="result"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="create1"/>

Example 3. Server replies with Conflict

<iq type="error"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="create1">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
        <create node="generic/pgm-mp3-player"/>
    </pubsub>
    <error code="409" type="cancel">
      <conflict xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    </error>
</iq>

Example 4. Server replies with Not Implemented

<iq type="error"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="create1">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
        <create node="generic/pgm-mp3-player"/>
    </pubsub>
    <error code="501" type="cancel">
      <feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    </error>
</iq>

Example 5. Server replies with Registration Required

<iq type="error"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="create1">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
        <create node="generic/pgm-mp3-player"/>
    </pubsub>
    <error code="407" type="auth">
      <registration-required xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    </error>
</iq>

In some cases, the requesting entity may want the service to automatically generate a unique NodeID for the newly-created node, to which it may immediately publish; we can think of this as an "instant node". To do this, the requesting entity MUST NOT include a NodeID in the request. If the user has permissions to create nodes, the pubsub service MUST create the node, generate a NodeID that is unique within the context of that pubsub service, and inform the user of success (including the NodeID). A service SHOULD support instant nodes; if it does not, it MUST return a <not-acceptable/> error.

Example 6. Client requests an instant node

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="create2">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
        <create/>
    </pubsub>
</iq>

Example 7. Server replies with success and generated NodeID

<iq type="result"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="create2">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
       <create
         node="generic/25e3d37dabbab9541f7523321421edc5bfeb2dae"/>
    </pubsub>
</iq>

Example 8. Server does not support instant nodes

<iq type="error"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="create2">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
       <create/>
    </pubsub>
    <error code="406" type="modify">
      <not-acceptable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    </error>
</iq>

8.1.3 Publish an Item to a Node

Any entity which is allowed to publish to a node (i.e., a publisher or an owner) may do so at any time. When the pubsub service receives the request, all (approved and active) subscribers are notified of the event. The node configuration MUST specify whether or not the payload is to be delivered to the subscribers. If payloads are not delivered with the event notification, subscribers MAY request the published item via the protocol defined in the Get Items for a Node section of this document.

An item MUST NOT contain data defined by more than one namespace, with the exception of item meta-data as described below.

When a publisher publishes a new item to a node, the service MUST validate that the publish request matches the event type node configuration. Specifically, if items are persistent, or payloads are delivered with event notifications, then the publish request MUST contain an item. If the node is configured for pure event notification, then the publish request MUST NOT contain an item. If a mismatch is detected, the service MUST bounce the packet with a <bad-request/> error.

In order to facilitate authorization for item removal as shown in the Delete an Item from a Node section below, implementations which support persistent items SHOULD store the item (if the node is so configured) and maintain a record of the publisher.

(Note: the following examples adhere to the payload format defined in User Tune [4]).

Example 9. Entity publishes an item with an ItemID

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="publish1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <publish node="generic/pgm-mp3-player">
      <item id="current">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Ralph Vaughan Williams</artist>
          <title>Concerto in F for Bass Tuba</title>
          <source>Golden Brass: The Collector's Edition</source>
        </tune>
      </item>
    </publish>
  </pubsub>
</iq>

Example 10. Server replies with success

<iq type="result"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="publish1"/>

Example 11. Entity is not authorized to publish to node

<iq type="error"
    from="pubsub.jabber.org"
    id="publish1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <publish node="generic/pgm-mp3-player">
      <item id="current">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Ralph Vaughan Williams</artist>
          <title>Concerto in F for Bass Tuba</title>
          <source>Golden Brass: The Collector's Edition</source>
        </tune>
      </item>
    </publish>
  </pubsub>
  <error code="401" type="auth">
    <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 12. Entity attempts to publish to a non-existent node

<iq type="error"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="publish1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <publish node="generic/pgm-mp3-player">
      <item id="current">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Ralph Vaughan Williams</artist>
          <title>Concerto in F for Bass Tuba</title>
          <source>Golden Brass: The Collector's Edition</source>
        </tune>
      </item>
    </publish>
  </pubsub>
  <error code="404" type="cancel">
    <item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

If the node is so configured, the subscribers will receive event notifications only.

Example 13. Subscribers receive event notifications only

<message to="subscriber1" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic/pgm-mp3-player">
      <item id="current"/>
    </items>
  </event>
</message>

<message to="subscriber2" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic/pgm-mp3-player">
      <item id="current"/>
    </items>
  </event>
</message>

If the node is so configured, the subscribers will receive both event notifications and payloads.

Example 14. Subscribers receive event notifications with payloads

<message to="subscriber1" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic/pgm-mp3-player">
      <item id="current">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Ralph Vaughan Williams</artist>
          <title>Concerto in F for Bass Tuba</title>
          <source>Golden Brass: The Collector's Edition</source>
        </tune>
      </item>
    </items>
  </event>
</message>

<message to="subscriber2" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic/pgm-mp3-player">
      <item id="current">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Ralph Vaughan Williams</artist>
          <title>Concerto in F for Bass Tuba</title>
          <source>Golden Brass: The Collector's Edition</source>
        </tune>
      </item>
    </items>
  </event>
</message>

Item identifiers are not mandatory and may not be necessary for many types of nodes. In these cases, when an item is published, it is put into the stack of items.

Example 15. Entity publishes an item without an ItemID

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="publish1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <publish node="generic/pgm-mp3-catalog">
      <item>
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Ralph Vaughan Williams</artist>
          <title>Concerto in F for Bass Tuba</title>
          <source>Golden Brass: The Collector's Edition</source>
        </tune>
      </item>
    </publish>
  </pubsub>
</iq>

Example 16. Server replies with success

<iq type="result"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="publish1"/>

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.

If a single entity is subscribed to a node multiple times, then the service SHOULD notate the event notification so that the entity can determine what subscription identifiers generated this event. If these notations are included, they MUST use the Stanza Headers and Internet Metadata (SHIM) [5] protocol and SHOULD be included after the event notification information (i.e., as the last child of the <message/> stanza).

Example 17. Subscriber receives notated event notification

<message to="subscriber1" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic/pgm-mp3-player">
      <item id="current"/>
    </items>
  </event>
  <headers xmlns='http://jabber.org/protocol/shim'>
    <header name="pubsub#subid">123-abc</header>
    <header name="pubsub#subid">004-yyy</header>
  </headers>
</message>

8.1.4 Delete an Item from a Node

A service SHOULD allow publishers to delete items once they have been published to a node that supports persistent items. To delete an item, the publisher sends a retract request as shown in the follow examples. This request may fail because:

Example 18. Entity deletes an item from a node

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="deleteitem1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <retract node="generic/pgm-mp3-player">
      <item id="current"/>
    </retract>
  </pubsub>
</iq>

Example 19. Server replies with success

<iq type="result"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="deleteitem1"/>

Example 20. Publisher is not authorized to delete this item

<iq type="error"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="deleteitem1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <retract node="generic/pgm-mp3-player">
      <item id="current"/>
    </retract>
  </pubsub>
  <error code="401" type="auth">
    <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 21. Publisher is trying to delete an item from a non-existent node

<iq type="error"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="deleteitem1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <retract node="generic/pgm-mp3-player">
      <item id="current"/>
    </retract>
  </pubsub>
  <error code="404" type="cancel">
    <item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 22. Publisher is trying to delete an item from a node which does not support persistent items

<iq type="error"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="deleteitem1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <retract node="generic/pgm-mp3-player">
      <item id="current"/>
    </retract>
  </pubsub>
  <error code="405" type="cancel">
    <not-allowed xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 23. Service does not support deleting items

<iq type="error"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="deleteitem1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <retract node="generic/pgm-mp3-player">
      <item id="current"/>
    </retract>
  </pubsub>
  <error code="501" type="cancel">
    <feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

If an implementation supports allowing subscribers to be notified of deleted items (and the node is configured for it), the service MUST use message notifications as shown below. The syntax is identical to publish notifications except that instead of <item/> elements, we have <retract/> elements.

Example 24. Subscribers are notified of deletion

<message to="subscriber1" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic/pgm-mp3-player">
      <retract id="current"/>
    </items>
  </event>
</message>

<message to="subscriber2" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic/pgm-mp3-player">
      <retract id="current"/>
    </items>
  </event>
</message>

8.1.5 Subscribe to a Node

When a Jabber entity wishes to subscribe to a node, it sends an IQ request to the pubsub service. Depending on the configuration of the node, several things may happen. If the node has "open" subscriptions, the potential subscriber receives either a result or an error. If the node has been configured so that subscription requests must be approved by the node owner (or a designated approver), the pubsub service sends a message to the node owner requesting authorization, where the message contains a form that is structured in accordance with the Data Forms [6] protocol. To approve the subscription request, the node owner MUST submit the form. To deny the request, the owner MUST cancel the form.

Subscription requests to a node MUST contain a 'jid' attribute, which enables the subscriber to specify either a bare JID or a specific resource which should be used as the subscribed Jabber ID. Implementations MUST at a minimum check the bare JID requested against the 'from' attribute on the received packet 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. (Naturally, JIDs of the form <domain> and <domain/resource> may subscribe as well.)

Some implementations MAY allow a service-configured list of entities (Jabber IDs) which are excluded from this check. Those entities may be treated as trusted proxies which are allowed to subscribe on behalf of other users. In the same way, implementations may enable blacklisting of entities based on Jabber ID which are not allowed to perform specific operations.

Services MAY allow entities to subscribe multiple times to the same node. This enables an entity to subscribe using different subscription options. If multiple subscriptions for the same JID is allowed, the service MUST use the 'subid' attribute to differentiate between subscriptions for the same entity. The SubID MUST be present on the entity element any time it is sent to the entity. 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).

If an entity attempts to subscribe with a JID that is not allowed (bare JIDs do not match, or the user does not have some kind of admin or proxy privilege as defined by the implementation), then the pubsub service MUST respond with a <not-authorized/> error.

Commercial deployments may wish to allow subscribers to be linked to some kind of paying customer database. 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-required/> error to the subscriber.

Example 25. Entity subscribes to a node

<iq type="set"
    from="sub1@foo.com/home"
    to="pubsub.jabber.org"
    id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <subscribe
        node="generic/pgm-mp3-player"
        jid="sub1@foo.com"/>
  </pubsub>
</iq>

Example 26. Server replies with success

<iq type="result"
    from="pubsub.jabber.org"
    to="sub1@foo.com/home"
    id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <entity node="generic/pgm-mp3-player"
            jid="sub1@foo.com"
            affiliation="none"
            subid="123-abc"
            subscription="subscribed"/>
  </pubsub>
</iq>

Example 27. Entity is not authorized to create a subscription

<iq type="error"
    from="pubsub.jabber.org"
    to="sub1@foo.com/home"
    id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <subscribe
        node="generic/pgm-mp3-player"
        jid="sub1@foo.com"/>
  </pubsub>
  <error code="401" type="auth">
    <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 28. Payment is required for a subscription

<iq type="error"
    from="pubsub.jabber.org"
    to="sub1@foo.com/home"
    id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <subscribe
        node="generic/pgm-mp3-player"
        jid="sub1@foo.com"/>
  </pubsub>
  <error code="402" type="auth">
    <payment-required xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 29. Server replies with node not found

<iq type="error"
    from="pubsub.jabber.org"
    to="sub1@foo.com/home"
    id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <subscribe
        node="generic/pgm-mp3-player"
        jid="sub1@foo.com"/>
  </pubsub>
  <error code="404" type="cancel">
    <item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 30. Server replies with pending (owner must approve subscription request)

<iq type="result"
    from="pubsub.jabber.org"
    to="sub1@foo.com/home"
    id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <entity node="generic/pgm-mp3-player"
            jid="sub1@foo.com"
            affiliation="none"
            subid="123-abc"
            subscription="pending"/>
  </pubsub>
</iq>

8.1.6 Approving and Denying Subscription Requests

Pubsub services MAY send approval requests to the current approver (typically the node owner) at any time. As such, these are simple message stanzas which contain a Data Form. The node owner MAY also request the current pending subscriptions at any time. Implementations MUST use the Ad-Hoc Commands [7] protocol to request the pending list. The command name (node attribute of the command element) MUST have a value of "http://jabber.org/protocol/pubsub#get-pending". The command MUST take a single field argument with a 'var' attribute value of "node". This field MUST contain the desired NodeID. The node field SHOULD be a list-single field which contains all of the NodeIDs for which the requestor has approval privileges.

If an entity which does not have sufficient permissions to approve subscription requests attempts to get the current pending list, the service MUST respond with a <forbidden/> error message. If the node requested in the node field does not exist, the service MUST respond with a <item-not-found/> error message.

When subscription approval messages are sent to the current approver (typically, the node owner), the form MUST contain a hidden field element which uses a 'var' attribute of FORM_TYPE, and a value of "http://jabber.org/protocol/pubsub" as specified in Field Standardization for Data Forms [8]. This enables client applications to detect that this is a pubsub subscriber request, and, if desired, to use some non-standard jabber:x:data dialog. 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. This field MUST be checked when the form is processed after submission to see if the subscription should be allowed or denied. If the approver cancels the Data Form, then the subscription request MUST remain in the pending list. The Data Form sent to the approver SHOULD include fields to show the node identifier, the subscription id (if applicable), and the JID of the pending subscriber.

Example 31. Owner requests pending subscription requests

<iq type="set" to="pubsub.jabber.org" id="pending1">
    <command xmlns="http://jabber.org/protocol/commands"
             node="http://jabber.org/protocol/pubsub#get-pending"
             action="execute"/>
</iq>

Example 32. Server responds with data form to be populated

<iq type="result" to="pubsub.jabber.org" id="pending1">
    <command xmlns="http://jabber.org/protocol/commands"
             sessionid="pubsub-get-pending:20031021T150901Z-600"
             node="http://jabber.org/protocol/pubsub#get-pending"
             status="executing"
             action="execute">
        <x xmlns="jabber:x:data" type="form">
            <field type="list-single"
                   var="pubsub#node">
                <option><value>generic/pgm-mp3-player</value></option>
                <option><value>generic/pgm-geoloc</value></option>
                <option><value>generic/pgm-avatar</value></option>
            </field>
        </x>
    </command>
</iq>

Example 33. Server responds with forbidden

<iq type="error" from="pubsub.jabber.org" id="pending2">
    <error code="403" type="cancel">
      <forbidden xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    </error>
</iq>

Example 34. Server responds with node not found

<iq type="error" from="pubsub.jabber.org" id="pending2">
    <error code="404">
      <item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    </error>
</iq>

Example 35. Owner requests all pending subscription requests for a node

<iq type="set" to="pubsub.jabber.org" id="pending2">
    <command xmlns="http://jabber.org/protocol/commands"
             sessionid="pubsub-get-pending:20031021T150901Z-600"
             node="http://jabber.org/protocol/pubsub#get-pending"
             action="execute">
        <x xmlns="jabber:x:data" type="submit">
            <field var="pubsub#node">
                <value>generic/pgm-mp3-player</value>
            </field>
        </x>
    </command>
</iq>

Example 36. Server responds with success

<iq type="result" from="pubsub.jabber.org" id="pending2"/>

Example 37. Server sends authorization request to node owner

<message to="node-owner" from="pubsub.jabber.org">
    <x xmlns="jabber:x:data" type="form">
        <title>PubSub subscriber request</title>
        <instructions>
          To approve this entity&apos;s subscription request,
          click the OK button. To deny the request, click the
          cancel button.
        </instructions>
        <field var="FORM_TYPE" type="hidden">
            <value>http://jabber.org/protocol/pubsub#subscribe_authorization</value>
        </field>
        <field var="pubsub#subid"
               type="hidden">
            <value>123-abc</value>
        </field>
        <field var="pubsub#node"
               type="text-single"
               label="Node ID">
            <value>generic/pgm-mp3-player</value>
        </field>
        <field var="pusub#subscriber_jid"
               type="jid-single"
               label="Subscriber Address">
            <value>sub1@foo.com</value>
        </field>
        <field var="pubsub#allow"
               type="boolean"
               label="Allow this JID to subscribe to this pubsub node?">
            <value>0</value>
        </field>
    </x>
</message>

Example 38. Owner approves subscription request

<message from="node-owner" to="pubsub.jabber.org">
    <x xmlns="jabber:x:data" type="submit">
        <field var="FORM_TYPE" type="hidden">
           <value>http://jabber.org/protocol/pubsub#subscribe_authorization</value>
        </field>
        <field var="pubsub#subid">
           <value>123-abc</value>
        </field>
        <field var="pubsub#node">
           <value>generic/pgm-mp3-player</value>
        </field>
        <field var="pubsub#subscriber_jid">
           <value>sub1@foo.com</value>
        </field>
        <field var="pubsub#allow">
            <value>1</value>
        </field>
    </x>
</message>

Example 39. Owner denies subscription request

<message from="node-owner" to="pubsub.jabber.org">
    <x xmlns="jabber:x:data" type="submit">
        <field var="FORM_TYPE" type="hidden">
           <value>http://jabber.org/protocol/pubsub#subscribe_authorization</value>
        </field>
        <field var="pubsub#subid">
           <value>123-abc</value>
        </field>
        <field var="pubsub#node">
           <value>generic/pgm-mp3-player</value>
        </field>
        <field var="pubsub#subscriber_jid">
           <value>sub1@foo.com</value>
        </field>
        <field var="pubsub#allow">
            <value>0</value>
        </field>
    </x>
</message>

The service would then send a message with extended information in the 'jabber:x:data' namespace for all pending subscription requests, as shown above for a single pending subscription request.

8.1.7 Retrieve Current Affiliations

Entities SHOULD be allowed to query the service to provide all of the current affiliations for all nodes within that service for that entity. The affiliations element is used to make the request. For each affiliation, an entity element is returned containing the NodeID, the JID which is affiliated (MAY include a resource, depending on how the JID subscribed), the affiliation, and the current subscription state. If subscription identifiers are supported by the service and the entity's subscription is not NONE or OUTCAST, the 'subid' attribute MUST be present as well as the 'jid' attribute.

Example 40. Entity requests all current affiliations

<iq type="get"
    from="sub1@foo.com"
    to="pubsub.jabber.org"
    id="allsubs">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <affiliations/>
  </pubsub>
</iq>

Example 41. Service replies with all current affiliations

<iq type="result"
    from="pubsub.jabber.org"
    to="sub1@foo.com"
    id="allsubs">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <affiliations>
      <entity node="node1"
              jid="sub1@foo.com"
              affiliation="owner"
              subid="sub1"
              subscription="subscribed"/>
      <entity node="node2"
              jid="sub1@foo.com"
              affiliation="publisher"
              subid="sub2"
              subscription="subscribed"/>
      <entity node="node3"
              jid="sub1@foo.com/pda"
              affiliation="none"
              subid="sub3"
              subscription="unconfigured"/>
      <entity node="node4"
              jid="sub1@foo.com/work"
              affiliation="none"
              subid="sub4"
              subscription="pending"/>
      <entity node="node5"
              jid="sub1@foo.com"
              affiliation="outcast"
              subscription="none"/>
      <entity node="node6"
              jid="sub1@foo.com"
              affiliation="owner"
              subscription="none"/>
    </affiliations>
  </pubsub>
</iq>

8.1.8 Unsubscribe from a Node

To unsubscribe from a node, the subscriber sends an appropriately-formatted IQ request to the node in question. If the unsubscribe is successful, an IQ result is sent back. 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-request/> and which SHOULD also include a <not-subscribed/> child qualified by the 'http://jabber.org/protocol/pubsub#errors' namespace. If the requestor is not authorized to unsubscribe the specified JID, the service MUST return a <not-authorized/> error. If the node does not exist, the pubsub service MUST return a <item-not-found/> error. If a subscription identifier is associated with the subscription (ie, the service supports them), the unsubscribe request MUST include the 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), then the service SHOULD ignore the SubID and simply unsubscribe the entity. If subscriber originally subscribed with a SubID but the unsubscribe request includes a SubID other that is not valid or current for the subscriber, the service MUST return a <not-acceptable/> error.

Example 42. Entity unsubscribes from a node

<iq type="set"
    from="sub1@foo.com"
    to="pubsub.jabber.org"
    id="unsub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
     <unsubscribe
         node="generic/pgm-mp3-player"
         subid="123-abc"
         jid="sub1@foo.com"/>
  </pubsub>
</iq>

Example 43. Server replies with success

<iq type="result"
    from="pubsub.jabber.org"
    to="sub1@foo.com"
    id="unsub1"/>

Example 44. Requestor is not a subscriber

<iq type="error"
    from="pubsub.jabber.org"
    to="sub1@foo.com"
    id="unsub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
     <unsubscribe
         node="generic/pgm-mp3-player"
         subid="123-abc"
         jid="sub1@foo.com"/>
  </pubsub>
  <error code="401" type="auth">
    <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <not-subscribed xmlns="http://jabber.org/protocol/pubsub#errors"/>
  </error>
</iq>

Example 45. Node does not exist

<iq type="error"
    from="pubsub.jabber.org"
    to="sub1@foo.com"
    id="unsub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
     <unsubscribe
         node="generic/pgm-mp3-player"
         subid="123-abc"
         jid="sub1@foo.com"/>
  </pubsub>
  <error code="404" type="cancel">
    <item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 46. Invalid subscription identifier

<iq type="error"
    from="pubsub.jabber.org"
    to="sub1@foo.com"
    id="unsub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
     <unsubscribe
         node="generic/pgm-mp3-player"
         subid="123-abc"
         jid="sub1@foo.com"/>
  </pubsub>
  <error code="406" type="modify">
    <not-acceptable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

8.1.9 Configure Subscription Options

Implementations MAY allow subscribers to configure options for their own subscription. Implementations SHOULD use the Data Forms protocol to accomplish this configuration. A subscriber requests the subscription options by using the <options/> element inside of an IQ stanza, to which the service MUST respond with either an error (detailed below) or a result element containing the options.

If a service supports subscription options it MUST advertise that fact in the result to a disco#info query by including a feature whose 'var' attribute is "pubsub#subscription-options". If a service supports subscription options, an entity MAY subscribe and provide the subscription options in the same stanza. In this case, the subscribe-options element MUST be a sibling of the subscribe element on the subscribe request. (If the service does not support subscription options, is MUST return a <feature-not-implemented/> error.)

When requesting subscription options, the subscriber MUST specify both the NodeID of the node and the JID which is subscribed to the node. Services 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 <user@host/resource>, a services SHOULD perform this check by comparing the user@host part of the two JIDs to ensure that they match. 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 a node supports subscription options, it MUST return a <subscribe-options> element inside the entity element in the result of the subscription request. The subscribe-options element MAY contain a <required/> child element if the subscriber MUST configure the subscription before receiving any notifications from that event. Services MAY timeout 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). If the jabber:x:data <required/> element is not present, the subscription takes effect immediately and enables the entity to configure the subscription at any time.

The following example shows some (but by no means all) of the possible configuration options which MAY be implemented in implementations. If an implementation implements these options using the Data Forms protocol, that implementation MUST use the field variables that are registered with the Jabber Registrar in association with the 'http://jabber.org/protocol/pubsub' namespace (a preliminary representation of those field variables is shown below, but MUST NOT be construed as canonical, since the Jabber Registrar may standardize additional fields at a later date without changes to this JEP). An implementation MAY choose to specify different labels, values, and even field types, but must conform to the defined variable naming scheme.

If nodes or services do not support subscriber options, then the response for an options request MUST be a <feature-not-implemented/> error. If a subscriber attempts to set an invalid group of options, the service MUST respond with a <bad-request/> error.

Example 47. Entity subscribes to a node

<iq type="set"
    from="sub1@foo.com/home"
    to="pubsub.jabber.org"
    id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <subscribe
        node="generic/pgm-mp3-player"
        jid="sub1@foo.com"/>
  </pubsub>
</iq>

Example 48. Server replies with success and indicates that subscription configuration is required

<iq type="result"
    from="pubsub.jabber.org"
    to="sub1@foo.com/home"
    id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <entity node="generic/pgm-mp3-player"
            jid="sub1@foo.com"
            affiliation="none"
            subid="123-abc"
            subscription="unconfigured">
      <subscribe-options>
        <required/>
      </subscribe-options>
    </entity>
  </pubsub>
</iq>

Example 49. Subscriber requests subscription options form

<iq type="get"
    from="sub1@foo.com/home"
    to="pubsub.jabber.org"
    id="options1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <options
        node="generic/pgm-mp3-player"
        subid="123-abc"
        jid="sub1@foo.com"/>
  </pubsub>
</iq>

Example 50. Server responds with Not Implemented (subscription options not supported)

<iq type="error"
    from="pubsub.jabber.org"
    to="sub1@foo.com/home"
    id="options1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <options
        node="generic/pgm-mp3-player"
        subid="123-abc"
        jid="sub1@foo.com"/>
  </pubsub>
  <error code="501" type="cancel">
    <feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <subscription-options-unavailable 
        xmlns="http://jabber.org/protocol/pubsub#errors"/>
  </error>
</iq>

Example 51. Server responds with the options form

<iq type="result"
    from="pubsub.jabber.org"
    to="sub1@foo.com/home"
    id="options1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <options node="generic/pgm-mp3-player"
             jid="sub1@foo.com"
             subid="123-abc">
        <x xmlns="jabber:x:data">
          <field var="FORM_TYPE" type="hidden">
            <value>http://jabber.org/protocol/pubsub#subscribe_options</value>
          </field>
          <field var="pubsub#digest" type="boolean"
                 label="Receive digest notifications (approx. one per day)">
            <value>0</value>
          </field>
          <field
              var="pubsub#show-values"
              type="list-multi"
              label="Select the presence types which are 
                     allowed to receive notifications">
            <option label="Want to Chat"><value>chat</value></option>
            <option label="Available"><value>online</value></option>
            <option label="Away"><value>away</value></option>
            <option label="Extended Away"><value>xa</value></option>
            <option label="Do Not Disturb"><value>dnd</value></option>
            <value>chat</value>
            <value>online</value>
          </field>
        </x>
     </options>
  </pubsub>
</iq>

Example 52. Subscriber returns completed options form

<iq type="set"
    from="sub1@foo.com/home"
    to="pubsub.jabber.org"
    id="options2">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <options node="generic/pgm-mp3-player"
             jid="sub1@foo.com"
             subid="123-abc">
        <x xmlns="jabber:x:data">
          <field var="FORM_TYPE" type="hidden">
            <value>http://jabber.org/protocol/pubsub#subscribe_options</value>
          </field>
          <field var="pubsub#digest" type="boolean"><value>0</value></field>
          <field var="pubsub#show-values" type="list-multi">
            <value>chat</value>
            <value>online</value>
            <value>away</value>
          </field>
        </x>
     </options>
  </pubsub>
</iq>

Example 53. Server responds with success

<iq type="result"
    from="pubsub.jabber.org"
    to="sub1@foo.com/home"
    id="options2"/>

Example 54. Server responds with Bad Request for invalid options

<iq type="error"
    from="pubsub.jabber.org"
    to="sub1@foo.com/home"
    id="options2">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <options node="generic/pgm-mp3-player"
             subid="123-abc"
             jid="sub1@foo.com">
        <x xmlns="jabber:x:data">
          <field var="FORM_TYPE" type="hidden">
            <value>http://jabber.org/protocol/pubsub#subscribe_options</value>
          </field>
          <field var="pubsub#digest" type="boolean"><value>0</value></field>
          <field var="pubsub#show-values" type="list-multi">
            <value>chat</value>
            <value>online</value>
            <value>away</value>
          </field>
        </x>
     </options>
  </pubsub>
  <error code="400" type="modify">
    <bad-request xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <invalid-options xmlns="http://jabber.org/protocol/pubsub#errors"/>
  </error>
</iq>

8.1.10 Get Items for a Node

Implementations of pubsub that choose to persist items MAY allow entities to request existing items from a node. Entities may wish to do this after successfully subscribing to a node in order to receive all the items that are in the publishing "history" for that node. When an entity requests items, the pubsub service SHOULD verify that the requesting entity has a subscription to the pubsub node. If a subscription identifier is associated with a specific subscription, the entity MUST append the 'subid' attribute to the items element when making the request (if it does not, the service SHOULD return a <not-acceptable/> error). This attribute allows the pubsub service to generate different sets of items based on the subscription options associated with a specific subscription.

Subscribers may also receive event notification without any payload information. In this case, the client may request the item that was published (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. Implementations MAY also 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.

Example 55. Subscriber requests all active items

<iq type="get"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="items1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <items node="generic/pgm-mp3-player" subid="123-abc"/>
  </pubsub>
</iq>

Example 56. Server sends items back

<iq type="result"
    from="pubsub.jabber.org"
    id="items1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <items node="generic/pgm-mp3-player" subid="123-abc">
      <item id="item1">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Ralph Vaughan Williams</artist>
          <title>Concerto in F for Bass Tuba</title>
          <source>Golden Brass: The Collector's Edition</source>
        </tune>
      </item>
      <item id="item2">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Edward Gregson</artist>
          <title>Tuba Concerto</title>
          <source>Tuba Tones</source>
        </tune>
      </item>
      <item id="item3">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Walter Ross</artist>
          <title>Tuba Concerto</title>
          <source>The Tuba's Greatest Hits</source>
        </tune>
      </item>
    </items>
  </pubsub>
</iq>

Example 57. Service does not support persistent items

<iq type="error"
    from="pubsub.jabber.org"
    id="items1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <items node="generic/pgm-mp3-player" subid="123-abc"/>
  </pubsub>
  <error code="501" type="cancel">
    <feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <persistence-unavailable xmlns="http://jabber.org/protocol/pubsub#errors"/>
  </error>
</iq>

Example 58. Subscriber requests two most recent items

<iq type="get"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="items2">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <items node="generic/pgm-mp3-player" max_items="2" subid="123-abc"/>
  </pubsub>
</iq>

Example 59. Server returns two most recent items

<iq type="result"
    from="pubsub.jabber.org"
    id="items2">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <items node="generic/pgm-mp3-player" subid="123-abc">
      <item id="item2">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Edward Gregson</artist>
          <title>Tuba Concerto</title>
          <source>Tuba Tones</source>
        </tune>
      </item>
      <item id="item3">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Walter Ross</artist>
          <title>Tuba Concerto</title>
          <source>The Tuba's Greatest Hits</source>
        </tune>
      </item>
    </items>
  </pubsub>
</iq>

Example 60. Subscriber requests specific items by ItemID

<iq type="get"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="items3">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <items node="generic/pgm-mp3-player" subid="123-abc">
      <item id="item1"/>
      <item id="item3"/>
    </items>
  </pubsub>
</iq>

Example 61. Server sends requested item(s)

<iq type="result"
    from="pubsub.jabber.org"
    id="items3">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <items node="generic/pgm-mp3-player" subid="123-abc">
      <item id="item1">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Ralph Vaughan Williams</artist>
          <title>Concerto in F for Bass Tuba</title>
          <source>Golden Brass: The Collector's Edition</source>
        </tune>
      </item>
      <item id="item3">
        <tune xmlns="http://jabber.org/protocol/tune">
          <artist>Walter Ross</artist>
          <title>Tuba Concerto</title>
          <source>The Tuba's Greatest Hits</source>
        </tune>
      </item>
    </items>
  </pubsub>
</iq>

Example 62. Subscriber sends request without subid

<iq type="get"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="items5">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <items node="generic/pgm-mp3-player"/>
  </pubsub>
</iq>

Example 63. Subid required

<iq type="error"
    from="pubsub.jabber.org"
    id="items5">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <items node="generic/pgm-mp3-player"/>
  </pubsub>
  <error code="406" type="modify">
    <not-acceptable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

8.1.11 Discover Nodes

A service MAY implement some kind of pubsub browsing mechanism which enables the user to discover various nodes. The user may then select nodes to which he or she is interested in subscribing. Entities SHOULD use the Service Discovery protocol for node discovery, subject to the recommendations in JEP-0030 regarding large result sets (for which Jabber Search [9] or some other protocol SHOULD be used). The examples show the protocol for possible results when using Service Discovery on a hierarchical pubsub service.

Example 64. A client discovers all first level nodes

<iq type="get"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="nodes1">
    <query xmlns="http://jabber.org/protocol/disco#items"/>
</iq>

<iq type="result"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="nodes1">
    <query xmlns="http://jabber.org/protocol/disco#items">
        <item jid="pubsub.jabber.org"
              node="generic"
              name="A place for generic nodes"/>
        <item jid="pubsub.jabber.org"
              node="bar"
              name="A place for drinks"/>
        <item jid="pubsub.jabber.org"
              node="fez"
              name="A place for hats"/>
    </query>
</iq>

Example 65. A client drills down to second level nodes

<iq type="get"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="nodes2">
    <query xmlns="http://jabber.org/protocol/disco#items" node="generic"/>
</iq>

<iq type="result"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="nodes2">
    <query xmlns="http://jabber.org/protocol/disco#items"
           node="generic">
        <item jid="pubsub.jabber.org"
              node="generic/pgm-mp3-player"/>
        <item jid="pubsub.jabber.org"
              node="generic/psa-mp3-player"/>
        <item jid="pubsub.jabber.org"
              node="generic/slashdot-news"/>
        <item jid="pubsub.jabber.org"
              node="generic/meerkat-news"/>
    </query>
</iq>

8.1.12 Discover Node Information and Meta-Data

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 results MUST include an identity with a category of pubsub and a type of either leaf or collection. If a specific node has an identity type of leaf, then it MUST contain individual items. If a specific node has an identity type of collection, then it MUST contain other nodes and/or collections but MUST NOT contain items.

The disco#info result MAY include detailed metadata about the node, encapsulated in the Data Forms (JEP-0004) format as described in Service Discovery Extensions [10], where the data form context is specified by including a FORM_TYPE of "http://jabber.org/protocol/pubsub#meta-data" in accordance with JEP-0068. 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.

Example 66. Entity Queries a node for information and meta-data

<iq type="get" to="pubsub.jabber.org" from="entity1" id="meta-1">
  <query xmlns="http://jabber.org/protocol/disco#info"
         node="generic/pgm-mp3-player"/>
</iq>

Example 67. Service responds with information and meta-data

<iq type="result" from="pubsub.jabber.org" to="entity1">
  <query xmlns="http://jabber.org/protocol/disco#info"
         node="generic/pgm-mp3-player">
    <identity category="pubsub" type="leaf"/>
    <feature var="http://jabber.org/protocol/pubsub"/>
    <x xmlns="jabber:x:data" type="result">
      <field var="FORM_TYPE" type="hidden">
        <value>http://jabber.org/protocol/pubsub#meta-data</value>
      </field>
      <field var="pubsub#type" label="Payload type">
        <value>http://jabber.org/protocol/tune</value>
      </field>
      <field var="pubsub#payload_xslt" label="Payload XSLT">
        <value>http://jabber.org/protocol/tune/payload.xslt</value>
      </field>
      <field var="pubsub#creator" label="Node creator">
        <value>creator@jabber.org</value>
      </field>
      <field var="pubsub#creation_date" label="Creation date">
        <value>2003-07-29T22:56Z</value>
      </field>
      <field var="pubsub#description" label="A description of the node">
        <value>This node rocks!</value>
      </field>
      <field var="pubsub#language" label="Default language">
        <value>en</value>
      </field>
      <field var="pubsub#publisher" label="Publishers to this node">
        <value>pgm@jabber.org</value>
        <value>MaineBoy@jabber.org</value>
      </field>
      <field var="pubsub#title" label="A name for the node">
        <value>This node has no name.</value>
      </field>
    </x>
  </query>
</iq>

Much of the meta-data provided about a node maps directly to selected Dublin Core Metadata Initiative (DCMI) [11] meta-data attributes; specifically:

Table 6: Dublin Core Metadata Mapping

Pubsub Field Dublin Core Metadata Attribute
pubsub#creation_date Date [12]
pubsub#creator Creator
pubsub#description Description
pubsub#language Language
pubsub#publisher Publisher
pubsub#title Title
pubsub#type Type [13]

8.1.13 Discover Items for a Node

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 each item will be returned 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 actual node using the protocol defined in the Get Items for a Node section of this document.

Example 68. A client requests all of the items for a node

<iq type="get"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="items1">
    <query xmlns="http://jabber.org/protocol/disco#items"
           node="generic/slashdot-news" />
</iq>

<iq type="result"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="items1">
    <query xmlns="http://jabber.org/protocol/disco#items"
           node="generic/slashdot-news">
        <item jid="pubsub.jabber.org" name="2003/03/06/1641229"/>
        <item jid="pubsub.jabber.org" name="2003/03/06/1629206"/>
        <item jid="pubsub.jabber.org" name="2003/03/06/1625222"/>
        <item jid="pubsub.jabber.org" name="2003/03/06/1341209"/>
    </query>
</iq>

8.2 Owner Use Cases

Implementations MAY allow node owners to configure the various options for a specific node. Implementations SHOULD use the Data Forms protocol to allow the node owner to accomplish the configuration.

The following example shows SOME of the possible configuration options which MAY be implemented in some implementations. If an implementation implements these features using the Data Forms protocol, that implementation MUST use the fields that are registered with the Jabber Registrar in association with the 'http://jabber.org/protocol/pubsub' namespace (a preliminary representation of those field variables is shown below, but MUST NOT be construed as canonical, since the Jabber Registrar may standardize additional fields at a later date without changes to this JEP). An implementation MAY choose to specify different labels, values, and even field types, but must conform to the defined variable naming scheme.

8.2.1 Configure a Node

After creating a new node, the node owner may want to modify the node configuration. The process for doing so is shown below.

Example 69. Owner requests configuration form

<iq type="get"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="config1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
    <configure node="generic/pgm-mp3-player"/>
  </pubsub>
</iq>

Example 70. Server responds with configuration form

<iq type="result"
    from="pubsub.jabber.org"
    id="config1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
    <configure node="generic/pgm-mp3-player">
      <x xmlns="jabber:x:data" type="form">
        <field var="FORM_TYPE" type="hidden">
          <value>http://jabber.org/protocol/pubsub#node_config</value>
        </field>
        <field var="pubsub#deliver_payloads" type="boolean"
               label="Deliver payloads with event notifications">
          <value>1</value>
        </field>
        <field var="pubsub#notify_config" type="boolean"
               label="Notify subscribers when the node configuration changes">
          <value>0</value>
        </field>
        <field var="pubsub#notify_delete" type="boolean"
               label="Notify subscribers when the node is deleted">
          <value>0</value>
        </field>
        <field var="pubsub#notify_retract" type="boolean"
               label="Notify subscribers when items are removed from the node">
          <value>0</value>
        </field>
        <field var="pubsub#persist_items" type="boolean"
               label="Persist items to storage">
        <value>1</value>
        </field>
        <field var="pubsub#max_items" type="text-single"
               label="Max # of items to persist">
          <value>10</value>
        </field>
        <field var="pubsub#subscribe" type="boolean"
               label="Whether to allow subscriptions">
          <value>1</value>
        </field>
        <field var="pubsub#subscription_model" type="list-single"
               label="Specify the subscriber model">
          <option><value>whitelist</value></option>
          <option><value>authorize</value></option>
          <option><value>open</value></option>
          <value>open</value>
        </field>
        <field var="pubsub#publish_model" type="list-single"
               label="Specify the publisher model">
          <option><value>publishers</value></option>
          <option><value>subscribers</value></option>
          <option><value>open</value></option>
          <value>publishers</value>
        </field>
        <field var="pubsub#max_payload_size" type="text-single"
               label="Max Payload size in bytes">
          <value>9216</value>
        </field>
        <field var="pubsub#send_item_subscribe" type="boolean"
               label="Send items to new subscribers">
          <value>0</value>
        </field>
        <field var="pubsub#presence_based_delivery" type="boolean"
               label="Only deliver notifications to available users">
          <value>0</value>
        </field>
        <field var="pubsub#current_approver" type="list-single"
               label="Specify the current subscription approver">
          <option><value>owner1@foo.com</value></option>
          <option><value>owner2@foo.com</value></option>
          <option><value>owner3@foo.com</value></option>
          <value>owner2@foo.com</value>
        </field>
        <field var="pubsub#type" type="text-single"
               label="Specify the type of payload data to be provided at this node"/>
        <field var="pubsub#payload_xslt" type="text-single"
	       label="Payload XSLT"/>
      </x>
    </configure>
  </pubsub>
</iq>

If no configuration options are available (e.g., because node configuration is "locked down"), the service MUST return a <feature-not-implemented/> error to the owner.

Example 71. Node has no configuration options

<iq type="error"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="config1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
    <configure node="generic/pgm-mp3-player"/>
  </pubsub>
  <error code="501" type="cancel">
    <feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <node-not-configurable xmlns="http://jabber.org/protocol/pubsub#errors"/>
  </error>
</iq>

After receiving the configuration form, the owner SHOULD either submit a completed configuration form or cancel the configuration process, in which case the existing configuration MUST be applied.

Example 72. Owner submits node configuration form

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="config2">
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
    <configure node="generic/pgm-mp3-player">
      <x xmlns="jabber:x:data" type="submit">
        <field var="FORM_TYPE" type="hidden">
          <value>http://jabber.org/protocol/pubsub#node_config</value>
        </field>
        <field var="pubsub#deliver_payloads"><value>1</value></field>
        <field var="pubsub#persist_items"><value>1</value></field>
        <field var="pubsub#max_items"><value>10</value></field>
        <field var="pubsub#subscription_allow"><value>authorize</value></field>
        <field var="pubsub#publish_model"><value>publishers</value></field>
        <field var="pubsub#send_item_subscribe"><value>1</value></field>
        <field var="pubsub#presence_based_delivery"><value>0</value></field>
        <field var="pubsub#notify_config"><value>0</value></field>
        <field var="pubsub#notify_delete"><value>1</value></field>
        <field var="pubsub#notify_retract"><value>1</value></field>
        <field var="pubsub#max_payload_size"><value>1028</value></field>
        <field var="pubsub#current_approver"><value>owner2@foo.com</value></field>
        <field var="pubsub#type">http://jabber.org/protocol/tune</field>
        <field var="pubsub#payload_xslt">
	  <value>http://jabber.org/protocol/tune/payload.xslt</value>
	</field>
      </x>
    </configure>
  </pubsub>
</iq>

Example 73. Owner cancels configuration process

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="config2">
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
    <configure node="generic/pgm-mp3-player">
      <x xmlns="jabber:x:data" type="cancel"/>
    </configure>
  </pubsub>
</iq>

If the "pubsub#notify_config" option is set to "1" (yes), then 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 Collection Nodes.) If the node configuration is set to event notifications only, the notification MUST consist of an empty <item/> element whose 'id' attribute is set to a value of "configuration"; if the node configuration is set to full payloads, the <item/> element MUST in addition contain the node configuration as represented via the Data Forms protocol.

Example 74. Service sends configuration change notification (event notification only)

<message to="subscriber1" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic/pgm-mp3-player">
      <item id="configuration"/>
    </items>
  </event>
</message>

Example 75. Service sends configuration change notification (full payload)

<message to="subscriber1" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic/pgm-mp3-player">
      <item id="configuration">
        <x xmlns="jabber:x:data" type="result">
          <field var="FORM_TYPE" type="hidden">
            <value>http://jabber.org/protocol/pubsub#node_config</value>
          </field>
          <field var="pubsub#deliver_payloads"
                 label="Deliver payloads with event notifications">
            <value>1</value>
          </field>
          <field var="pubsub#notify_config"
                 label="Notify subscribers when the node configuration changes">
            <value>0</value>
          </field>
          <field var="pubsub#notify_delete"
                 label="Notify subscribers when the node is deleted">
            <value>0</value>
          </field>
          <field var="pubsub#notify_retract"
                 label="Notify subscribers when items are removed from the node">
            <value>0</value>
          </field>
          <field var="pubsub#persist_items"
                 label="Persist items to storage">
            <value>1</value>
          </field>
          <field var="pubsub#max_items"
                 label="Max # of items to persist">
            <value>10</value>
          </field>
          <field var="pubsub#subscribe"
                 label="Whether to allow subscriptions">
            <value>1</value>
          </field>
          <field var="pubsub#subscription_model"
                 label="Specify the subscriber model">
            <value>open</value>
          </field>
          <field var="pubsub#publish_model"
                 label="Specify the publisher model">
            <value>publishers</value>
          </field>
          <field var="pubsub#max_payload_size"
                 label="Max Payload size in bytes">
            <value>9216</value>
          </field>
          <field var="pubsub#send_item_subscribe"
                 label="Send items to new subscribers">
            <value>0</value>
          </field>
          <field var="pubsub#presence_based_delivery"
                 label="Only deliver notifications to available users">
            <value>0</value>
          </field>
          <field var="pubsub#current_approver"
                 label="Specify the current subscription approver">
            <value>owner2@foo.com</value>
          </field>
          <field var="pubsub#type"
                 label="Specify the type of payload data to be provided at this node">
            <value>http://jabber.org/protocol/tune</value>
          </field>
          <field var="pubsub#payload_xslt" label="Payload XSLT">
            <value>http://jabber.org/protocol/tune/payload.xslt</value>
          </field>
        </x>
      </item>
    </items>
  </event>
</message>

8.2.2 Request Default Configuration Options

Services MAY allow entities to create nodes and include configuration options in the same stanza as the node creation request. In these cases, the entity SHOULD first get the node options which can be used. To get the options, the entity MUST send a configure request to the service with no NodeID; in response, the service MUST return the default node options if it supports batching a node creation and configuration request. [14] If the service does not support this feature, it MUST return a <feature-not-implemented/> error in response to the configure request with no NodeID. If the feature is not implemented but the requesting entity does not first check to determine if it is implemented but instead simply sends a create-node request that includes configuration options, the service SHOULD ignore the configuration part of the request and proceed as if it had not been included.

Before deciding whether or not accept the default configuration during node creation, an entity may want to determine what the default node configuration settings are for the service.

Example 76. Entity requests default configuration options for leaf nodes

<iq type="get"
    from="pgm@jabber.org"
    id="config3">
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
    <configure type="leaf"/>
  </pubsub>
</iq>

Example 77. Service responds with default configuration options for leaf nodes

<iq type="result"
    from="pgm@jabber.org"
    id="config3">
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
    <configure type="leaf">
     <x xmlns="jabber:x:data" type="form">
      <field var="FORM_TYPE" type="hidden">
         <value>http://jabber.org/protocol/pubsub#node_config</value>
      </field>
      <field var="pubsub#deliver_payloads" type="boolean"
             label="Deliver payloads with event notifications">
        <value>1</value>
      </field>
      <field var="pubsub#notify_config" type="boolean"
             label="Notify subscribers when the node configuration changes">
        <value>0</value>
      </field>
      <field var="pubsub#notify_delete" type="boolean"
             label="Notify subscribers when the node is deleted">
        <value>0</value>
      </field>
      <field var="pubsub#notify_retract" type="boolean"
             label="Notify subscribers when items are removed from the node">
        <value>0</value>
      </field>
      <field var="pubsub#persist_items" type="boolean"
             label="Persist items to storage">
        <value>1</value>
      </field>
      <field var="pubsub#max_items" type="text-single"
             label="Max # of items to persist">
        <value>10</value>
      </field>
      <field var="pubsub#subscribe" type="boolean"
             label="Whether to allow subscriptions">
        <value>1</value>
      </field>
      <field var="pubsub#subscription_model" type="list-single"
             label="Specify the subscriber model">
        <option><value>whitelist</value></option>
        <option><value>authorize</value></option>
        <option><value>open</value></option>
        <value>open</value>
      </field>
      <field var="pubsub#publish_model" type="list-single"
             label="Specify the publisher model">
        <option><value>publishers</value></option>
        <option><value>subscribers</value></option>
        <option><value>open</value></option>
        <value>publishers</value>
      </field>
      <field var="pubsub#max_payload_size" type="text-single"
             label="Max Payload size in bytes">
        <value>9216</value>
      </field>
      <field var="pubsub#send_item_subscribe" type="boolean"
             label="Send items to new subscribers">
        <value>0</value>
      </field>
      <field var="pubsub#presence_based_delivery" type="boolean"
             label="Only deliver notifications to available users">
        <value>0</value>
      </field>
      <field var="pubsub#current_approver" type="list-single"
             label="Specify the current subscription approver">
        <option><value>owner1@foo.com</value></option>
        <option><value>owner2@foo.com</value></option>
        <option><value>owner3@foo.com</value></option>
        <value>owner2@foo.com</value>
     </field>
     </x>
    </configure>
  </pubsub>
</iq>

Example 78. Service does not support default options

<iq type="error"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="config3">
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
    <configure/>
  </pubsub>
  <error code="501" type="cancel">
    <feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
    <node-not-configurable xmlns="http://jabber.org/protocol/pubsub#errors"/>
  </error>
</iq>

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 a collection nodes, an entity MUST specify a type of "collection" in the request (since the default value for the 'type' attribute is "leaf"):

Example 79. Entity requests default configuration options for leaf nodes

<iq type="get"
    from="pgm@jabber.org"
    id="config4">
  <pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
    <configure type="collection"/>
  </pubsub>
</iq>

8.2.3 Delete a Node

Deleting a node removes the node from the implementation (and data store if applicable). If an implementation persists items, deleting a node MUST first have the same effect as purging all the items for the node (see the Purge all node items section below) before the node itself is deleted.

Example 80. Owner deletes a node

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="delete1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <delete node="generic/pgm-mp3-player"/>
  </pubsub>
</iq>

Example 81. Node does not exist

<iq type="error"
    from="pubsub.jabber.org"
    id="delete1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <delete node="generic/pgm-mp3-player"/>
  </pubsub>
  <error code="404" type="cancel">
    <item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 82. Entity is not an owner

<iq type="error"
    from="pubsub.jabber.org"
    id="delete1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <delete node="generic/pgm-mp3-player"/>
  </pubsub>
  <error code="401" type="auth">
    <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 83. Server replies with success

<iq type="result"
    from="pubsub.jabber.org"
    id="delete1"/>

Example 84. Subscribers are notified of node removal

<message to="subscriber1" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <delete node="generic/pgm-mp3-player"/>
  </event>
</message>

<message to="subscriber2" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <delete node="generic/pgm-mp3-player"/>
  </event>
</message>

8.2.4 Purge All Node Items

Purging a node is applicable only in an implementation which persists published items. The act of purging a node removes all items from the persistent store. If an implementation does not persist items, it MUST return a <feature-not-implemented/> error. If the entity requesting to purge the node is not a node owner, the implementation must return a <not-authorized/> error.

If a node and/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 huge number of notifications); instead, the node MUST send a single notification to each subscriber, containing an empty <purge/> child element.

Example 85. Owner purges items from a node

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="purge1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <purge node="generic/pgm-mp3-player"/>
  </pubsub>
</iq>

Example 86. Server replies with success

<iq type="result"
    from="pubsub.jabber.org"
    id="purge1"/>

Example 87. Subscribers are notified of node purge

<message to="subscriber1" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <purge node="generic/pgm-mp3-player"/>
  </event>
</message>

<message to="subscriber2" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <purge node="generic/pgm-mp3-player"/>
  </event>
</message>

Example 88. Node does not exist

<iq type="error"
    from="pubsub.jabber.org"
    id="purge1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <purge node="generic/pgm-mp3-player"/>
  </pubsub>
  <error code="404" type="cancel">
    <item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 89. Entity is not an owner

<iq type="error"
    from="pubsub.jabber.org"
    id="purge1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <purge node="generic/pgm-mp3-player"/>
  </pubsub>
  <error code="401" type="auth">
    <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

Example 90. Node is not configured for persistent items

<iq type="error"
    from="pubsub.jabber.org"
    id="purge1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <purge node="generic/pgm-mp3-player"/>
  </pubsub>
  <error code="501" type="cancel">
    <feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

8.2.5 Modifying Entity Affiliations

Entities will be affiliated with a node. The node owner may edit these affiliations using the pubsub namespace. The owner may get a list of all affiliated entities, and set affiliations for existing or new entities. Note that if the node is configured for open subscriptions and/or open publishers, then the service itself will also be modifying this list. Affiliations with a node SHOULD be handled and stored using the "bare JID" (user@host) of an entity rather than the "full JID" (user@host/resource).

Implementations SHOULD allow owners to specify not only affiliations, but also subscriptions. If either the 'affiliation' attribute or the 'subscription' attribute is not specified in a modification request, then the value MUST NOT be changed.

Example 91. Owner requests all affiliated entities

<iq type="get"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="ent1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <entities node="generic/pgm-mp3-player"/>
  </pubsub>
</iq>

Example 92. Server responds with entity items

<iq type="result"
    from="pubsub.jabber.org"
    to="pgm@jabber.org"
    id="ent1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <entities node="generic/pgm-mp3-player">
      <entity jid="pgm@jabber.org"
              affiliation="owner"
              subscription="none"/>
      <entity jid="bar@baz.com"
              affiliation="publisher"
              subscription="none"/>
      <entity jid="bar2@baz.com"
              affiliation="publisher"
              subid="sub1"
              subscription="subscribed"/>
      <entity jid="bar3@baz.com"
              affiliation="publisher"
              subid="sub2"
              subscription="subscribed"/>
      <entity jid="sub1@foo.com"
              affiliation="none"
              subid="sub3"
              subscription="subscribed"/>
      <entity jid="sub2@foo.com"
              affiliation="none"
              subid="sub4"
              subscription="subscribed"/>
      <entity jid="sub3@foo.com"
              affiliation="none"
              subid="sub5"
              subscription="subscribed"/>
      <entity jid="p1@bar.com"
              affiliation="none"
              subid="sub6"
              subscription="pending"/>
      <entity jid="p2@bar.com"
              affiliation="none"
              subid="sub7"
              subscription="pending"/>
      <entity jid="out1@foo.com"
              affiliation="outcast"
              subscription="none"/>
      <entity jid="out2@foo.com"
              affiliation="outcast"
              subscription="none"/>
    </entities>
  </pubsub>
</iq>

Example 93. Owner sets affiliations for publishers

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="ent2">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <entities node="generic/pgm-mp3-player">
      <entity jid="abc@bar.com"
              affiliation="publisher"
              subscription="subscribed"/>
    </entities>
  </pubsub>
</iq>

Example 94. Server responds with success

<iq type="result"
    from="pubsub.jabber.org"
    id="ent2"/>

The owner MAY change multiple affiliations in a single request. If one of the entity elements specified is invalid, the service SHOULD return an IQ error with the invalid entries. The following example shows an entity attempting to make another owner an outcast (pgm@jabber.org). This implementation of pubsub does not allow that operation, so it returns that item, and the error for that item. Note that the affiliation sent back is the original un-altered affiliation.

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. When errors occur during a modification request for multiple entities, the pubsub service MUST return any entity element(s) which caused the error. Returned entities which failed to be modified MUST include the existing 'affiliation' and 'subscription' attributes. An error element containing the error code and a brief description of the error MUST also be included as a child element of the entity which failed. Any entity elements which are not returned in an IQ error case MUST be treated as successful modifications.

Example 95. Owner sets affiliation for multiple entities

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="ent3">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <entities node="generic/pgm-mp3-player">
      <entity jid="bar@baz.com"
              affiliation="publisher"
              subscription="none"/>
      <entity jid="bar2@baz.com"
              affiliation="publisher"
              subscription="none"/>
      <entity jid="bar3@baz.com"
              affiliation="publisher"
              subid="sub2"
              subscription="subscribed"/>
      <entity jid="pgm@jabber.org"
              affiliation="outcast"
              subscription="none"/>
    </entities>
  </pubsub>
</iq>

Example 96. Server responds with an error

<iq type="error"
    from="pubsub.jabber.org"
    id="ent3"/>
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <entities node="generic/pgm-mp3-player">
      <entity jid="pgm@jabber.org"
              affiliation="owner"
              subscription="none"/>
    </entities>
  </pubsub>
  <error code="401" type="auth">
    <not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
  </error>
</iq>

9. Collection Nodes

A pubsub service MAY support collection nodes as well as leaf nodes. Collections enable nodes to be grouped together in any way including a hierarchy. Collections MUST contain only "leaf" nodes and/or other collections. Collections MUST NOT contain published items, since only "leaf" nodes contain items. If collections are supported, then the service MUST advertise that fact in its disco#info responses by including a feature of "pubsub#collections".

Pubsub services that implement collections SHOULD allow entities to subscribe to collection nodes. Subscriptions to collection nodes MUST be configured via the protocol specified in the Use Cases section of this document. Subscription options for collection nodes MUST include a subscription type field which enables the subscriber to configure the subscription either as a subscription for items or as a subscription for nodes. This subscription option MUST use the registered field name of "pubsub#subscription_type" as defined in the Jabber Registrar Considerations section of this document. If the subscription type specified on a subscription to a collection node is "items", the subscriber MUST be notified whenever an item is published to any node contained in the collection, where such a node may be a direct "child" of the collection node, or a child (to any depth) of a sub-collection of the collection node to which the subscriber has subscribed.

9.1 Subscribing to a Collection Node

When subscribing to a collection node, a service MUST allow the subscriber to specify whether it wants to receive notifications only from first-level children of the collection or from all descendents. 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 node "tree" that begins at the level of the collection to which it has subscribed. A similar distinction applies to subscriptions of type "items". The name for this configuration option is "pubsub#subscription_depth".

Example 97. Entity subscribes to a collection node

<iq type="set"
    from="sub1@foo.com/home"
    to="pubsub.jabber.org"
    id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <subscribe jid="sub1@foo.com"/>
    <options jid="sub1@foo.com">
        <x xmlns="jabber:x:data">
          <field var="FORM_TYPE" type="hidden">
            <value>http://jabber.org/protocol/pubsub#subscribe_options</value>
          </field>
          <field var="pubsub#subscription_type">
            <value>items</value>
          </field>
          <field var="pubsub#subscription_depth">
            <value>all</value>
          </field>
        </x>
     </options>
   </pubsub>
</iq>

The subscriber will now receive item notifications from nodes at any depth within this collection.

9.2 Root Collection Node

Pubsub services that implement collections SHOULD support a root collection. This collection MUST include all nodes in the entire pubsub service and shall be identified by the lack of a node identifier (i.e., the address of the pubsub service itself, such as "pubsub.shakespeare.lit"). Subscribing to this node with a subscription of type "nodes" enables an entity to be notified whenever a new node is created in the entire pubsub system.

Example 98. Entity subscribes to the root collection node

<iq type="set"
    from="sub1@foo.com/home"
    to="pubsub.jabber.org"
    id="sub1">
  <pubsub xmlns="http://jabber.org/protocol/pubsub">
    <subscribe jid="sub1@foo.com"/>
    <options jid="sub1@foo.com">
        <x xmlns="jabber:x:data">
          <field var="FORM_TYPE" type="hidden">
            <value>http://jabber.org/protocol/pubsub#subscribe_options</value>
          </field>
          <field var="pubsub#subscription_type">
            <value>nodes</value>
          </field>
          <field var="pubsub#subscription_depth">
            <value>1</value>
          </field>
        </x>
     </options>
   </pubsub>
</iq>

If an entity subscribes to a collection node with a subscription type of "nodes", then the service MUST inform the subscriber whenever a new node is added to the collection. This is simply done by sending a notification where the 'id' attribute of the <item/> element specifies the NodeID of the new node. The notification event MUST also include the node meta-data specified in the section above, which is formatted using the Data Forms protocol.

Example 99. Payload format for node subscriptions

<message to="subscriber1" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items>
      <item id="new-node-id">
        <x xmlns="jabber:x:data" type="result">
          <field var="FORM_TYPE" type="hidden">
            <value>http://jabber.org/protocol/pubsub#meta-data</value>
          </field>
          <field var="pubsub#creation_date" label="Creation date">
            <var>2003-07-29T22:56Z</var>
          </field>
          <field var="pubsub#creator" label="Node creator">
            <var>creator@jabber.org</var>
          </field>
          <field var="pubsub#description" label="A description of the node">
            <var>This node rocks!</var>
          </field>
          <field var="pubsub#language" label="Default language">
            <var>en</var>
          </field>
          <field var="pubsub#publisher" label="Publishers to this node">
            <var>pgm@jabber.org</var>
            <var>MaineBoy@jabber.org</var>
          </field>
          <field var="pubsub#title" label="A name for the node">
            <var>This node has no name.</var>
          </field>
          <field var="pubsub#type" label="The type of data provided at the node">
            <var>http://jabber.org/protocol/moods</var>
          </field>
          <field var="pubsub#payload_xslt" label="Payload XSLT">
            <value>http://jabber.org/protocol/tune/payload.xslt</value>
          </field>
        </x>
      </item>
    </items>
  </event>
</message>

9.3 Creating New Collection Nodes

To create a new node which is a collection node, the requesting entity MUST specify a type of "collection" when asking the service to create the node. [15] If a service does not allow new collection nodes to be created, it MUST respond with a <not-allowed/> error. If the requesting entity has insufficient privileges to create new collections, the service MUST respond with a <not-authorized/> error.

Example 100. Entity requests a new collection node

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="create3">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
        <create node="test"
	        type="collection"/>
    </pubsub>
</iq>

Example 101. Server responds with success

<iq type="result"
    to="pgm@jabber.org"
    from="pubsub.jabber.org"
    id="create3"/>

9.4 Creating Nodes Affiliated with a Collection

To create a new node which is part of an existing collection, the node configuration protocol MUST be used in the node creation request. When a pubsub system supports collections, it MUST support node configuration via the Data Forms protocol as specified in the foregoing sections. A field for collections MUST be included in the node configuration form, and it MUST have a 'var' attribute of "pubsub#collections". This field MUST have a Data Forms type of "text-multi".

Example 102. Entity creates a new node related to a collection

<iq type="set"
    from="pgm@jabber.org"
    to="pubsub.jabber.org"
    id="create4">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
        <create node="foo"/>
        <configure>
            <x xmlns="jabber:x:data" type="submit">
                <field var="pubsub#collections"><value>test</value></field>
            </x>
        </configure>
    </pubsub>
</iq>

Example 103. Server responds with actual new node identifier

<iq type="result"
    to="pgm@jabber.org"
    from="pubsub.jabber.org"
    id="create4">
    <pubsub xmlns="http://jabber.org/protocol/pubsub">
        <create node="test/foo"/>
    </pubsub>
</iq>

9.5 Generating Publish Notifications for Collections

If an item is published to a node which is also contained 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 have the node identifier of the collection that the entity originally subscribed to. The item element MUST ALSO contain a node identifier for the node which generated the notification.

Example 104. Subscribers receive notifications from a collection

<message to="subscriber1" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic">
      <item node="generic/pgm-mp3-player" id="current"/>
    </items>
  </event>
</message>

<message to="subscriber2" from="pubsub.jabber.org">
  <event xmlns="http://jabber.org/protocol/pubsub#event">
    <items node="generic">
      <item node="generic/pgm-mp3-player" id="current"/>
    </items>
  </event>
</message>

10. Error Conditions

Table 7: Error conditions and typical causes

Condition Description
<conflict/> The node already exists. Some implementations may also use this error when publishing items with an ItemID that already exists. See implementation notes for ItemIDs below.
<feature-not-implemented/> The operation being attempted on a node (or the system) is disabled because the service itself does not support the operation.
<forbidden/> An entity is requesting an operation for a Jabber ID which it is not allowed to change (e.g., a@jabber.org attempts to subscribe b@jabber.org to a specific node) or the requesting entity has an affiliation of "outcast".
<item-not-found/> The node specified for some operation does not exist.
<not-allowed/> An entity has attempted to perform an action which the service implements; however the sysadmin or the node owner has disabled the action for that specific service or node.
<not-authorized/> This error is produced when an entity tries to perform some action on a node, and that entity has insufficient privileges to perform the action.
<payment-required/> This error would typically be used to indicate that a subscription for a pubsub node is based on some kind payment service. Payments would be done out-of-band using some agreed-upon method (not defined herein).
<registration-required/> Some implementations may require entities to register before node creation is allowed.

Note: Refer to Error Condition Mappings [16] for information regarding error syntax.

11. Implementation Notes

11.1 Presence-Based Delivery of Events

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. In addition, to facilitate this, the pubsub service needs to subscribe to the subscriber's presence and check the current presence information before sending any event notifications (as described in XMPP IM [17]).

11.2 Not Sending Events to Offline Storage

Sending events to users of existing Jabber servers may force event notifications to be sent to offline storage for later delivery. This may not always be desirable. The possible ways of preventing this behavior include:

11.3 Node and Item ID Uniqueness

NodeIDs MUST be treated as unique identifiers within the context of a particular pubsub service.

If item identifiers are used, they MUST be treated as unique within the scope of the node. NodeID + ItemID MUST be unique within a given service, and MUST specify a single published item to a single node. Multiple publishes to the same ItemID MAY result in behavior similar to that stated above for nodes (except that multiple items in a list MUST NOT have the same ItemID, since ItemIDs MUST be unique within the scope of a node).

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.

11.4 Authorizing Subscription Requests (Pending Subscribers)

Implementations may handle sending subscription requests to node owners differently. Possibilities include:

An implementation MAY use any of these methods, or some other method not defined herein.

11.5 Handling Node Hierarchies

NodeIDs MAY have semantic value in implementations of pubsub. If an implementation wishes node IDs to have hierarchical meaning (as is shown in the examples), that implementation MAY choose any naming scheme which is suitable to the hierarchy in question. Identifiers could use slashes, periods, or other special characters as the hierarchy separator.

11.6 Message Bodies

The <message/> stanzas sent from a service to a subscriber for purposes of event notification SHOULD include a <body/> child whose textual CDATA informs the subscriber that the message contains an event notification (e.g., text such as "This message contains an event notification" would be appropriate). This enables "graceful degradation" in case the user's current client does not support pubsub.

11.7 Multiple Node Discovery

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 JEP-0030). 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:

Example 105. Discovering multiple nodes

<iq type="get"
    from="stpeter@jabber.org/home"
    to="pgm@jabber.org"
    id="multi-1"/>
  <query xmlns="http://jabber.org/protocol/disco#items"
         node="http://jabber.org/protocol/tune"/>
</iq>

<iq type="result"
    from="pgm@jabber.org"
    to="stpeter@jabber.org/home"
    id="multi-1"/>
  <query xmlns="http://jabber.org/protocol/disco#items"
         node="http://jabber.org/protocol/tune">
    <item jid="pubsub.jabber.org"
          node="generic/pgm-mp3-player"
          name="Laptop MP3 Player"/>
    <item jid="thepub.pgmillard.com"
          node="cdplayer"
          name="CD Player @ Home"/>
  </query>
</iq>

11.8 Associating Events and Payloads with the Generating Entity

In some contexts, it is valuable to provide an association between the event notification or payload and the entity to which the published information pertains. For example, in the context of a protocol such as User Geolocation [19], 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 about the user (specifically, his or her spatial location). In order to associate the information with the user in a manner more explicit than enforcing semantic meaning on the NodeID, the service MAY include 'replyto' or 'replyroom' data (as specified by the Extended Stanza Addressing [20] protocol) with the <message/> or <presence/> stanzas that contain event notifications and payloads. An example is shown below:

Example 106. Event notification with extended stanza addressing

<message from='pubsub.shakespeare.lit'
         to='bassanio@merchantofvenice.lit'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='n48ad4fj78zn38st734'>
      <item id='i1s2d3f4g5h6bjeh936'>
        <geoloc xmlns='http://jabber.org/protocol/geoloc'>
          <description>Venice</description>
          <lat>45.44</lat>
          <lon>12.33</lon>
        </geoloc>
      </item>
    </items>
  </event>
  <addresses xmlns='http://jabber.org/protocol/address'>
    <address type='replyto' jid='portia@merchantofvenice.lit'/>
  </addresses>
</message>
          

11.9 Implementing Time-Based Subscriptions (Leases)

In some systems it may be desirable to provide a leasing system on subscriptions to a node in order to expire old or stale subscriptions. This can be accomplished using this protocol by using the configurable subscription options, and implementations SHOULD use this method when providing this type of functionality. When an entity subscribes, a field could be sent back in the subscription options which has a 'var' attribute of pubsub#expire. This field MUST contain a date-time specified in Jabber Date and Time Profiles [21]. When an entity wants to renew the lease, it simply gets the current subscription options, changes the value of the pubsub#expire field, and resubmits the new subscription options back to the service. If the new expire value exceeds the maximum value allowed for subscription leases then service MUST change the value of the field to be the current date/time plus the maximum allowed lease period.

11.10 Implementing Content-Based Pubsub Systems

Content-based pubsub services SHOULD make use of a variety of optional features.

12. Security Considerations

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.

A service MUST NOT send event notifications or payloads to an entity, nor allow an entity to retrieve items published to a node, unless that entity is an authorized subscriber to the node.

A service MUST NOT allow non-owners or other unauthorized entities to complete any actions defined under the Owner Use Cases section above.

13. IANA Considerations

This JEP does not require interaction with the Internet Assigned Numbers Authority (IANA) [22].

14. Jabber Registrar Considerations

14.1 Protocol Namespaces

The Jabber Registrar [23] shall include the following namespaces in its registry of protocol namespaces:

14.2 Service Discovery Category/Type

As a result of this JEP, the Jabber Registrar shall register a Service Discovery category of "pubsub", as well as three specific Service Discovery types within that category:

Table 8: Service Discovery Types in Pubsub Category

collection A pubsub node of the "collection" type.
leaf A pubsub node of the "leaf" type.
service A pubsub service that supports the functionality defined in JEP-0060. (Prior to version 1.15 of JEP-0060, this type was called "generic".)

The registry submission is as follows:

<category>
  <name>pubsub</name>
  <desc>Services and nodes that adhere to JEP-0060.</desc>
  <type>
    <name>collection</name>
    <desc>A pubsub node of the "collection" type.</desc>
    <doc>JEP-0060</doc>
  </type>
  <type>
    <name>leaf</name>
    <desc>A pubsub node of the "leaf" type.</desc>
    <doc>JEP-0060</doc>
  </type>
  <type>
    <name>service</name>
    <desc>A pubsub service that supports the functionality defined in JEP-0060.</desc>
    <doc>JEP-0060</doc>
  </type>
</category>
        

Future submissions to the Jabber Registrar may register additional types.

14.3 Service Discovery Features

As a result of this JEP, the Jabber Registrar shall register Service Discovery features that may be returned by pubsub services. The following table defines the initial set of such features. (Future submissions to the Jabber Registrar may register additional features.)

Table 9: Service Discovery Features

http://jabber.org/protocol/pubsub#collections Collection nodes are supported.
http://jabber.org/protocol/pubsub#config-node Configuration of node options is supported.
http://jabber.org/protocol/pubsub#create-nodes Creation of nodes is supported.
http://jabber.org/protocol/pubsub#delete-any Any publisher may delete an item (not only the originating publisher).
http://jabber.org/protocol/pubsub#delete-nodes Deletion of nodes is supported.
http://jabber.org/protocol/pubsub#instant-nodes Creation of instant nodes is supported.
http://jabber.org/protocol/pubsub#item-ids Publishers may specify item identifiers.
http://jabber.org/protocol/pubsub#leased-subscription Time-based subscriptions are supported.
http://jabber.org/protocol/pubsub#meta-data Node meta-data is supported.
http://jabber.org/protocol/pubsub#multi-subscribe A single entity may subscribe to a node multiple times.
http://jabber.org/protocol/pubsub#outcast-affiliation The outcast affiliation is supported.
http://jabber.org/protocol/pubsub#persistent-items Persistent items are supported.
http://jabber.org/protocol/pubsub#presence-notifications Presence-based delivery of event notifications is supported.
http://jabber.org/protocol/pubsub#publisher-affiliation The publisher affiliation is supported.
http://jabber.org/protocol/pubsub#purge-nodes Purging of nodes is supported.
http://jabber.org/protocol/pubsub#retract-items Item retraction is supported.
http://jabber.org/protocol/pubsub#retrieve-affiliations Retrieval of current affiliations is supported.
http://jabber.org/protocol/pubsub#retrieve-items Item retrieval is supported.
http://jabber.org/protocol/pubsub#subscribe Subscribing and unsubscribing are supported.
http://jabber.org/protocol/pubsub#subscription-options Configuration of subscription options is supported.

The registry submission is as follows:

<var>
  <name>http://jabber.org/protocol/pubsub#collections</name>
  <desc>Collection nodes are supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#config-node</name>
  <desc>Configuration of node options is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#create-nodes</name>
  <desc>Creation of nodes is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#delete-any</name>
  <desc>Any publisher may delete an item (not only the originating publisher).</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#delete-nodes</name>
  <desc>Deletion of nodes is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#instant-nodes</name>
  <desc>Creation of instant nodes is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#item-ids</name>
  <desc>Publishers may specify item identifiers.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#leased-subscription</name>
  <desc>Time-based subscriptions are supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#meta-data</name>
  <desc>Node meta-data is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#multi-subscribe</name>
  <desc>A single entity may subscribe to a node multiple times.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#outcast-affiliation</name>
  <desc>The outcast affiliation is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#persistent-items</name>
  <desc>Persistent items are supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#presence-notifications</name>
  <desc>Presence-based delivery of event notifications is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#publisher-affiliation</name>
  <desc>The publisher affiliation is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#purge-nodes</name>
  <desc>Purging of nodes is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#retract-items</name>
  <desc>Item retraction is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#retrieve-affiliations</name>
  <desc>Retrieval of current affiliations is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#retrieve-items</name>
  <desc>Item retrieval is supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#subscribe</name>
  <desc>Subscribing and unsubscribing are supported.</desc>
  <doc>JEP-0060</doc>
</var>
<var>
  <name>http://jabber.org/protocol/pubsub#subscription-options</name>
  <desc>Configuration of subscription options is supported.</desc>
  <doc>JEP-0060</doc>
</var>
        

14.4 Field Standardization

JEP-0068 defines a process for standardizing the fields used within Data Forms scoped by a particular namespace. Within pubsub, there are four uses of such forms:

  1. Authorization of subscriptions using the 'http://jabber.org/protocol/pubsub#subscribe_authorization' namespace
  2. Configuration of subscription options using the 'http://jabber.org/protocol/pubsub#subscribe_options' namespace
  3. Configuration of a node using the 'http://jabber.org/protocol/pubsub#node_config' namespace
  4. Setting of meta-data information using the 'http://jabber.org/protocol/pubsub#meta-data' namespace

The registry submissions associated with these namespaces are defined below.

14.4.1 pubsub#subscribe_authorization FORM_TYPE

<form_type>
  <name>http://jabber.org/protocol/pubsub#subscribe_authorization</name>
  <jep>JEP-0060</jep>
  <desc>Forms enabling authorization of subscriptions to pubsub nodes</desc>
  <field
      var='pubsub#allow'
      type='boolean'
      label='Whether to allow the subscription'/>
  <field
      var='pubsub#node'
      type='text-single'
      label='The NodeID of the node'/>
  <field
      var='pubsub#subid'
      type='text-single'
      label='The SubID of the subscription'/>
  <field
      var='pubsub#subscriber_jid'
      type='jid-single'
      label='The address (JID) of the subscriber'/>
</form_type>
          

14.4.2 pubsub#subscribe_options FORM_TYPE

<form_type>
  <name>http://jabber.org/protocol/pubsub#subscribe_options</name>
  <jep>JEP-0060</jep>
  <desc>Forms enabling configuration of subscription options for pubsub nodes</desc>
  <field
      var='pubsub#digest'
      type='boolean'
      label='Whether a user wants to receive digests
             (aggregations) of notifications or all
             notifications individually'/>
  <field
      var='pubsub#digest'
      type='boolean'
      label='Whether a user wants to receive digests
             (aggregations) of notifications or all
             notifications individually'/>
  <field
      var='pubsub#show-values'
      type='list-multi'
      label='The presence states for which a user
             wants to receive notifications'>
    <option label='XMPP Show Value of Away'>
      <value>away</value>
    </option>
    <option label='XMPP Show Value of Chat'>
      <value>chat</value>
    </option>
    <option label='XMPP Show Value of DND (Do Not Disturb)'>
      <value>dnd</value>
    </option>
    <option label='Mere Availability in XMPP (No Show Value)'>
      <value>online</value>
    </option>
    <option label='XMPP Show Value of XA (Extended Away)'>
      <value>xa</value>
    </option>
  </field>
  <field var="pubsub#subscription_type"
         type="list-single">
    <option label='Receive notification of new items only'>
      <value>items</value>
    </option>
    <option label='Receive notification of new nodes only'>
      <value>nodes</value>
    </option>
  </field>
  <field var="pubsub#subscription_depth"
         type="list-single">
    <option label='Receive notification from direct child nodes only'>
      <value>1</value>
    </option>
    <option label='Receive notification from all descendent nodes'>
      <value>all</value>
    </option>
  </field>
  </field>
</form_type>
          

14.4.3 pubsub#node_config FORM_TYPE

<form_type>
  <name>http://jabber.org/protocol/pubsub#node_config</name>
  <jep>JEP-0060</jep>
  <desc>Forms enabling configuration of pubsub nodes</desc>
  <field var="pubsub#collection"
         type="boolean"
         label="Whether or not the node is a collection"/>
  <field var="pubsub#current_approver"
         type="list-single"
         label="The current subscription approver"/>
  <field var="pubsub#deliver_payloads"
         type="boolean"
         label="Whether to deliver payloads with event notifications"/>
  <field var="pubsub#max_items"
         type="text-single"
         label="The maximum number of items to persist"/>
  <field var="pubsub#max_payload_size"
         type="text-single"
         label="The maximum payload size in bytes"/>
  <field var="pubsub#node_type"
         type="list-single"
         label="The type of node (collection or leaf)">
    <option label='Collection node (contains nodes and/or collections)'>
      <value>collection</value>
    </option>
    <option label='Leaf node (contains published items only)'>
      <value>leaf</value>
    </option>
  </field>
  <field var="pubsub#notify_config"
         type="boolean"
         label="Whether to notify subscribers when the node configuration changes"/>
  <field var="pubsub#notify_delete"
         type="boolean"
         label="Whether to notify subscribers when the node is deleted"/>
  <field var="pubsub#notify_retract"
         type="boolean"
         label="Whether to notify subscribers when items are removed from the node"/>
  <field var="pubsub#persist_items"
         type="boolean"
         label="Whether to persist items to storage"/>
  <field var="pubsub#presence_based_delivery"
         type="boolean"
         label="Whether to deliver notifications to available users only"/>
  <field var="pubsub#publish_model"
         type="list-single"
         label="The publisher model">
    <option label='Only publishers may publish'>
      <value>publishers</value>
    </option>
    <option label='Subscribers may publish'>
      <value>subscribers</value>
    </option>
    <option label='Anyone may publish'>
      <value>open</value>
    </option>
  </field>
  <field var="pubsub#subscribe" type="boolean"
         label="Whether to allow subscriptions">
    <value>1</value>
  </field>
  <field var="pubsub#subscription_model"
         type="list-single"
         label="The subscriber model">
    <option label='Only those on a whitelist may subscribe'>
      <value>whitelist</value>
    </option>
    <option label='Subscription requests must be authorized'>
      <value>authorize</value>
    </option>
    <option label='Anyone may subscribe'>
      <value>open</value>
    </option>
  </field>
  <field var="pubsub#send_item_subscribe"
         type="boolean"
         label="Whether to send items to new subscribers"/>
  <field var="pubsub#type"
         type='text-single'
         label="The type of node data, usually specified by
                the namespace of the payload (if any); MAY
                be list-single rather than text-single"/>
  <field var="pubsub#payload_xslt" 
	 type="text-single"
         label="The URL of an XSL transformation which can be 
	        applied to payload packets in order to generate 
		a valid Data Forms result that the client could 
		then display using a generic Data Forms rendering 
		engine"/>
</form_type>
          

14.4.4 pubsub#meta-data FORM_TYPE

<form_type>
  <name>http://jabber.org/protocol/pubsub#meta-data</name>
  <jep>JEP-0060</jep>
  <desc>Forms enabling setting of meta-data information about pubsub nodes</desc>
  <field var="pubsub#creation_date"
         type='text-single'
         label="The datetime when the node was created"/>
  <field var="pubsub#creator"
         type='jid-single'
         label="The JID of the node creator"/>
  <field var="pubsub#description"
         type='text-single'
         label="A description of the node"/>
  <field var="pubsub#language"
         type='text-single'
         label="The default language of the node"/>
  <field var="pubsub#publisher"
         type='jid-multi'
         label="The JIDs of those who may publish to this node"/>
  <field var="pubsub#title"
         type='text-single'
         label="The name of the node"/>
</form_type>
          

14.5 SHIM Headers

The Jabber Registrar shall add "pubsub#subid" to its registry of SHIM headers (per JEP-0131). The registry submission is as follows:

<header>
  <name>pubsub#subid</name>
  <desc>A subscription identifer within the pubsub protocol.</desc>
  <doc>JEP-0060</doc>
</header>
        

Future submissions to the Jabber Registrar may register additional SHIM headers that can be used in relation to the pubsub protocol.

14.6 URI Query Types

As authorized by XMPP URI Query Components [24], the Jabber Registrar maintains a registry of queries and key-value pairs for use in XMPP URIs (see <http://www.jabber.org/registrar/querytypes.html>).

The "pubsub" querytype is defined herein for interaction with pubsub services, with two keys: (1) "node" (to specify pubsub nodes) and (2) "action", whose defined values are "subscribe" and "unsubscribe".

Example 107. Pubsub Subscribe Action: IRI/URI

xmpp:pubsub.shakespeare.lit?pubsub;action=subscribe;node=globe/performances
    

Example 108. Pubsub Subscribe Action: Resulting Stanza

<iq to='pubsub.shakespeare.lit' type='set'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe node='globe/performances'/>
  </pubsub>
</iq>
    

Example 109. Pubsub Unsubscribe Action: IRI/URI

xmpp:pubsub.shakespeare.lit?pubsub;action=unsubscribe;node=globe/performances
    

Example 110. Pubsub Unsubscribe Action: Resulting Stanza

<iq to='pubsub.shakespeare.lit' type='set'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <unsubscribe node='globe/performances'/>
  </pubsub>
</iq>
    

The following submission registers the "pubsub" querytype.

<querytype>
  <name>pubsub</name>
  <proto>http://jabber.org/protocol/pubsub</proto>
  <desc>enables interaction with a publish-subscribe service</desc>
  <doc>JEP-0060</doc>
  <keys>
    <key>
      <name>action</name>
      <desc>the pubsub action</desc>
      <values>
        <value>
	  <name>subscribe</name>
          <desc>enables subscribing to a pubsub node</desc>
        </value>
        <value>
	  <name>unsubscribe</name>
          <desc>enables unsubscribing from a pubsub node</desc>
        </value>
      </values>
    </key>
    <key>
      <name>node</name>
      <desc>the pubsub node</desc>
    </key>
  </keys>
</querytype>
    

15. XML Schemas

15.1 http://jabber.org/protocol/pubsub

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/pubsub'
    xmlns='http://jabber.org/protocol/pubsub'
    elementFormDefault='qualified'>

  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      JEP-0060: http://www.jabber.org/jeps/jep-0060.html
    </xs:documentation>
  </xs:annotation>

  <xs:import 
      namespace='jabber:x:data'
      schemaLocation='http://jabber.org/protocol/x-data/x-data.xsd'/>

  <xs:element name='pubsub'>
    <xs:complexType>
      <xs:choice minOccurs='0'>
        <xs:sequence>
          <xs:element ref='create' minOccurs='0'/>
          <xs:element ref='configure' minOccurs='0'/>
        </xs:sequence>
        <xs:sequence>
          <xs:element ref='subscribe' minOccurs='0'/>
          <xs:element ref='options' minOccurs='0'/>
        </xs:sequence>
        <xs:choice minOccurs='0'>
          <xs:element ref='affiliations'/>
          <xs:element ref='delete'/>
          <xs:element ref='entities'/>
          <xs:element ref='entity'/>
          <xs:element ref='items'/>
          <xs:element ref='publish'/>
          <xs:element ref='purge'/>
          <xs:element ref='retract'/>
          <xs:element ref='unsubscribe'/>
        </xs:choice>
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <xs:element name='affiliations'>
    <xs:complexType>
      <xs:element ref='entity' minOccurs='0' maxOccurs='unbounded'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='configure'>
    <xs:complexType>
      <xs:sequence minOccurs='0'
                   xmlns:xdata='jabber:x:data'>
        <xs:element ref='xdata:x'/>
      </xs:sequence>
      <xs:attribute name='node' use='optional'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='create'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='node' type='xs:string' use='optional'/>
          <xs:attribute name='type' use='optional' default='leaf'>
            <xs:simpleType>
              <xs:restriction base='xs:NCName'>
                <xs:enumeration value='collection'/>
                <xs:enumeration value='leaf'/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='delete'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='node' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='entities'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='entity' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='node' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='entity'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='subscribe-options' minOccurs='0'/>
      </xs:sequence>
      <xs:attribute name='affiliation' use='required'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='none'/>
            <xs:enumeration value='outcast'/>
            <xs:enumeration value='owner'/>
            <xs:enumeration value='publisher'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name='jid' type='xs:string' use='required'/>
      <xs:attribute name='node' type='xs:string' use='optional'/>
      <xs:attribute name='subscription' use='optional'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='none'/>
            <xs:enumeration value='pending'/>
            <xs:enumeration value='subscribed'/>
            <xs:enumeration value='unconfigured'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

  <xs:element name='items'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='max_items' type='xs:positiveInteger' use='optional'/>
      <xs:attribute name='node' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='item'>
    <xs:complexType>
      <xs:sequence minOccurs='0'>
        <xs:any namespace='##other'/>
      </xs:sequence>
      <xs:attribute name='id' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='options'>
    <xs:complexType>
      <xs:sequence minOccurs='0'>
        <xs:any namespace='jabber:x:data'/>
      </xs:sequence>
      <xs:attribute name='jid' type='xs:string' use='required'/>
      <xs:attribute name='node' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='publish'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='node' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='purge'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='node' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='retract'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='node' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='subscribe-options'>
    <xs:complexType>
      <xs:sequence>
        <xs:element name='required' type='empty' minOccurs='0'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='subscribe'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='jid' type='xs:string' use='required'/>
          <xs:attribute name='node' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='unsubscribe'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='jid' type='xs:string' use='required'/>
          <xs:attribute name='node' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>
        

15.2 http://jabber.org/protocol/pubsub#event

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/pubsub#event'
    xmlns='http://jabber.org/protocol/pubsub#event'
    elementFormDefault='qualified'>

  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      JEP-0060: http://www.jabber.org/jeps/jep-0060.html
    </xs:documentation>
  </xs:annotation>

  <xs:element name='event'>
    <xs:complexType>
      <xs:choice minOccurs='0'>
        <xs:element ref='delete'/>
        <xs:element ref='items'/>
        <xs:element ref='purge'/>
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <xs:element name='delete'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='node' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='items'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='node' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='item'>
    <xs:complexType>
      <xs:sequence minOccurs='0'>
        <xs:any namespace='##other'/>
      </xs:sequence>
      <xs:attribute name='id' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='purge'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='node' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>
        

15.3 http://jabber.org/protocol/pubsub#owner

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/pubsub#owner'
    xmlns='http://jabber.org/protocol/pubsub#owner'
    elementFormDefault='qualified'>

  <xs:annotation>
    <xs:documentation>
      The protocol documented by this schema is defined in
      JEP-0060: http://www.jabber.org/jeps/jep-0060.html
    </xs:documentation>
  </xs:annotation>

  <xs:import 
      namespace='jabber:x:data'
      schemaLocation='http://jabber.org/protocol/x-data/x-data.xsd'/>

  <xs:element name='pubsub'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='configure'/>
      </xs:sequence>
      <xs:attribute name='action' use='optional'/>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='get-pending'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

  <xs:element name='configure'>
    <xs:complexType>
      <xs:sequence minOccurs='0'
                   xmlns:xdata='jabber:x:data'>
        <xs:element ref='xdata:x'/>
      </xs:sequence>
      <xs:attribute name='node' use='optional'/>
      <xs:attribute name='type' use='optional' default='leaf'>
        <xs:simpleType>
          <xs:restriction base='xs:NCName'>
            <xs:enumeration value='collection'/>
            <xs:enumeration value='leaf'/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>

</xs:schema>
        

15.4 http://jabber.org/protocol/pubsub#errors

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://jabber.org/protocol/pubsub#errors'
    xmlns='http://jabber.org/protocol/pubsub#errors'
    elementFormDefault='qualified'>

  <xs:annotation>
    <xs:documentation>
      This namespace is used for error reporting only, as
      defined in JEP-0060: 
      
      http://www.jabber.org/jeps/jep-0060.html
    </xs:documentation>
  </xs:annotation>

  <xs:element name='invalid-options' type='empty'/>
  <xs:element name='node-not-configurable' type='empty'/>
  <xs:element name='persistence-unavailable' type='empty'/>
  <xs:element name='not-subscribed' type='empty'/>
  <xs:element name='subscription-options-unavailable' type='empty'/>

  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>
        


Notes

1. RFC 3920: Extensible Messaging and Presence Protocol (XMPP): Core <http://www.ietf.org/rfc/rfc3920.txt>.

2. JEP-0030: Service Discovery <http://www.jabber.org/jeps/jep-0030.html>.

3. JEP-0045: Multi-User Chat <http://www.jabber.org/jeps/jep-0045.html>.

4. JEP-0118: User Tune <http://www.jabber.org/jeps/jep-0118.html>.

5. JEP-0131: Stanza Headers and Internet Metadata (SHIM) <http://www.jabber.org/jeps/jep-0131.html>.

6. JEP-0004: Data Forms <http://www.jabber.org/jeps/jep-0004.html>.

7. JEP-0050: Ad-Hoc Commands <http://www.jabber.org/jeps/jep-0050.html>.

8. JEP-0068: Field Data Standardization for Data Forms <http://www.jabber.org/jeps/jep-0068.html>.

9. JEP-0055: Jabber Search <http://www.jabber.org/jeps/jep-0055.html>.

10. JEP-0128: Service Discovery Extensions <http://www.jabber.org/jeps/jep-0128.html>.

11. The Dublin Core Metadata Initiative (DCMI) is an organization dedicated to promoting the widespread adoption of interoperable metadata standards. For further information, see <http://www.dublincore.org/>.

12. The value SHOULD be a DateTime as defined in JEP-0082, and MUST conform to one of the profiles defined therein.

13. The pubsub type SHOULD be the namespace that defines the payload (such as 'http://jabber.org/protocol/tune') if appropriate.

14. A configure request with no NodeID must not be confused with a creation request with no NodeID; in response to the former, the service returns the default node options, whereas in response to the latter it creates an instant node.

15. Earlier versions of this JEP specified the use of the configuration protocol in the node creation request, containing a field for node type in the node configuration form whose 'var' attribute was "pubsub#node_type" and whose <value/> was "collection"; that protocol is now deprecated.

16. JEP-0086: Error Condition Mappings <http://www.jabber.org/jeps/jep-0086.html>.

17. RFC 3921: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence <http://www.ietf.org/rfc/rfc3921.txt>.

18. JEP-0079: Advanced Message Processing <http://www.jabber.org/jeps/jep-0079.html>.

19. JEP-0080: User Geolocation <http://www.jabber.org/jeps/jep-0080.html>.

20. JEP-0033: Extended Stanza Addressing <http://www.jabber.org/jeps/jep-0033.html>.

21. JEP-0082: Jabber Date and Time Profiles <http://www.jabber.org/jeps/jep-0082.html>.

22. The Internet Assigned Numbers Authority (IANA) is the central coordinator for the assignment of unique parameter values for Internet protocols, such as port numbers and URI schemes. For further information, see <http://www.iana.org/>.

23. The Jabber Registrar maintains a list of reserved Jabber protocol namespaces as well as registries of parameters used in the context of protocols approved by the Jabber Software Foundation. For further information, see <http://www.jabber.org/registrar/>.

24. JEP-0147: XMPP URI Query Components <http://www.jabber.org/jeps/jep-0147.html>.


Revision History

Version 1.7 (2005-03-03)

Reinstated pubsub#subscribe feature (deleted in error); added type attribute for the <create/> and <configure/> elements to differentiate between leaf nodes and collection nodes; in Section 8.1.7, changed affiliations retrieval support to SHOULD and added pubsub#retrieve-affiliations feature; in Section 8.1.10, removed two duplicate examples; in Section 8.1.12, clarified relationship between normal disco#info data and node meta-data (which uses a service discovery extension); in Section 8.2.4, specified that node purgation MUST result in one event notification, not a notification per item; in Section 8.1.8, further specified handling of SubIDs; clarified nature of the pubsub#type field; mentioned that the forbidden error should be returned in response to certain operations requested by an outcast; corrected datatype of max_items attribute from xs:string to xs:positiveInteger; corrected <requestor-not-subscribed/> error to <not-subscribed/> since the subsribed JID need not be that of the requestor; added service discovery features for more optional use cases: retracting items, purging nodes, deleting nodes; updated relevant registries. (psa/rm)

Version 1.6 (2004-07-13)

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. (pgm/psa)

Version 1.5 (2004-07-07)

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 Jabber Registrar submissions. Corrected schemas. (pgm/psa)

Version 1.4 (2004-06-22)

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. (pgm)

Version 1.3 (2004-04-25)

Editorial review; added one implementation note. (psa)

Version 1.2 (2004-03-09)

Added XMPP error handling. (psa)

Version 1.1 (2004-01-14)

Added Jabber Registrar Considerations subsection for Service Discovery category/type registration. (psa)

Version 1.0 (2003-10-28)

Per a vote of the Jabber Council, advanced status to Draft. (psa)

Version 0.16 (2003-10-23)

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. (pgm)

Version 0.15 (2003-10-21)

Fixed invalid XML in examples for subscription deny/allow. (pgm)

Version 0.14 (2003-10-21)

Clarified restrictions on addressing nodes by JID. Added "Approving and denying subscription requests" section. Changed get-pending to use Ad-Hoc Commands. Changed semantics when sending in a form type='cancel' for pending subscriptions. (pgm)

Version 0.13 (2003-09-30)

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. (pgm)

Version 0.12 (2003-08-13)

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 Jabber Registrar considerations. (pgm, psa)

Version 0.11 (2003-06-25)

Removed subscription notifications since they have inherent issues. Removed empty implementation note sub-section. (pgm)

Version 0.10 (2003-06-11)

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. (pgm)

Version 0.9 (2003-04-30)

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. (pgm)

Version 0.8 (2003-04-03)

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 batching configuration and node creation requests into a single stanza. Added meta-node implementation notes and specified the interaction with the Jabber Registrar and the "meta" NodeIDs. Added authorization notes to subscription options. (pgm)

Version 0.7 (2003-02-14)

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. (pgm)

Version 0.6 (2003-02-06)

Added more details and an example about publishing without NodeID. Added more implementation notes about NodeIDs and persistent storage. (pgm)

Version 0.5 (2003-01-22)

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. (pgm)

Version 0.4 (2003-01-21)

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 Jabber 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. (pgm)

Version 0.3 (2003-01-20)

Added subscription attribute for entities. Removed subscriber from the affiliations table. Clarified configuration details. Clarified JabberID usages. Added Jabber Registrar Considerations. Added link to JEP-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. (pgm)

Version 0.2 (2003-01-02)

Added numerous implementation notes; added get-pending action with regard to subscriptions; added error table; changed purge and delete to use IQ type='set'. (pgm)

Version 0.1 (2002-11-19)

Initial version. (pgm)


END