Not logged in. · Lost password · Register
Forum: MatriX RSS
Avatar
alexypa #1
Member since Mar 2009 · 6 posts
Group memberships: Members
Show profile · Link to this post
Subject: XmppClient - OnXmlError
How can I catch a message that contains an Xml error (Matrix.Xml.Xpnet.InvalidTokenException thrown) and which triggers the OnXmlError event without closing the connection?

Alex
Avatar
Alex #2
Member since Feb 2003 · 4297 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
The invalid TokenException which shows sometimes in the debugger can be ignored. This is exception is there by design of the Xml tokenizer.
Because XMPP is streaming Xml, often only partial nodes are received from the socket. The tokenizer throws this exception to notify that we have a partial node and are waiting for the next socket receive until we can build a node from it. The buffer site in MatriX is 1024 bytes, so the debugger shows this exception on when stanzas > 1024 bytes gets received and received datadoes not end with a parseable node

The tokenizer (xpnet) is the same as used in agsXMPP, you can look there in the sources if you want.
OnXmlError gets raised only if we get invalid xml from the server which should never happen. This handler can be used when you write a server and deal with buggy clients.

Alex
Avatar
alexypa #3
Member since Mar 2009 · 6 posts
Group memberships: Members
Show profile · Link to this post
Thank you, Alex. In my test application I am sending an xml-serialized object from one client to another. It turned out that my agsXMPP-client assembled a message with invalid xml (no closing tags, etc) into an agsXMPP Message stanza. This stanza was submitted to the Jabber server who routed it to the MatriX client, which promptly raised the OnXmlError event followed by the OnClose event and shut down. I have since fixed the origin of the problem and unfortunately have no further evidence to share, but I am still concerned that either:

The agsXMPP client will send an invalid message stanza.
The server (Openfire) will pass such stanza to the roster
The receiving client will raise the OnXmlError, followed by the OnClose events and shut down.

If I recreate the issue, I will be sure to share it.

Alex
Avatar
Alex #4
Member since Feb 2003 · 4297 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
Quote by alexypa:
The agsXMPP client will send an invalid message stanza.

XmppConnection has a Send method which takes a string. This is passed directly to the socket. In this case the user has to check if the xml is valid. Custom packets should be build with the xml classes in agsXMPP.Xml.Dom, like descried in the custom packet doc. Normally the xml is valid then. But I am pretty sure that there are still ways to build invalid xml with agsXMPP.Xml.Dom as well ;-)

Quote by alexypa:
The server (Openfire) will pass such stanza to the roster
When the server received invalid Xml it must close the stream and return an error to the client. Some servers don't parse all Xml to get a higher throughput on packets and performance. I don't know if this applied to openfire. Can you post the invalid Xml you sent and ow you built it?
agsXMPP is also optimized for highest performance, and for this reason does not double check and validate the outgoing xml.

Quote by alexypa:
The receiving client will raise the OnXmlError, followed by the OnClose events and shut down.
This is correct, but the server should have done this before with client 1 and don't route the packet.

Alex
Avatar
alexypa #5
Member since Mar 2009 · 6 posts
Group memberships: Members
Show profile · Link to this post
I have to respectfully disagree with the third point you made below, Alex. I contend that the XMPP server as well as the frameworks underlying the receiving client, whether it is agsXMPP or Matrix, should never worry about the content contained in the body of the message. If there is string in the Body token, it should leave it alone and pass it to the application intact, without attempting to parse it. It is strictly the application's role to check the validity of the content.  IMHO, The agsXMPP or MatriX frameworks should never throw an exception caused by an event not under the application's control (an inbound message, in this case) and shut down the entire application without letting the application have the opportunity of catching the exception and handling it.

Alex
Avatar
Alex #6
Member since Feb 2003 · 4297 posts · Location: Germany
Group memberships: Administrators, Members
Show profile · Link to this post
agsXMPP and MatriX are responsible for the XMPP protocol, XMPP is based on a subset of Xml, and according to the RFCs the server must close the stream when there an XML error. Most XMPP libraries use a Sax like parser because the complete XMPP session is one big XML document. And any Sax parser will raise an XML error in this case, and is not able to process the rest of the stream/packet.
Of course you could build a XMPP library without parsing everything below the root node, and not care about the content, but this is likely to fail as well in many cases. Because you have to count the angle brackets so find the end of a stanza or split multiple stanzas.

This is an edge case because Openfire did not close the stream. If you try this code against some others server eg. ejabberd I am pretty sure that this packet will never be routed and client 1 gets disconnected with a stream error.

Anyway, you have to make sure that the XML which you send over the wire is always valid. And I think this is pretty easy when you build your packets with agsXMPP, Matrix, any other XML library or just include complex content as base64, JSON or any other technology which is XML compatible.

Alex
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Forum: MatriX RSS