If I am sending a presence subscription request (type="subscribe") to another user in order to subscribe to its presence and add some <status> text to provide some additional text as suggested in:
The <status/> child MAY also be sent in a subscription-related presence stanza (i.e., type "subscribe", "subscribed", "unsubscribe", or "unsubscribed") to provide a description of the action. An interactive client MAY present this <status/> information to a human user (see Section 11).
and also add a nickname as suggested by XEP-172:
Openfire will drop the <status> and nickname, in case the recipient is offline.
E.g. the outgoing presence looks like this:
If 222@dev is offline, Openfire will send only:
as soon as it comes online.
(Any other extension is probably dropped, too)
I come across the issue yesterday as I extended a presence stanza for my project. I downloaded the OF sources, did some experiments and found the issue might not be fixed easily.
An offline message stanza is stored in the "ofoffline" table with a "stanza" field which keeps the entire xml contents of the message including the custom parts if any.
A subscription presence will be routed without modification if the recipient is online. The problem is that, if the recipient is offline, however, the subscription presence will be converted to a RosterItem which is backed by the "ofroster" table with "sub", "ask" and "recv" fields to identify the type. As the recipient goes online, a new presence stanza will be created from the "ofroster" table and sent to the recipient. There is no "stanza" or alike field and thus any extra information is dropped. To sum up, the "ofroster" table is designed to combine the roster and subscription presence information together, but loses important information in recipient offline situation.
To resolve the issue, we need to:
Add extra fields to the "ofroster" table to store stanza contents (or create a new table to store the offline presence stanzas).
Update related OF modules accordingly, such as the cache module.
Some related classes I inspected are:
PresenceSubscribeHandler (manageSub() method especially)
Hope it helps.
Yes it's not easy to fix.
The problem is already, that subscription status is stored in the roster table. That means, you can't have a subscription to a contact, without having that contact in your roster. It would probably not make much sense, but I think it's allowed by XMPP.
In my opinion the cleanest approach would be to have a "pure" roster table with only the roster item information (jid, nickname, group) and a subscription table which holds the subscription state (e.g. "pending in + none") + presence stanza.
The problem now is, that a subscription request from User A to Contact B results in a roster item addition to Contact B's roster, even if Contact B declines the subscription, resulting in bugs like OF-317.
This issue violates XMPP core specification RFC 6121:
Otherwise, if the contact has no available resources when the subscription request is received by the contact's server, then the contact's server MUST keep a record of the complete presence stanza comprising the subscription request, including any extended content contained therein