resources). If the contact is in the user’s roster with either
of those states, the user’s server (1) MUST deliver the presence
stanza of type "subscribed" from the contact to the user; (2)
MUST initiate a roster push to all of the user’s available
resources that have requested the roster, containing an updated
roster item for the contact with the ’subscription’ attribute set
to a value of "to"; and (3) MUST deliver the available presence
stanza received from each of the contact’s available resources to
each of the user’s available resources:
<presence
to=’user@example.com’
from=’contact@example.org’
type=’subscribed’/>
<iq type=’set’>
<query xmlns=’jabber:iq:roster’>
<item
jid=’contact@example.org’
subscription=’to’
name=’MyContact’>
<group>MyBuddies</group>
</item>
</query>
</iq>
<presence
from=’contact@example.org/resource’
to=’user@example.com/resource’/>
9. Upon receiving the presence stanza of type "subscribed", the user
SHOULD acknowledge receipt of that subscription state
notification through either "affirming" it by sending a presence
stanza of type "subscribe" to the contact or "denying" it by
sending a presence stanza of type "unsubscribe" to the contact;
this step does not necessarily affect the subscription state (see
Subscription States (Section 9) for details), but instead lets
the user’s server know that it MUST no longer send notification
of the subscription state change to the user (see Section 9.4).
From the perspective of the user, there now exists a subscription to
the contact’s presence information; from the perspective of the
contact, there now exists a subscription from the user.
8.2.1. Alternate Flow: Contact Declines Subscription Request
The above activity flow represents the "happy path" regarding the
user’s subscription request to the contact. The main alternate flow
occurs if the contact refuses the user’s subscription request, as
described below.
1. If the contact wants to refuse the request, the contact’s client
MUST send a presence stanza of type "unsubscribed" to the user
(instead of the presence stanza of type "subscribed" sent in Step
6 of Section 8.2):
<presence to=’user@example.com’ type=’unsubscribed’/>
2. As a result, the contact’s server MUST route the presence stanza
of type "unsubscribed" to the user, first stamping the ’from’
address as the bare JID (<contact@example.org>) of the contact:
<presence
from=’contact@example.org’
to=’user@example.com’
type=’unsubscribed’/>
Note: If the contact’s server previously added the user to the
contact’s roster for tracking purposes, it MUST remove the relevant
item at this time.
3. Upon receiving the presence stanza of type "unsubscribed"
addressed to the user, the user’s server (1) MUST deliver that
presence stanza to the user and (2) MUST initiate a roster push
to all of the user’s available resources that have requested the
roster, containing an updated roster item for the contact with
the ’subscription’ attribute set to a value of "none" and with no
’ask’ attribute:
<presence
from=’contact@example.org’
to=’user@example.com’
type=’unsubscribed’/>
<iq type=’set’>
<query xmlns=’jabber:iq:roster’>
<item
jid=’contact@example.org’
subscription=’none’
name=’MyContact’>
<group>MyBuddies</group>
</item>
</query>
</iq>
4. Upon receiving the presence stanza of type "unsubscribed", the
user SHOULD acknowledge receipt of that subscription state
notification through either "affirming" it by sending a presence
stanza of type "unsubscribe" to the contact or "denying" it by
sending a presence stanza of type "subscribe" to the contact;
this step does not necessarily affect the subscription state (see
Subscription States (Section 9) for details), but instead lets
the user’s server know that it MUST no longer send notification
of the subscription state change to the user (see Section 9.4).
As a result of this activity, the contact is now in the user’s roster
with a subscription state of "none", whereas the user is not in the
contact’s roster at all.
8.3. Creating a Mutual Subscription
The user and contact can build on the "happy path" described above to
create a mutual subscription (i.e., a subscription of type "both").
The process is described below.
1. If the contact wants to create a mutual subscription, the contact
MUST send a subscription request to the user (subject to the
contact’s configured preferences, the contact’s client MAY send
this automatically):
<presence to=’user@example.com’ type=’subscribe’/>
2. As a result, the contact’s server (1) MUST initiate a roster push
to all available resources associated with the contact that have
requested the roster, with the user still in the ’from’
subscription state but with a pending ’to’ subscription denoted
by the inclusion of the ask=’subscribe’ attribute in the roster
item; and (2) MUST route the presence stanza of type "subscribe"
to the user, first stamping the ’from’ address as the bare JID
(<contact@example.org>) of the contact:
<iq type=’set’>
<query xmlns=’jabber:iq:roster’>
<item
jid=’user@example.com’
subscription=’from’
ask=’subscribe’
name=’SomeUser’>
<group>SomeGroup</group>
</item>
</query>
</iq>
<presence
from=’contact@example.org’
to=’user@example.com’
type=’subscribe’/>
Note: If the contact’s server receives a presence stanza of type
"error" from the user’s server, it MUST deliver the error stanza to
the contact, whose client MAY determine that the error is in response
to the outgoing presence stanza of type "subscribe" it sent
previously (e.g., by tracking an ’id’ attribute) and then choose to
resend the "subscribe" request or revert the roster to its previous
state by sending a presence stanza of type "unsubscribe" to the user.
3. Upon receiving the presence stanza of type "subscribe" addressed
to the user, the user’s server must determine if there is at
least one available resource for which the user has requested the
roster. If so, the user’s server MUST deliver the subscription
request to the user (if not, it MUST store the subscription
request offline for delivery when this condition is next met). No
matter when the subscription request is delivered, the user must
then decide whether or not to approve it (subject to the user’s
configured preferences, the user’s client MAY approve or refuse
the subscription request without presenting it to the user).
Here we assume the "happy path" that the user approves the
subscription request (the alternate flow of declining the
subscription request is defined in Section 8.3.1). In this case,
the user’s client MUST send a presence stanza of type
"subscribed" to the contact in order to approve the subscription
request.
<presence to=’contact@example.org’ type=’subscribed’/>
4. As a result, the user’s server (1) MUST initiate a roster push to
all of the user’s available resources that have requested the
roster, containing a roster item for the contact with the
’subscription’ attribute set to a value of "both"; (2) MUST route
the presence stanza of type "subscribed" to the contact, first
stamping the ’from’ address as the bare JID (<user@example.com>)
of the user; and (3) MUST send to the contact the full XML of the
last presence stanza with no ’to’ attribute received by the
server from each of the user’s available resources (subject to
privacy lists in force for each session):
<iq type=’set’>
<query xmlns=’jabber:iq:roster’>
<item
jid=’contact@example.org’
subscription=’both’
name=’MyContact’>
<group>MyBuddies</group>
</item>
</query>
</iq>
<presence
from=’user@example.com’
to=’contact@example.org’
type=’subscribed’/>
<presence
from=’user@example.com/resource’
to=’contact@example.org’/>
Note: If the user’s server receives a presence stanza of type "error"
from the contact’s server, it MUST deliver the error stanza to the
user, whose client MAY determine that the error is in response to the
outgoing presence stanza of type "subscribed" it sent previously
(e.g., by tracking an ’id’ attribute) and then choose to resend the
subscription request or revert the roster to its previous state by
sending a presence stanza of type "unsubscribed" to the contact.
5. Upon receiving the presence stanza of type "subscribed" addressed
to the contact, the contact’s server MUST first verify that the
user is in the contact’s roster with either of the following
states: (a) subscription=’none’ and ask=’subscribe’ or (b)
subscription=’from’ and ask=’subscribe’. If the user is not in
the contact’s roster with either of those states, the contact’s
server MUST silently ignore the presence stanza of type
"subscribed" (i.e., it MUST NOT route it to the contact, modify
the contact’s roster, or generate a roster push to the contact’s
available resources). If the user is in the contact’s roster
with either of those states, the contact’s server (1) MUST
deliver the presence stanza of type "subscribed" from the user to
the contact; (2) MUST initiate a roster push to all available
resources associated with the contact that have requested the
roster, containing an updated roster item for the user with the
’subscription’ attribute set to a value of "both"; and (3) MUST
deliver the available presence stanza received from each of the
user’s available resources to each of the contact’s available
resources:
<presence
from=’user@example.com’
to=’contact@example.org’
type=’subscribed’/>
<iq type=’set’>
<query xmlns=’jabber:iq:roster’>
<item
jid=’user@example.com’
subscription=’both’
name=’SomeUser’>
<group>SomeGroup</group>
</item>
</query>
</iq>
<presence
from=’user@example.com/resource’
to=’contact@example.org/resource’/>
6. Upon receiving the presence stanza of type "subscribed", the
contact SHOULD acknowledge receipt of that subscription state
notification through either "affirming" it by sending a presence
stanza of type "subscribe" to the user or "denying" it by sending
a presence stanza of type "unsubscribe" to the user; this step
does not necessarily affect the subscription state (see
Subscription States (Section 9) for details), but instead lets
the contact’s server know that it MUST no longer send
notification of the subscription state change to the contact (see
Section 9.4).
The user and the contact now have a mutual subscription to each
other’s presence -- i.e., the subscription is of type "both".
8.3.1. Alternate Flow: User Declines Subscription Request
The above activity flow represents the "happy path" regarding the
contact’s subscription request to the user. The main alternate flow
occurs if the user refuses the contact’s subscription request, as
described below.
1. If the user wants to refuse the request, the user’s client MUST
send a presence stanza of type "unsubscribed" to the contact
(instead of the presence stanza of type "subscribed" sent in Step
3 of Section 8.3):
<presence to=’contact@example.org’ type=’unsubscribed’/>
2. As a result, the user’s server MUST route the presence stanza of
type "unsubscribed" to the contact, first stamping the ’from’
address as the bare JID (<user@example.com>) of the user:
<presence
from=’user@example.com’
to=’contact@example.org’
type=’unsubscribed’/>
3. Upon receiving the presence stanza of type "unsubscribed"
addressed to the contact, the contact’s server (1) MUST deliver
that presence stanza to the contact; and (2) MUST initiate a
roster push to all available resources associated with the
contact that have requested the roster, containing an updated
roster item for the user with the ’subscription’ attribute set to
a value of "from" and with no ’ask’ attribute:
<presence
from=’user@example.com’
to=’contact@example.org’
type=’unsubscribed’/>
<iq type=’set’>
<query xmlns=’jabber:iq:roster’>
<item
jid=’user@example.com’
subscription=’from’
name=’SomeUser’>
<group>SomeGroup</group>
</item>
</query>
</iq>
4. Upon receiving the presence stanza of type "unsubscribed", the
contact SHOULD acknowledge receipt of that subscription state
notification through either "affirming" it by sending a presence
stanza of type "unsubscribe" to the user or "denying" it by
sending a presence stanza of type "subscribe" to the user; this
step does not necessarily affect the subscription state (see
Subscription States (Section 9) for details), but instead lets
the contact’s server know that it MUST no longer send
notification of the subscription state change to the contact (see
Section 9.4).
As a result of this activity, there has been no change in the
subscription state; i.e., the contact is in the user’s roster with a
subscription state of "to" and the user is in the contact’s roster
with a subscription state of "from".
8.4. Unsubscribing
At any time after subscribing to a contact’s presence information, a
user MAY unsubscribe. While the XML that the user sends to make this
happen is the same in all instances, the subsequent subscription
state is different depending on the subscription state obtaining when
the unsubscribe "command" is sent. Both possible scenarios are
described below.
8.4.1. Case #1: Unsubscribing When Subscription is Not Mutual
In the first case, the user has a subscription to the contact’s
presence information but the contact does not have a subscription to
the user’s presence information (i.e., the subscription is not yet
mutual).
1. If the user wants to unsubscribe from the contact’s presence
information, the user MUST send a presence stanza of type
"unsubscribe" to the contact:
<presence to=’contact@example.org’ type=’unsubscribe’/>
2. As a result, the user’s server (1) MUST send a roster push to all
of the user’s available resources that have requested the roster,
containing an updated roster item for the contact with the
’subscription’ attribute set to a value of "none"; and (2) MUST
route the presence stanza of type "unsubscribe" to the contact,
first stamping the ’from’ address as the bare JID
(<user@example.com>) of the user:
<iq type=’set’>
<query xmlns=’jabber:iq:roster’>
<item
jid=’contact@example.org’
subscription=’none’
name=’MyContact’>
<group>MyBuddies</group>
</item>
</query>
</iq>
<presence
from=’user@example.com’
to=’contact@example.org’
type=’unsubscribe’/>
3. Upon receiving the presence stanza of type "unsubscribe"
addressed to the contact, the contact’s server (1) MUST initiate
a roster push to all available resources associated with the
contact that have requested the roster, containing an updated
roster item for the user with the ’subscription’ attribute set to
a value of "none" (if the contact is unavailable or has not
requested the roster, the contact’s server MUST modify the roster
item and send that modified item the next time the contact
requests the roster); and (2) MUST deliver the "unsubscribe"
state change notification to the contact:
<iq type=’set’>
<query xmlns=’jabber:iq:roster’>
<item
jid=’user@example.com’
subscription=’none’
name=’SomeUser’>
<group>SomeGroup</group>
</item>
</query>
</iq>
<presence
from=’user@example.com’
to=’contact@example.org’
type=’unsubscribe’/>
4. Upon receiving the presence stanza of type "unsubscribe", the
contact SHOULD acknowledge receipt of that subscription state
notification through either "affirming" it by sending a presence
stanza of type "unsubscribed" to the user or "denying" it by
sending a presence stanza of type "subscribed" to the user; this
step does not necessarily affect the subscription state (see
Subscription States (Section 9) for details), but instead lets
the contact’s server know that it MUST no longer send
notification of the subscription state change to the contact (see
Section 9.4).
5. The contact’s server then (1) MUST send a presence stanza of type
"unsubscribed" to the user; and (2) SHOULD send unavailable
presence from all of the contact’s available resources to the
user:
<presence
from=’contact@example.org’
to=’user@example.com’
type=’unsubscribed’/>
<presence
from=’contact@example.org/resource’
to=’user@example.com’
type=’unavailable’/>
6. When the user’s server receives the presence stanzas of type
"unsubscribed" and "unavailable", it MUST deliver them to the
user:
<presence
from=’contact@example.org’
to=’user@example.com’
type=’unsubscribed’/>
<presence
from=’contact@example.org/resource’
to=’user@example.com’
type=’unavailable’/>
7. Upon receiving the presence stanza of type "unsubscribed", the
user SHOULD acknowledge receipt of that subscription state
notification through either "affirming" it by sending a presence
stanza of type "unsubscribe" to the contact or "denying" it by
sending a presence stanza of type "subscribe" to the contact;
this step does not necessarily affect the subscription state (see
Subscription States (Section 9) for details), but instead lets
the user’s server know that it MUST no longer send notification
of the subscription state change to the user (see Section 9.4).
8.4.2. Case #2: Unsubscribing When Subscription is Mutual
In the second case, the user has a subscription to the contact’s
presence information and the contact also has a subscription to the
user’s presence information (i.e., the subscription is mutual).
1. If the user wants to unsubscribe from the contact’s presence
information, the user MUST send a presence stanza of type
"unsubscribe" to the contact:
<presence to=’contact@example.org’ type=’unsubscribe’/>
2. As a result, the user’s server (1) MUST send a roster push to all
of the user’s available resources that have requested the roster,
containing an updated roster item for the contact with the
’subscription’ attribute set to a value of "from"; and (2) MUST
route the presence stanza of type "unsubscribe" to the contact,
first stamping the ’from’ address as the bare JID
(<user@example.com>) of the user:
<iq type=’set’>
<query xmlns=’jabber:iq:roster’>
<item
jid=’contact@example.org’
subscription=’from’
name=’MyContact’>
<group>MyBuddies</group>
</item>
</query>
</iq>
<presence
from=’user@example.com’
to=’contact@example.org’
type=’unsubscribe’/>
3. Upon receiving the presence stanza of type "unsubscribe"
addressed to the contact, the contact’s server (1) MUST initiate
a roster push to all available resources associated with the
contact that have requested the roster, containing an updated
roster item for the user with the ’subscription’ attribute set to
a value of "to" (if the contact is unavailable or has not
requested the roster, the contact’s server MUST modify the roster
item and send that modified item the next time the contact
requests the roster); and (2) MUST deliver the "unsubscribe"
state change notification to the contact:
<iq type=’set’>
<query xmlns=’jabber:iq:roster’>
<item
jid=’user@example.com’
subscription=’to’
name=’SomeUser’>
<group>SomeGroup</group>
</item>
</query>
</iq>
<presence
from=’user@example.com’
to=’contact@example.org’
type=’unsubscribe’/>
4. Upon receiving the presence stanza of type "unsubscribe", the
contact SHOULD acknowledge receipt of that subscription state
notification through either "affirming" it by sending a presence
stanza of type "unsubscribed" to the user or "denying" it by
sending a presence stanza of type "subscribed" to the user; this
step does not necessarily affect the subscription state (see
Subscription States (Section 9) for details), but instead lets
the contact’s server know that it MUST no longer send
notification of the subscription state change to the contact (see
Section 9.4).
5. The contact’s server then (1) MUST send a presence stanza of type
"unsubscribed" to the user; and (2) SHOULD send unavailable
presence from all of the contact’s available resources to the
user:
<presence
from=’contact@example.org’
to=’user@example.com’
type=’unsubscribed’/>
<presence
from=’contact@example.org/resource’
to=’user@example.com’