From bd709dc32379dcc60dfd230313f3c70c13d84d86 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 9 Oct 2013 17:02:34 +0000 Subject: [PATCH] SMACK-452 Correctly parse stream error packets Modified PacketParserUtils.parseStreamError() to take into account that there may be an optional text element and an optional application specific element. git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/branches/smack_3_3_2@13767 b35dd754-fafc-0310-a699-88a17e54d16e --- .../smack/packet/StreamError.java | 18 ++++ .../smack/util/PacketParserUtils.java | 26 ++++-- .../smack/packet/StreamErrorTest.java | 89 +++++++++++++++++++ 3 files changed, 126 insertions(+), 7 deletions(-) create mode 100644 test-unit/org/jivesoftware/smack/packet/StreamErrorTest.java diff --git a/source/org/jivesoftware/smack/packet/StreamError.java b/source/org/jivesoftware/smack/packet/StreamError.java index 8bb4c75bc..363e9fbb3 100644 --- a/source/org/jivesoftware/smack/packet/StreamError.java +++ b/source/org/jivesoftware/smack/packet/StreamError.java @@ -82,13 +82,21 @@ package org.jivesoftware.smack.packet; */ public class StreamError { + public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-streams"; + private String code; + private String text; public StreamError(String code) { super(); this.code = code; } + public StreamError(String code, String text) { + this(code); + this.text = text; + } + /** * Returns the error code. * @@ -98,9 +106,19 @@ public class StreamError { return code; } + /** + * Returns the error text, which may be null. + * + * @return the error text. + */ + public String getText() { + return text; + } + public String toString() { StringBuilder txt = new StringBuilder(); txt.append("stream:error (").append(code).append(")"); + if (text != null) txt.append(" text: ").append(text); return txt.toString(); } } diff --git a/source/org/jivesoftware/smack/util/PacketParserUtils.java b/source/org/jivesoftware/smack/util/PacketParserUtils.java index 57d539c59..7fba71f90 100644 --- a/source/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/source/org/jivesoftware/smack/util/PacketParserUtils.java @@ -695,21 +695,33 @@ public class PacketParserUtils { */ public static StreamError parseStreamError(XmlPullParser parser) throws IOException, XmlPullParserException { - StreamError streamError = null; + final int depth = parser.getDepth(); boolean done = false; + String code = null; + String text = null; while (!done) { int eventType = parser.next(); if (eventType == XmlPullParser.START_TAG) { - streamError = new StreamError(parser.getName()); - } - else if (eventType == XmlPullParser.END_TAG) { - if (parser.getName().equals("error")) { - done = true; + String namespace = parser.getNamespace(); + if (StreamError.NAMESPACE.equals(namespace)) { + String name = parser.getName(); + if (name.equals("text") && !parser.isEmptyElementTag()) { + parser.next(); + text = parser.getText(); + } + else { + // If it's not a text element, that is qualified by the StreamError.NAMESPACE, + // then it has to be the stream error code + code = name; + } } } + else if (eventType == XmlPullParser.END_TAG && depth == parser.getDepth()) { + done = true; + } } - return streamError; + return new StreamError(code, text); } /** diff --git a/test-unit/org/jivesoftware/smack/packet/StreamErrorTest.java b/test-unit/org/jivesoftware/smack/packet/StreamErrorTest.java new file mode 100644 index 000000000..9c3e9dfc6 --- /dev/null +++ b/test-unit/org/jivesoftware/smack/packet/StreamErrorTest.java @@ -0,0 +1,89 @@ +package org.jivesoftware.smack.packet; + +import static org.junit.Assert.*; + +import org.jivesoftware.smack.TestUtils; +import org.jivesoftware.smack.packet.StreamError; +import org.jivesoftware.smack.util.PacketParserUtils; +import org.junit.Test; +import org.xmlpull.v1.XmlPullParser; + +public class StreamErrorTest { + + @Test + public void testParsingOfSimpleStreamError() { + StreamError error = null; + final String xml = + // Usually the stream:stream element has more attributes (to, version, ...) + // We omit those, since they are not relevant for testing + "" + + "" + + " +" + + "" + + ""; + try { + XmlPullParser parser = TestUtils.getParser(xml, "error"); + error = PacketParserUtils.parseStreamError(parser); + } catch (Exception e) { + fail(e.getMessage()); + } + assertNotNull(error); + assertEquals("conflict", error.getCode()); + } + + @Test + public void testParsingOfStreamErrorWithText() { + StreamError error = null; + final String xml = + // Usually the stream:stream element has more attributes (to, version, ...) + // We omit those, since they are not relevant for testing + "" + + "" + + "" + + "" + + "Replaced by new connection" + + "" + + "" + + ""; + try { + XmlPullParser parser = TestUtils.getParser(xml, "error"); + error = PacketParserUtils.parseStreamError(parser); + } catch (Exception e) { + fail(e.getMessage()); + } + assertNotNull(error); + assertEquals("conflict", error.getCode()); + assertEquals("Replaced by new connection", error.getText()); + } + + @Test + public void testParsingOfStreamErrorWithTextAndOptionalElement() { + StreamError error = null; + final String xml = + // Usually the stream:stream element has more attributes (to, version, ...) + // We omit those, since they are not relevant for testing + "" + + "" + + "" + + "" + + "Replaced by new connection" + + "" + + "" + + "Text contents of application-specific condition element: Foo Bar" + + "" + + "" + + ""; + try { + XmlPullParser parser = TestUtils.getParser(xml, "error"); + error = PacketParserUtils.parseStreamError(parser); + } catch (Exception e) { + fail(e.getMessage()); + } + assertNotNull(error); + assertEquals("conflict", error.getCode()); + assertEquals("Replaced by new connection", error.getText()); + // As of now, Smack ignores application-specific condition elements, so we don't + // test them. + } + +}