Patch to enable unknown IQ messages to include childXML

I had a need to send IQ messages to a client, and then get the response(without modeling).

This mostly worked. I could attach a packetCollector for the packetId and get an IQ subclass. The only problerm was the unknown IQ dropped any childXML beneath. This patch creates a StringIQ class that simply stores any text underneath the IQ.

It also edited the parseContent method to use a StringBuffer instead of concatination.
specialIQ.patch.zip (1145 Bytes)

Logged as SMACK-423

Commited. I improved the patch here and there. Please check if it suits your needs.

Looks fine.

Thanks

Ah, there is a bug. The parent elements are not included. The parser is at the right level, but it immediately descents into any child elements. This seems to address that oversight.

diff -ruN orig/org/jivesoftware/smack/util/PacketParserUtils.java src/org/jivesoftware/smack/util/PacketParserUtils.java

— orig/org/jivesoftware/smack/util/PacketParserUtils.java 2013-05-04 06:14:42.000000000 -0500

+++ src/org/jivesoftware/smack/util/PacketParserUtils.java 2013-05-23 12:16:27.903156268 -0500

@@ -171,12 +171,13 @@

*/

private static String parseContent(XmlPullParser parser)

throws XmlPullParserException, IOException {

  •    StringBuffer content = new StringBuffer();
    
  •    StringBuffer content = new StringBuffer(parser.getText());
    

int parserDepth = parser.getDepth();

while (!(parser.next() == XmlPullParser.END_TAG && parser

.getDepth() == parserDepth)) {

content.append(parser.getText());

}

  •    content.append(parser.getText());
    

return content.toString();

}

Good idea. I have reopened SMACK-423. Please also attach the patch as unified ‘.patch’ file to your post in the feature. This makes it easier for us to apply the patch as we don’t have to copy and paste it form the post.

There doesn’t seem to be an attachment option in the replies. Here we go

https://gist.github.com/taer/9586e09865a67076d59c

A hint. You can press on “undefined” in the top right corner of the reply box (should say “Advanced editor”) and here you will find the attachment option.

Hi Flow. I see in 3.3.x this was removed in favor of a callback.

This callback doesn’t really help. My usage of the unparsedIQ was by creating a PacketCollector on the connection for a specific PacketId. This is done by multiple threads in parallel.

The callback is a singleton for the entire connection, and I lose the ability to use the packetCollector features to get my small pieces of XML.

Here is what we’re doing with the initial patch I sent in(the one that resulted in a StringIQ when it couldn’t find a handler).

https://gist.github.com/taer/f6359e999e46286c0a8b

I can’t see how a callback will be helpful in this case

So, your use case is that you want to collect IQ packages by their ID which doen’t have an IQ provider and therefore end as unparsedIQ. I hope I get that right.

UnparsablePacket is meant as debug help to make you aware that a provider is missing. It’s not meant to be used as part of your businnes logic. And without knowing anything else about your use case: Why don’t you simply create an IQ provider, register that provider and use it?

The use case is a simple one. An API that lets a non-xmpp client send random message via IQ to endpoint, and get the random IQ back and return to the client. A Rest->XMPP bridge.

Well ok, but the important question remains unanswered: Why don’t you create an IQProvider for those IQs?

Because the content is 100% unknown. I didn’t think a provider could be created to get all IQ messages.

And the iq stanza does not posses any extension element? Are you in control of the stanza generation?

It needs to look like this, so that a provider can handle it:

<iq type= id=…>

payload here, even if exact content is 100% unkown

In this particular case, we have no control over the stanzas. The best we can do is define providers for messages we support, but part of the feature set is effectively a REST->XMPP bridge(via IQ or message, the message one is working fine).

Thanks

You should approach the creator of the stanzas and convince him to wrap the payload into an extension element.

There will be more than one creator. We have no control over either side of the communication. Simply taking arbitrary XML via HTTP, embedding in IQ and sending. Getting the response, unwrapping it from the IQ, and returning via the HTTP response

Ok maybe I was not clear, it doesn’t matter if there is one or many creators. And I am not sure what you mean by “no control over either side of the communication”, because you obvisouly control the Smack side.

There is basically one layer missing. Instead of wrapping the content, arbitrary XML in your case, directly into an IQ, you, or whoever creates the stanzas, should wrap it first into an extension element and then into an IQ.

So that

<iq type= id=…>

payload here, even if exact content is 100% unkown

becomes

<iq type= id=…>

payload here, even if exact content is 100% unkown

This allows you to register an IQProvider for ‘myextension’ and all your problems are done.

For this use case, my control of the smack side is “place well formed XML submitted via HTTP POST inside an addressed IQ message and send to the end device”. When the end device responds, I use a packetID filter to capture an IQ response, unwrap the XML, and return it to the caller.

If I wrap that in an extension element, the end device will likely simply reject the request. We DO have an IQ extension you’re suggesting already. But it’s not flexible enough. Example.

If I wrapped that,

The device will reject the request due to being invalid.

BUT, I can already send the first example. Smack already supports sending random IQ contents to an endpoint without a provider. However, it lacks the ability to receive the response. What you get without patch is the IQ result with an empty body.

The StringIQ patch I sent in accomplished this. Another means might be to allow a “no match” provider to be registered that would receive any IQs that were not matched by others.

I really suggest fixing the end device then. I see no reason why

should be considerd invalid. IIRC It’s how all IQ stanzas are designed and perfectly valid XML.

I guess the leasson learned is: Don’t send paylod as IQ stanza without an extension element.