Smack version: 4.5.0-alpha1-SNAPSHOT (4.3.4-856-g0a6c21982-master 2020-09-07)
XMPP message text received in phase openFrameSent
:
<open xmlns="urn:ietf:params:xml:ns:xmpp-framing" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" from="REMOVED" id="REMOVED" xml:lang="en"></open>
Relevant code from OkHttpWebSocket
:
case openFrameSent:
if (isOpenElement(text)) {
// Converts the <open> element received into <stream> element.
openStreamHeader = getStreamFromOpenElement(text);
Relevant code for AbstractWebSocket.getStreamFromOpenElement(String)
:
protected static String getStreamFromOpenElement(String openElement) {
String streamElement = openElement.replaceFirst("\\A<open ", "<stream ")
.replace("urn:ietf:params:xml:ns:xmpp-framing", "jabber:client")
.replaceFirst("/>\\s*\\z", ">");
return streamElement;
}
This method returns:
<stream xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0" from="REMOVED" id="REMOVED" xml:lang="en"></open>
This results in a parse error, which causes the connection to fail.
The relevant specification from RFC 7395:
3.3.1. Framed XML Stream
The start of a framed XML stream is marked by the use of an opening “stream header”, which is an <open/> element with the appropriate attributes and namespace declarations (see Section 3.3.2). The attributes of the <open/> element are the same as those of the <stream/> element defined for the ‘http://etherx.jabber.org/streams’ namespace RFC6120 and with the same semantics and restrictions.
Although the RFC references the <open/>
element in self-closing style, it also references the <stream/>
element in self-closing style. It would not make much sense to have a self-closing <stream/>
element, therefore I don’t think the specification implies a requirement that the <open/>
element must self-close, because it doesn’t explicitly specify it as self-closing.
It seems AbstractWebSocket.getStreamFromOpenElement(String)
has a bug because it does not handle this scenario.