1
0
mirror of https://github.com/moparisthebest/xeps synced 2024-11-25 10:42:19 -05:00
git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@905 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2007-06-01 20:32:46 +00:00
parent 5471ed89eb
commit 330b91c6b8

View File

@ -27,10 +27,10 @@
&stpeter; &stpeter;
&ksmith; &ksmith;
<revision> <revision>
<version>1.1pre1</version> <version>1.1pre3</version>
<date>in progress, last updated 2007-04-03</date> <date>in progress, last updated 2007-05-30</date>
<initials>psa</initials> <initials>psa</initials>
<remark><p>Defined atomic publish+configure action for use on first publish; added friendly but non-normative How It Works section to introduction; tightened up definition of normative sections; explicitly defined auto-create and publish-and-configure features.</p></remark> <remark><p>In accordance with XMPP Council consensus (1) explicitly defined auto-create, auto-subscribe, filtered-notifications, and last-published features, (2) moved them to XEP-0060, and (3) added appropriate references to XEP-0060 throughout; also added friendly but non-normative How It Works section and removed references to private data storage.</p></remark>
</revision> </revision>
<revision> <revision>
<version>1.0</version> <version>1.0</version>
@ -154,41 +154,31 @@
<p>There are two sides to personal eventing: what the user does to generate events and what the contact does to receive events. As shown in the following examples, both are simplified in PEP as compared to generic pubsub.</p> <p>There are two sides to personal eventing: what the user does to generate events and what the contact does to receive events. As shown in the following examples, both are simplified in PEP as compared to generic pubsub.</p>
<p>Imagine that you are a Shakespearean character named Juliet and that you want to generate the following kinds of events that may be of interest to other people:</p> <p>Imagine that you are a Shakespearean character named Juliet and that you want to generate the following kinds of events that may be of interest to other people:</p>
<ol start='1'> <ol start='1'>
<li>Information about what music you're listening to, which anyone may see even if they are not allowed to know your online/offline presence (i.e., a pubsub access model of "presence")</li> <li>Information about what music you're listening to, which anyone may see as long as they are authorized to see your online/offline presence (i.e., a pubsub access model of "presence")</li>
<li>Information about your geographical location, which only contacts in your "Friends" roster group may see (i.e., a pubsub access model of "roster" with a group of "Friends")</li> <li>Information about your geographical location, which only contacts in your "Friends" roster group may see (i.e., a pubsub access model of "roster" with a group of "Friends")</li>
</ol> </ol>
<p>We assume that there are three other users who have the following relationship to you:</p> <p>We assume that there are three other users who have the following relationship to you:</p>
<ol start='1'> <ol start='1'>
<li>benvolio@montague.net, who has no subscription to your presence</li> <li>benvolio@montague.lit, who has no subscription to your presence</li>
<li>nurse@capulet.com, who has a bidirectional subscription to your presence and who is in your "Servants" roster group</li> <li>nurse@capulet.lit, who has a bidirectional subscription to your presence and who is in your "Servants" roster group</li>
<li>romeo@montague.net, who has a bidirectional subscription to your presence and who is in your "Friends" roster group</li> <li>romeo@montague.lit, who has a bidirectional subscription to your presence and who is in your "Friends" roster group</li>
</ol> </ol>
<p>We also assume that your server (montague.net) supports PEP and that your client discovered that support when you logged in.</p> <p>We also assume that your server (capulet.lit) supports PEP and that your client discovered that support when you logged in.</p>
<p>Now you start playing a song on your music playing software. Your client captures that "event" and publishes it to your server:</p> <p>Now you start playing a song on your music playing software. Your client captures that "event" and publishes it to your server:</p>
<example caption='Publishing an event'><![CDATA[ <example caption='Publishing an event'><![CDATA[
<iq from='juliet@capulet.com/balcony' type='set' id='pub1'> <iq from='juliet@capulet.lit/balcony' type='set' id='pub1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='http://jabber.org/protocol/tune'> <publish node='http://jabber.org/protocol/tune'>
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
<title>Introduction (Allegro vigoroso)</title>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<track>1</track>
<length>255</length> <length>255</length>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<title>Introduction (Allegro vigoroso)</title>
<track>1</track>
</tune> </tune>
</item> </item>
</publish> </publish>
<configure>
<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#access_model'>
<value>presence</value>
</field>
</x>
</configure>
</pubsub> </pubsub>
</iq> </iq>
]]></example> ]]></example>
@ -196,12 +186,11 @@
<ol start='1'> <ol start='1'>
<li>It is sent with no 'to' address (see <link url='#approach-everyjid'>Every Account a Pubsub Service</link>).</li> <li>It is sent with no 'to' address (see <link url='#approach-everyjid'>Every Account a Pubsub Service</link>).</li>
<li>It specifies a node of "http://jabber.org/protocol/tune" (see <link url='#approach-onenode'>One Node per Namespace</link>).</li> <li>It specifies a node of "http://jabber.org/protocol/tune" (see <link url='#approach-onenode'>One Node per Namespace</link>).</li>
<li>It includes the desired node configuration, which here is a presence access model (see <link url='#approach-fire'>Fire and Forget</link>).</li>
</ol> </ol>
<p>If all goes well (see <link url='#publish'>Publishing Events</link>), everyone who is interested in what you are listening to will receive notification of the event:</p> <p>If all goes well (see <link url='#publish'>Publishing Events</link>), everyone who is interested in what you are listening to will receive notification of the event:</p>
<example caption='Interested parties receive event notifications'><![CDATA[ <example caption='Interested parties receive event notifications'><![CDATA[
<message from='juliet@capulet.com' <message from='juliet@capulet.lit'
to='romeo@montague.net/orchard' to='romeo@montague.lit/orchard'
type='headline' type='headline'
id='tunefoo1'> id='tunefoo1'>
<event xmlns='http://jabber.org/protocol/pubsub#event'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
@ -209,18 +198,18 @@
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
<title>Introduction (Allegro vigoroso)</title>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<track>1</track>
<length>255</length> <length>255</length>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<title>Introduction (Allegro vigoroso)</title>
<track>1</track>
</tune> </tune>
</item> </item>
</items> </items>
</event> </event>
</message> </message>
<message from='juliet@capulet.com' <message from='juliet@capulet.lit'
to='nurse@capulet.com/chamber' to='nurse@capulet.lit/chamber'
type='headline' type='headline'
id='tunefoo2'> id='tunefoo2'>
<event xmlns='http://jabber.org/protocol/pubsub#event'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
@ -228,29 +217,33 @@
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
<title>Introduction (Allegro vigoroso)</title>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<track>1</track>
<length>255</length> <length>255</length>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<title>Introduction (Allegro vigoroso)</title>
<track>1</track>
</tune> </tune>
</item> </item>
</items> </items>
</event> </event>
</message> </message>
]]></example> ]]></example>
<p>But how do Romeo and the Nurse tell your server that they are interested in knowing what you're listening to? In generic pubsub they need to explicitly subscribe to your "http://jabber.org/protocol/tune" node. <note>That is still necessary for open access model nodes in PEP if another user does not have a subscription to your presence, such as benvolio@montague.net in our scenario.</note> In PEP, they only need to advertise that they are interested by including some special flags (see <link url='#approach-filter'>Filtered Notifications</link>) in the &xep0115; information they include in their presence broadcasts (see <link url='#approach-presence'>Use Presence</link>).</p> <p>But how do Romeo and the Nurse tell your server that they are interested in knowing what you're listening to? In generic pubsub they need to explicitly subscribe to your "http://jabber.org/protocol/tune" node. <note>That is still necessary for open access model nodes in PEP if another user does not have a subscription to your presence, such as benvolio@montague.lit in our scenario.</note> But PEP services support two special features:</p>
<ol>
<li>"auto-subscribe" -- because they are subscribed to your presence, they automatically receive your events (see <link url='#approach-presence'>Use Presence</link>).</li>
<li>"filtered-notification" -- they can include some special flags in their &xep0115; information to specify which events they want to receive (see <link url='#approach-filter'>Filtered Notifications</link>).</li>
</ol>
<example caption='Romeo sends presence with caps'><![CDATA[ <example caption='Romeo sends presence with caps'><![CDATA[
<presence from='romeo@montague.net/orchard'> <presence from='romeo@montague.lit/orchard'>
<c xmlns='http://jabber.org/protocol/caps' <c xmlns='http://jabber.org/protocol/caps'
node='http://www.chatopus.com/ec' node='http://www.chatopus.com/ec'
ver='2.1' ver='2.1'
ext='sendmeloc sendmetunes'/> ext='sendmeloc sendmetunes'/>
</presence> </presence>
]]></example> ]]></example>
<p>Your server knows to send tune information to Romeo not directly because his client advertises an 'ext' value of "sendmetunes" (the 'ext' values have no semantic meaning in <cite>XEP-0115</cite>) but because the disco#info response from the "http://www.chatopus.com/ec#sendmetunes" node advertises a feature of "http://jabber.org/protocol/tune+notify", where the "+notify" suffix indicates interest in the protocol that precedes the suffix:</p> <p>Your server knows to send tune information to Romeo not because his client advertises an 'ext' value of "sendmetunes" (the 'ext' values have no semantic meaning in <cite>XEP-0115</cite>) but because the disco#info response from the "http://www.chatopus.com/ec#sendmetunes" node advertises a feature of "http://jabber.org/protocol/tune+notify", where the "+notify" suffix indicates interest in receiving notifications related to the protocol that precedes the suffix:</p>
<example caption='Disco#info result from extension'><![CDATA[ <example caption='Disco#info result from extension'><![CDATA[
<iq from='romeo@montague.net/orchard' <iq from='romeo@montague.lit/orchard'
to='juliet@capulet.com' to='juliet@capulet.lit'
type='result' type='result'
id='disco123'> id='disco123'>
<query xmlns='http://jabber.org/protocol/disco#info' <query xmlns='http://jabber.org/protocol/disco#info'
@ -264,7 +257,7 @@
<p>So that's the general idea. We'll demonstrate it again with an example of geolocation...</p> <p>So that's the general idea. We'll demonstrate it again with an example of geolocation...</p>
<p>First your client generates a geolocation event:</p> <p>First your client generates a geolocation event:</p>
<example caption='Publishing another event'><![CDATA[ <example caption='Publishing another event'><![CDATA[
<iq from='juliet@capulet.com/balcony' type='set' id='pub2'> <iq from='juliet@capulet.lit/balcony' type='set' id='pub2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='http://jabber.org/protocol/geoloc'> <publish node='http://jabber.org/protocol/geoloc'>
<item> <item>
@ -276,26 +269,13 @@
</geoloc> </geoloc>
</item> </item>
</publish> </publish>
<configure>
<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#access_model'>
<value>roster</value>
</field>
<field var='pubsub#roster_groups_allowed'>
<value>Friends</value>
</field>
</x>
</configure>
</pubsub> </pubsub>
</iq> </iq>
]]></example> ]]></example>
<p>Then your server sends event notifications, this time addressing the event only to Romeo, since the Nurse is not in your Friends roster group:</p> <p>Then your server sends event notifications, this time addressing the event only to Romeo, since the Nurse is not in your Friends roster group:</p>
<example caption='Interested parties receive event notifications'><![CDATA[ <example caption='Interested parties receive event notifications'><![CDATA[
<message from='juliet@capulet.com' <message from='juliet@capulet.lit'
to='romeo@montague.net/orchard' to='romeo@montague.lit/orchard'
type='headline' type='headline'
id='locfoo1'> id='locfoo1'>
<event xmlns='http://jabber.org/protocol/pubsub#event'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
@ -325,7 +305,6 @@
<li>Use presence.</li> <li>Use presence.</li>
<li>Filter notifications based on expressed interest.</li> <li>Filter notifications based on expressed interest.</li>
<li>Smart defaults.</li> <li>Smart defaults.</li>
<li>Fire and forget.</li>
</ol> </ol>
<p>These principles are described more fully below.</p> <p>These principles are described more fully below.</p>
<section2 topic='Every Account a Pubsub Service' anchor='approach-everyjid'> <section2 topic='Every Account a Pubsub Service' anchor='approach-everyjid'>
@ -342,54 +321,50 @@
<ul> <ul>
<li>Each messaging and presence account simply <em>is</em> a virtual publish-subscribe service.</li> <li>Each messaging and presence account simply <em>is</em> a virtual publish-subscribe service.</li>
<li>The default access model is "presence".</li> <li>The default access model is "presence".</li>
<li>A contact's subscription to an account owner's personal eventing data is normally handled via the existence of an XMPP presence subscription.</li> <li>A contact's subscription to an account owner's personal eventing data is automatically created because the contact has an XMPP presence subscription (the "auto-subscribe" feature).</li>
<li>Services take account of subscriber presence in the generation of notifications. <note>This works only if the subscription state is "both" (see <cite>RFC 3921</cite>).</note></li> <li>Services take account of subscriber presence in the generation of notifications. <note>This works only if the subscription state is "both" (see <cite>RFC 3921</cite>).</note></li>
</ul> </ul>
<p>These uses of presence simplify the task of developing compliant clients (cf. &xep0134;).</p> <p>These uses of presence simplify the task of developing compliant clients (cf. &xep0134;).</p>
</section2> </section2>
<section2 topic='Filtered Notifications' anchor='approach-filter'> <section2 topic='Filtered Notifications' anchor='approach-filter'>
<p>By default, the existence of an XMPP presence subscription is used to establish a PEP subscription to the account owner's personal eventing data. In order to filter which notifications are sent by the PEP service, the contact's client includes extended &xep0115; information in the presence notifications it sends to the account owner, and the PEP service sends only those notifications that match the contact's expressed notification preferences.</p> <p>By default, the existence of an XMPP presence subscription is used to establish a PEP subscription to the account owner's personal eventing data. In order to filter which notifications are sent by the PEP service, the contact's client includes extended &xep0115; information in the presence notifications it sends to the account owner. Because the PEP service supports the "filtered-notifications" feature, it sends only those notifications that match the contact's expressed notification preferences.</p>
</section2> </section2>
<section2 topic='Smart Defaults' anchor='approach-defaults'> <section2 topic='Smart Defaults' anchor='approach-defaults'>
<p>Most pubsub configuration options and metadata are not needed for personal eventing. Instead, PEP services offer smart defaults to simplify node creation and management.</p> <p>Most pubsub configuration options and metadata are not needed for personal eventing. Instead, PEP services offer smart defaults to simplify node creation and management.</p>
</section2> </section2>
<section2 topic='Fire and Forget' anchor='approach-fire'>
<p>A client should be able to publish an item without having to worry about whether the node exists; if the node does not exist, the server simply creates the node automatically and applies the specified configuration.</p>
</section2>
</section1> </section1>
<section1 topic='Publishing Events' anchor='publish'> <section1 topic='Publishing Events' anchor='publish'>
<p>An account owner publishes an item to a node by following the protocol specified in <cite>XEP-0060</cite>:</p> <p>An account owner publishes an item to a node by following the protocol specified in <cite>XEP-0060</cite>:</p>
<example caption='Account owner publishes item'><![CDATA[ <example caption='Account owner publishes item'><![CDATA[
<iq from='juliet@capulet.com/balcony' type='set' id='pub1'> <iq from='juliet@capulet.lit/balcony' type='set' id='pub1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='http://jabber.org/protocol/tune'> <publish node='http://jabber.org/protocol/tune'>
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
<title>Introduction (Allegro vigoroso)</title>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<track>1</track>
<length>255</length> <length>255</length>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<title>Introduction (Allegro vigoroso)</title>
<track>1</track>
</tune> </tune>
</item> </item>
</publish> </publish>
</pubsub> </pubsub>
</iq> </iq>
]]></example> ]]></example>
<p>If the node does not already exist, the PEP service MUST create the node (see <link url='approach-fire'>fire and forget</link>). This "auto-create" feature MUST be supported by a PEP service, but support for the feature is OPTIONAL on the part of a generic pubsub service. (Naturally, the account owner's client MAY follow the node creation use case specified in <cite>XEP-0060</cite> before attempting to publish an item.)</p> <p>If the node does not already exist, the PEP service MUST create the node. This "auto-create" feature MUST be supported by a PEP service, but support for the feature is OPTIONAL on the part of a generic pubsub service. (Naturally, the account owner's client MAY follow the node creation use case specified in <cite>XEP-0060</cite> before attempting to publish an item.)</p>
<p>Because PEP nodes may be automatically created, a client MAY specify the desired node configuration along with the publish request:</p>
<example caption='Publishing an event'><![CDATA[ <example caption='Publishing an event'><![CDATA[
<iq from='juliet@capulet.com/balcony' type='set' id='pub1'> <iq from='juliet@capulet.lit/balcony' type='set' id='pub1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'> <pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='http://jabber.org/protocol/tune'> <publish node='http://jabber.org/protocol/tune'>
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
<title>Introduction (Allegro vigoroso)</title>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<track>1</track>
<length>255</length> <length>255</length>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<title>Introduction (Allegro vigoroso)</title>
<track>1</track>
</tune> </tune>
</item> </item>
</publish> </publish>
@ -406,29 +381,6 @@
</pubsub> </pubsub>
</iq> </iq>
]]></example> ]]></example>
<p>The PEP service MUST process such a request in accordance with the rules shown in the table below. This "publish-and-configure" feature MUST be supported by a PEP service, but support for the feature is OPTIONAL on the part of a generic pubsub service.</p>
<table caption='Processing of Publish+Configure Requests'>
<tr>
<th>Case</th>
<th>Result</th>
</tr>
<tr>
<td>The node does not exist and the publish request does not include a &lt;configure/&gt; element.</td>
<td>The node is automatically created with default configuration (which for PEP nodes MUST be the presence access model) and the item is published.</td>
</tr>
<tr>
<td>The node does not exist and the publish request includes a &lt;configure/&gt; element.</td>
<td>The node is automatically created with the specified configuration and the item is published.</td>
</tr>
<tr>
<td>The node exists and the publish request does not include a &lt;configure/&gt; element.</td>
<td>The item is published and the node configuration is not modified.</td>
</tr>
<tr>
<td>The node exists and the publish request includes a &lt;configure/&gt; element.</td>
<td>If the specified configuration matches the existing node configuration, the item is published and the node configuration is not modified. If the specified configuration does not match the existing node configuration, the server returns a &conflict; error to the account owner (with an application-specific error of &lt;config-does-not-match/&gt;), the item is not published, and the node configuration is not modified.</td>
</tr>
</table>
<p>If the publication logic dictates that event notifications shall be sent, the account owner's server generates notifications and sends them to all appropriate entities as described in the <link url='#notify'>Receiving Event Notifications</link> section of this document, as well as to any of the account owner's available resources.</p> <p>If the publication logic dictates that event notifications shall be sent, the account owner's server generates notifications and sends them to all appropriate entities as described in the <link url='#notify'>Receiving Event Notifications</link> section of this document, as well as to any of the account owner's available resources.</p>
</section1> </section1>
@ -438,169 +390,18 @@
<li>The node has an open access model and the entity has explicitly discovered and subscribed to the node as explained in <cite>XEP-0060</cite>.</li> <li>The node has an open access model and the entity has explicitly discovered and subscribed to the node as explained in <cite>XEP-0060</cite>.</li>
<li>The entity shares presence with the account owner (see <link url='#notify-presence'>Presence Sharing</link>), is authorized to receive events from the node in accordance with the node access model (see <cite>XEP-0060</cite>), and advertises an interest in the payload type (see <link url='#notify-filter'>Notification Filtering</link>).</li> <li>The entity shares presence with the account owner (see <link url='#notify-presence'>Presence Sharing</link>), is authorized to receive events from the node in accordance with the node access model (see <cite>XEP-0060</cite>), and advertises an interest in the payload type (see <link url='#notify-filter'>Notification Filtering</link>).</li>
</ol> </ol>
<section2 topic='Presence Sharing' anchor='notify-presence'> <section2 topic='Automatic Subscriptions' anchor='notify-autosubscribe'>
<p>When a contact is affiliated with the account owner through a presence subscription, PEP greatly simplifies the subscription process. This is done by associating the presence subscription with a pubsub subscription to the account owner's root collection node (i.e., bare JID), with a subscription_type of "items" and a subscription_depth of "all".</p> <p>A PEP service MUST support the "auto-subscribe" feature defined in Section 10.1 of <cite>XEP-0060</cite>. This implies that when a user has an XMPP presence subscription to the account owner's presence, the user automatically also has a pubsub subscription account owner's root collection node (i.e., bare JID), with a subscription_type of "items" and a subscription_depth of "all".</p>
<p>Consider the following presence subscription exchange:</p>
<example caption='Presence subscription handshake'><![CDATA[
<presence from='nurse@capulet.com' to='juliet@capulet.com' type='subscribe'/>
<presence from='juliet@capulet.com' to='nurse@capulet.com' type='subscribed'/>
]]></example>
<p>For PEP purposes, this is equivalent to the following pubsub subscription exchange:</p>
<example caption='Entity subscribes to a collection node'><![CDATA[
<iq type='set'
from='nurse@capulet.com/chamber'
to='juliet@capulet.com
id='collsub'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<subscribe jid='nurse@capulet.com'/>
<options>
<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>
<iq type='result' from='juliet@capulet.com' to='nurse@capulet.com/chamber' id='collsub'/>
]]></example>
<p>Note: Automated pubsub subscriptions MUST be based on the JID contained in the 'from' address of the presence subscription request, which for IM contacts will be a bare JID (&BAREJID;).</p>
</section2> </section2>
<section2 topic='Notification Filtering' anchor='notify-filter'> <section2 topic='Notification Filtering' anchor='notify-filterednotifications'>
<p>A contact may not want to receive notifications for all payload types. A contact SHOULD signal its preferences to the account owner's server by including <cite>XEP-0115</cite> information that specifies the namespaces for which the contact wishes to receive notifications (if any).</p> <p>A PEP service MUST support the "filtered-notifications" feature defined in Section 10.2 of <cite>XEP-0060</cite>. This implies that when an automatic subscriber can specify which event payloads it wants to receive by including appropriate feature bundles in the <cite>XEP-0115</cite> information it broadcasts.</p>
<p>In order to make this possible, all possible payload namespaces can be appended with the string "+notify" to indicate that the contact wishes to receive notifications for the payload format. Thus if Romeo wants to receive notifications for activity data and geolocation data but not tune data, his client would advertise support for the following namespaces in the disco#info results it sends: <note>Including, say, the 'http://jabber.org/protocol/geoloc' namespace indicates that the client understands the geolocation namespace, whereas including the 'http://jabber.org/protocol/geoloc+notify' namespace indicates that the client wishes to receive notifications related to geolocation.</note></p>
<ul>
<li>http://jabber.org/protocol/geoloc+notify</li>
<li>http://jabber.org/protocol/tune+notify</li>
</ul>
<p>This set of namespaces would then be advertised as a <cite>XEP-0115</cite> "ext" value, such as the following:</p>
<example caption='Contact sends presence with caps'><![CDATA[
<presence from='romeo@montague.net/orchard'>
<c xmlns='http://jabber.org/protocol/caps'
node='http://www.chatopus.com/ec'
ver='2.1'
ext='sendmeloc tunes'/>
</presence>
]]></example>
<p>Note: In <cite>XEP-0115</cite>, the "ext" values are opaque strings with no semantic meaning.</p>
<p>It is the responsibility of the account owner's server to cache <cite>XEP-0115</cite> information (including "ext" values and their associated namespaces). When the server receives presence from a contact, it MUST check that presence information for entity capabilities data and correlate that data with the desired namespaces for the contact's client. The server MUST NOT send notifications related to any data formats that the contact's client has not asked for via the relevant "namespace+notify" disco#info feature. This enables a client to turn off all notifications (e.g., because of bandwidth restrictions) and to easily receive all desired data formats simply by adding support for the appropriate "namespace+notify" combination in its disco#info results and client capabililies. However, it also implies that a client can request notifications only on a global basis and cannot request, say, mood information only from certain contacts in the user's roster. Community consensus is that this is an acceptable tradeoff. Also, note that this works only if the account owner has a presence subscription to the contact and the contact has a presence subscription to the account owner.</p>
<p>Some examples may help to illustrate the concept of notification filtering. Here we show presence generated by two of the contacts listed above (benvolio@montague.net does have any presence subscriptions to or from juliet@capulet.com and therefore is not involved in these protocol flows).</p>
<example caption='Presence with caps'><![CDATA[
<presence from='nurse@capulet.com/chamber'>
<c xmlns='http://jabber.org/protocol/caps'
node='http://exodus.jabberstudio.org/caps'
ver='0.9'
ext='foo bar baz'/>
</presence>
<presence from='romeo@montague.net/orchard'>
<c xmlns='http://jabber.org/protocol/caps'
node='http://www.chatopus.com/ec'
ver='2.1'
ext='sendmeloc sendmetunes'/>
</presence>
]]></example>
<p>We assume that Juliet's server doesn't know anything about these capabilities, so it sends service discovery information requests to each of the clients on Juliet's behalf (realistically, the capulet.com server will quickly build up a cache of client capabilities, with the result that it will not need to send these service discovery requests):</p>
<example caption='Account server queries node#ver'><![CDATA[
<iq from='juliet@capulet.com'
to='nurse@capulet.com/chamber'
type='get'
id='disco123'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#0.9'/>
</iq>
<iq from='nurse@capulet.com/chamber'
to='juliet@capulet.com'
type='result'
id='disco123'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#0.9'/>
<feature var='http://jabber.org/protocol/tune'/>
<feature var='http://jabber.org/protocol/activity'/>
<feature var='http://jabber.org/protocol/geoloc'/>
</query>
</iq>
]]></example>
<p>Note: The disco#info result from the node#ver includes only base protocol support, since user-configured notification preferences are to be specified in entity capability extensions. Therefore the server also needs to query the relevant extensions:</p>
<example caption='Account server queries node#ext combinations'><![CDATA[
<iq from='juliet@capulet.com'
to='nurse@capulet.com/chamber'
type='get'
id='ext123'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#foo'/>
</iq>
<iq from='nurse@capulet.com/chamber'
to='juliet@capulet.com'
type='result'
id='ext123'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#foo'/>
<feature var='http://jabber.org/protocol/tune+notify'/>
</query>
</iq>
<iq from='juliet@capulet.com'
to='nurse@capulet.com/chamber'
type='get'
id='ext234'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#bar'/>
</iq>
<iq from='nurse@capulet.com/chamber'
to='juliet@capulet.com'
type='result'
id='ext234'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#bar'/>
<feature var='http://jabber.org/protocol/activity+notify'/>
</query>
</iq>
<iq from='juliet@capulet.com'
to='nurse@capulet.com/chamber'
type='get'
id='ext123'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#baz'/>
</iq>
<iq from='nurse@capulet.com/chamber'
to='juliet@capulet.com'
type='result'
id='ext123'>
<query xmlns='http://jabber.org/protocol/disco#info'
node='http://exodus.jabberstudio.org/caps#baz'/>
<feature var='http://jabber.org/protocol/geoloc+notify'/>
</query>
</iq>
]]></example>
<p>Note: As explained in <cite>XEP-0115</cite>, these requests would not all be sent to the same client and resource, but rather would be sent to random entities that advertise the same entity capabilities information.</p>
<p>The server shall also query the node#ver and node#ext combinations for other contacts (not shown here), which for &lt;romeo@montague.net&gt; indicate an interest in "http://jabber.org/protocol/geoloc+notify" and "http://jabber.org/protocol/tune+notify" but not "http://jabber.org/protocol/activity+notify".</p>
<p>Now we revisit account owner publication and server generation of notifications, with filtering enabled because the server has caps information:</p>
<ul>
<li><p>If Juliet publishes a tune item to the presence-access "http://jabber.org/protocol/tune" node, her server will send notifications to &lt;nurse@capulet.com/chamber&gt; and &lt;romeo@montague.net/orchard&gt; (full JIDs).</p></li>
<li><p>If Juliet publishes an activity item to the presence-access "http://jabber.org/protocol/activity" node, her server will send notifications only to &lt;nurse@capulet.com/chamber&gt;.</p></li>
<li><p>If Juliet publishes a geolocation item to the roster-access "http://jabber.org/protocol/geoloc" node, her server will send notifications only to &lt;romeo@montague.net/orchard&gt;.</p></li>
</ul>
</section2> </section2>
<section2 topic='Generating Notifications' anchor='notify-generate'> <section2 topic='Generating Notifications' anchor='notify-generate'>
<section3 topic='Addressing' anchor='notify-addressing'> <section3 topic='Addressing' anchor='notify-addressing'>
<ol start='1'> <ol start='1'>
<li><p>The server MUST set the 'from' address on the notification to the bare JID (&BAREJID;) of the account owner (in these examples, "juliet@capulet.com").</p></li> <li><p>The server MUST set the 'from' address on the notification to the bare JID (&BAREJID;) of the account owner (in these examples, "juliet@capulet.lit").</p></li>
<li><p>Any errors generated by the recipient or the recipient's server in relation to the notification MUST be directed to the JID of the 'from' address on the notification (i.e., the bare JID) so that bounce processing can be handled by the PEP service rather than by the publishing client.</p></li> <li><p>Any errors generated by the recipient or the recipient's server in relation to the notification MUST be directed to the JID of the 'from' address on the notification (i.e., the bare JID) so that bounce processing can be handled by the PEP service rather than by the publishing client.</p></li>
<li><p>When sending notifications to an entity that has a presence subscription to the account owner, the server SHOULD include an &xep0033; "replyto" extension specifying the publishing resource (in this example, "juliet@capulet.com/balcony"); this enables the subscriber's client to differentiate between information received from each of the account owner's resources (for example, different resources may be in different places and therefore may need to specify distinct geolocation data). However, a server MUST NOT include the "replyto" address when sending a notification to an entity that does not have a presence subscription to the account owner.</p></li> <li><p>When sending notifications to an entity that has a presence subscription to the account owner, the server SHOULD include an &xep0033; "replyto" extension specifying the publishing resource (in this example, "juliet@capulet.lit/balcony"); this enables the subscriber's client to differentiate between information received from each of the account owner's resources (for example, different resources may be in different places and therefore may need to specify distinct geolocation data). However, a server MUST NOT include the "replyto" address when sending a notification to an entity that does not have a presence subscription to the account owner.</p></li>
<li><p>If the PEP service has presence information about the intended recipient, it SHOULD direct the notification(s) to the full JID(s) of the recipients (&FULLJID;); if the PEP service does not have presence information about a subscriber, it MUST address the notification to the subscriber's bare JID (&BAREJID;).</p></li> <li><p>If the PEP service has presence information about the intended recipient, it SHOULD direct the notification(s) to the full JID(s) of the recipients (&FULLJID;); if the PEP service does not have presence information about a subscriber, it MUST address the notification to the subscriber's bare JID (&BAREJID;).</p></li>
</ol> </ol>
</section3> </section3>
@ -619,9 +420,9 @@
</ol> </ol>
</section3> </section3>
<section3 topic='Sending the Last Published Item' anchor='notify-last'> <section3 topic='Sending the Last Published Item' anchor='notify-last'>
<p>As mentioned, a PEP service MUST send the last published item to all new subscribers and to all newly-available resources for each subscriber. <note>That is, the default value of the "pubsub#send_last_published_item" node configuration field must be "on_sub_and_presence"; this behavior essentially mimics the functionality of presence as defined in <cite>XMPP IM</cite>.</note></p> <p>As mentioned, a PEP service MUST send the last published item to all new subscribers and to all newly-available resources for each subscriber. (That is, the default value of the "pubsub#send_last_published_item" node configuration field must be "on_sub_and_presence"; this behavior essentially mimics the functionality of presence as defined in <cite>XMPP IM</cite>.)</p>
<example caption='Subscriber sends presence from newly-available resource'><![CDATA[ <example caption='Subscriber sends presence from newly-available resource'><![CDATA[
<presence from='romeo@montague.net/orchard'> <presence from='romeo@montague.lit/orchard'>
<c xmlns='http://jabber.org/protocol/caps' <c xmlns='http://jabber.org/protocol/caps'
node='http://www.chatopus.com/ec' node='http://www.chatopus.com/ec'
ver='2.1' ver='2.1'
@ -629,7 +430,7 @@
</presence> </presence>
]]></example> ]]></example>
<example caption='Subscriber&apos;s server sends presence from newly-available resource to publisher&apos;s bare JID (i.e., PEP service)'><![CDATA[ <example caption='Subscriber&apos;s server sends presence from newly-available resource to publisher&apos;s bare JID (i.e., PEP service)'><![CDATA[
<presence from='romeo@montague.net/orchard' to='juliet@capulet.com'> <presence from='romeo@montague.lit/orchard' to='juliet@capulet.lit'>
<c xmlns='http://jabber.org/protocol/caps' <c xmlns='http://jabber.org/protocol/caps'
node='http://www.chatopus.com/ec' node='http://www.chatopus.com/ec'
ver='2.1' ver='2.1'
@ -637,8 +438,8 @@
</presence> </presence>
]]></example> ]]></example>
<example caption='PEP service sends last published item to newly-available resource'><![CDATA[ <example caption='PEP service sends last published item to newly-available resource'><![CDATA[
<message from='juliet@capulet.com' <message from='juliet@capulet.lit'
to='romeo@montague.net/orchard' to='romeo@montague.lit/orchard'
type='headline' type='headline'
id='foo'> id='foo'>
<event xmlns='http://jabber.org/protocol/pubsub#event'> <event xmlns='http://jabber.org/protocol/pubsub#event'>
@ -646,10 +447,10 @@
<item> <item>
<tune xmlns='http://jabber.org/protocol/tune'> <tune xmlns='http://jabber.org/protocol/tune'>
<artist>Gerald Finzi</artist> <artist>Gerald Finzi</artist>
<title>Introduction (Allegro vigoroso)</title>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<track>1</track>
<length>255</length> <length>255</length>
<source>Music for "Love's Labors Lost" (Suite for small orchestra)</source>
<title>Introduction (Allegro vigoroso)</title>
<track>1</track>
</tune> </tune>
</item> </item>
</items> </items>
@ -665,6 +466,7 @@
<p>A PEP service MUST:</p> <p>A PEP service MUST:</p>
<ul> <ul>
<li>Support the node discovery, node creation, node deletion, publish item, subscribe, unsubscribe, and item retrieval use cases specified in <cite>XEP-0060</cite>.</li> <li>Support the node discovery, node creation, node deletion, publish item, subscribe, unsubscribe, and item retrieval use cases specified in <cite>XEP-0060</cite>.</li>
<li>Support the "auto-create", "auto-subscribe", and "filtered-notifications" features.</li>
<li>Support the "owner" and "subscriber" affiliations.</li> <li>Support the "owner" and "subscriber" affiliations.</li>
<li>Support the "presence" access model and set it to the default.</li> <li>Support the "presence" access model and set it to the default.</li>
<li>Support the "open", "roster", and "whitelist" access models.</li> <li>Support the "open", "roster", and "whitelist" access models.</li>
@ -680,8 +482,8 @@
<section2 topic='Account Owner Service Discovery' anchor='disco-owner'> <section2 topic='Account Owner Service Discovery' anchor='disco-owner'>
<p>Naturally, before an account owner attempts to complete any PEP use cases, its client SHOULD determine whether the account owner's server supports PEP; to do so, it MUST send a &xep0030; information request to the server:</p> <p>Naturally, before an account owner attempts to complete any PEP use cases, its client SHOULD determine whether the account owner's server supports PEP; to do so, it MUST send a &xep0030; information request to the server:</p>
<example caption='Account owner queries server regarding protocol support'><![CDATA[ <example caption='Account owner queries server regarding protocol support'><![CDATA[
<iq from='juliet@capulet.com/balcony' <iq from='juliet@capulet.lit/balcony'
to='capulet.com' to='capulet.lit'
id='disco1' id='disco1'
type='get'> type='get'>
<query xmlns='http://jabber.org/protocol/disco#info'/> <query xmlns='http://jabber.org/protocol/disco#info'/>
@ -689,16 +491,20 @@
]]></example> ]]></example>
<p>If a server supports PEP, it MUST return an identity of "pubsub/pep" (as well as a list of the namespaces and other features it supports, including all supported <cite>XEP-0060</cite> features):</p> <p>If a server supports PEP, it MUST return an identity of "pubsub/pep" (as well as a list of the namespaces and other features it supports, including all supported <cite>XEP-0060</cite> features):</p>
<example caption='Server communicates protocol support'><![CDATA[ <example caption='Server communicates protocol support'><![CDATA[
<iq from='capulet.com' <iq from='capulet.lit'
to='juliet@capulet.com/balcony' to='juliet@capulet.lit/balcony'
id='disco1' id='disco1'
type='result'> type='result'>
<query xmlns='http://jabber.org/protocol/disco#info'> <query xmlns='http://jabber.org/protocol/disco#info'>
<identity category='server' type='im'/> <identity category='server' type='im'/>
<identity category='pubsub' type='pep'/> <identity category='pubsub' type='pep'/>
<feature var='http://jabber.org/protocol/pubsub#access-presence'/>
<feature var='http://jabber.org/protocol/pubsub#auto-create'/>
<feature var='http://jabber.org/protocol/pubsub#auto-subscribe'/>
<feature var='http://jabber.org/protocol/pubsub#config-node'/> <feature var='http://jabber.org/protocol/pubsub#config-node'/>
<feature var='http://jabber.org/protocol/pubsub#create-and-configure'/> <feature var='http://jabber.org/protocol/pubsub#create-and-configure'/>
<feature var='http://jabber.org/protocol/pubsub#create-nodes'/> <feature var='http://jabber.org/protocol/pubsub#create-nodes'/>
<feature var='http://jabber.org/protocol/pubsub#filtered-notifications'/>
<feature var='http://jabber.org/protocol/pubsub#persistent-items'/> <feature var='http://jabber.org/protocol/pubsub#persistent-items'/>
<feature var='http://jabber.org/protocol/pubsub#publish'/> <feature var='http://jabber.org/protocol/pubsub#publish'/>
<feature var='http://jabber.org/protocol/pubsub#retrieve-items'/> <feature var='http://jabber.org/protocol/pubsub#retrieve-items'/>
@ -714,28 +520,6 @@
</section2> </section2>
</section1> </section1>
<section1 topic='Pubsub Features' anchor='features'>
<p>This subset of Publish-Subscribe defines and registers two additional pubsub features, as shown in the following table.</p>
<p>Note: The feature names are of the form "http://jabber.org/protocol/pubsub#name", where "name" is the text specified in the first column below.</p>
<table caption='Service Discovery Features'>
<tr>
<th>Name</th>
<th>Description</th>
<th>Support</th>
</tr>
<tr>
<td>auto-create</td>
<td>The service supports auto-creation of nodes on publish to a non-existent node.</td>
<td>REQUIRED for PEP services, OPTIONAL for generic pubsub services</td>
</tr>
<tr>
<td>publish-and-configure</td>
<td>The service supports specification of desired node configuration on publish.</td>
<td>REQUIRED for PEP services, OPTIONAL for generic pubsub services</td>
</tr>
</table>
</section1>
<section1 topic='Implementation Notes' anchor='impl'> <section1 topic='Implementation Notes' anchor='impl'>
<section2 topic='Cancelling Subscriptions' anchor='impl-subscriptions'> <section2 topic='Cancelling Subscriptions' anchor='impl-subscriptions'>
<p>In order to ensure appropriate access to information published at nodes of type "presence" and "roster", a PEP service MUST re-calculate access controls when:</p> <p>In order to ensure appropriate access to information published at nodes of type "presence" and "roster", a PEP service MUST re-calculate access controls when:</p>
@ -745,9 +529,6 @@
</ol> </ol>
<p>If the modification results in a loss of access, the service MUST cancel the entity's subscription. In addition, the service MAY send a message to the (former) subscriber informing it of the cancellation (for information about the format of messages sent to notify subscribers of subscription cancellation, see the "Notification of Subscription Denial or Cancellation" section of <cite>XEP-0060</cite>).</p> <p>If the modification results in a loss of access, the service MUST cancel the entity's subscription. In addition, the service MAY send a message to the (former) subscriber informing it of the cancellation (for information about the format of messages sent to notify subscribers of subscription cancellation, see the "Notification of Subscription Denial or Cancellation" section of <cite>XEP-0060</cite>).</p>
</section2> </section2>
<section2 topic='Private Data Storage' anchor='impl-private'>
<p>A PEP node with an access model of "whitelist" and no entities on the whitelist effectively results in a node that enables private data storage, e.g. as defined in &xep0049;. A separate document will specify private data storage via PEP in more detail.</p>
</section2>
</section1> </section1>
<section1 topic='Security Considerations' anchor='security'> <section1 topic='Security Considerations' anchor='security'>
@ -776,21 +557,6 @@
</category> </category>
]]></code> ]]></code>
</section2> </section2>
<section2 topic='Service Discovery Features' anchor='registrar-features'>
<p>The XMPP Registrar maintains a registry of service discovery features (see &DISCOFEATURES;), which includes a number of features that may be returned by pubsub services. The following registry submission has been provided to the XMPP Registrar for that purpose.</p>
<code><![CDATA[
<var>
<name>http://jabber.org/protocol/pubsub#auto-create</name>
<desc>The service supports automatic creation of nodes on publish.</desc>
<doc>XEP-0163</doc>
</var>
<var>
<name>http://jabber.org/protocol/pubsub#publish-and-configure</name>
<desc>The service accepts node configuration forms on publish.</desc>
<doc>XEP-0163</doc>
</var>
]]></code>
</section2>
</section1> </section1>
<section1 topic='XML Schema' anchor='schema'> <section1 topic='XML Schema' anchor='schema'>