I have an Openfire server serving a bunch of group chat rooms (MUCs) to my web application, which interacts with Openfire using the Smack library. I'm trying to implement a feature in the app that allows MUC owners to destroy rooms that they own. Smack's MultiUserChat class has a method for this -- MultiUserChat.destroy(String, String). It's very simple:
muc.destroy("This room isn't getting used", null);
I don't get any compile errors or warnings when using destroy
in this manner. However, at runtime I get an XMPPErrorException when calling destroy
. This is the top of the stack trace:
org.jivesoftware.smack.XMPPException$XMPPErrorException: XMPPError: bad-request - modify
I went and read the XMPP MUC spec (XEP-0045) to see why a MUC destruction request might return a bad-request:modify. I know that a forbidden error will occur if the sender of the destruction request isn't the owner of the room, but that's not what is happening. I get a bad-request, not a forbidden. The spec doesn't give any indication as to why a bad-request might happen here, and the error doesn't give any indication as to what's bad about the request.
After seeing nothing related to a bad-request error in the XMPP spec, I booted up Wireshark so I could see the actual XMPP packets flowing back and forth between my application and the Openfire server. Everything looks basically as expected except for one thing: the MUC destruction packet my app sends to Openfire doesn't have a from
attribute in the <iq>
element.
My room destruction request:
<iq
to='[email protected]'
id='Pk4om-935'
type='set'>
<query
xmlns='http://jabber.org/protocol/muc#owner'>
<destroy jid=''>
<reason>Nobody is using this room</reason>
</destroy>
</query>
</iq>
XEP-0045 room destruction request sample:
<iq from='[email protected]/desktop'
id='begone'
to='[email protected]'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#owner'>
<destroy jid='[email protected]'>
<reason>Macbeth doth come.</reason>
</destroy>
</query>
</iq>
As you can see, my request doesn't have a from
attribute, but otherwise the two are almost identical (the jid
attribute of destroy
is explicitly optional, I don't want to use it). I dug into the Smack code and found where the destroy request gets built and it quite clearly doesn't set the from
attribute. Comments in this section of the code state that from
is usually optional and so can often be omitted, which may very well be true. However, I would expect that from
is required when destroying a room because only a room Owner is allowed to perform this action.
Has anyone used Smack to destroy Openfire MUC rooms before? If Smack always generates bad requests using the MultiUserChat.destroy(String, String) method, this seems like a major deficiency of the library. But, it's probably more likely that I am just misunderstanding how to use the method. Can any Smack/Openfire/XMPP experts help me out here?
Thank you!