aTalk is trying to add BOSH support using smack-Bosh library, but facing problem. As I am still no familiar with the whole BOSH setup protocol, so not sure whether problem is due to aTalk implementation or smack-Bosh library.
Below is the debug log for initial login via BOSH on aTalk. As smack-Bosh only provides log for received messages from server, I have modified BoshClient class to dump the BOSH send messages from client. As the debug messages from SEND/RECEIVED are not sync, the captured BOSH response message in the log may come before request from server (by few tens of ms).
During aTalk login, based on the ConnectionListener, it receives callback only for: connected(XMPPConnection connection)
immediately after that: connectionClosedOnError(Exception exception)
However from the debug log, it did received the authentication <success/> response from server.
According to the XEP spec: XEP-0206: XMPP Over BOSH
I see that smack-BOSH ends the whole login process at Example 8.Restart request
I would not recommend doing so right now. First smack-bosh is unmaintained horrible code and probably full of bugs. Second, I do plan to change how Smack does with the different transport mechanisms in the coming months™. I suggest to wait until that arrvies before you start adding support for BOSH.
aTalk has restarted the testing of BOSH connection using smack libraries built based on smack master repository source. Following is the observation on aTalk as per XEP-0206 standard:
Also currently there is no debug message for the stream data sent by BoshClient#send(). Appreciate if smack team would provide the debug log messages to ease the app development.
Edited by cmeng (20191017): actually already included in code. Just need to add writer.flush();
However it works until the following OMEMO exception.
Need investigation.
============== aTalk BOSH Connection debug log =============
2019-10-18 13:29:06.643 4732-5086/org.atalk.android D/SMACK: SENT (0):
<body rid='6089744892666124' sid='d57be2adf43b95d223f76e45a28b786d7a5b5227' xmlns='http://jabber.org/protocol/httpbind'>
<iq xmlns='jabber:client' id='62U8K-91' type='set'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='eu.siacs.conversations.axolotl.bundles:595475613'>
<item xmlns='http://jabber.org/protocol/pubsub'>
<bundle xmlns='eu.siacs.conversations.axolotl'>
<signedPreKeyPublic signedPreKeyId='4'>
BVqedxs4xxfZy3JemrbYVzU2BeZNXMXGUGy18bXeGf1V
</signedPreKeyPublic>
<signedPreKeySignature>
n9+hlTU0Acw2uF9bRMQLMczgcczGdu++TDurFhiwIpQ/thYDqt3/9GXcBnCh32rZ+icT7ii7ZbsvxKb/elpJgw==
</signedPreKeySignature>
<identityKey>
BWl44UKxSDEAYKMuzSRsavIyPk2FadrYm2K3tdQvpKEp
</identityKey>
<prekeys>
<preKeyPublic preKeyId='1'>
Ba2lvLjZha56q41hEd0N7Ta/Ci5Pg+fg+slt9HDlSnQ0
</preKeyPublic>
<preKeyPublic preKeyId='2'>
BWaVj+duXWK1s3gps8VfCycJD7cM05CukauYdXT2yMVT
</preKeyPublic>
<preKeyPublic preKeyId='3'>
BYrUzMZE2Njj54tWVg+OmRTQ+oaePJ2B/StBZ6ry2d8F
</preKeyPublic>
<preKeyPublic preKeyId='4'>
BSlUabLRfXEpoMhZXLVe73kQofthtLPKYJSkVId2E5Vh
</preKeyPublic>
....
<preKeyPublic preKeyId='22'>
Bb2YpRkhiHoPgrRNEL2ubE5SgoK3pVyv97bx92GYJ0pU
</preKeyPublic>
<preKeyPublic preKeyId='23'>
BTUnWUdS2w3V0FHrdO9W5/vZcEbQh9RErid7T0yzAzUO
</preKeyPublic>
<preKeyPublic preKeyId='24'>
BaNrEorxFVd+yKsCfnTc6cltqaVhj/P11f5iPVua1fk8
2019-10-18 13:29:06.644 4732-5086/org.atalk.android D/SMACK: SENT (0):
2019-10-18 13:29:06.646 4732-5078/org.atalk.android D/NetworkManagementSocketTagger: tagSocket(74) with statsTag=0xffffffff, statsUid=-1
2019-10-18 13:29:06.669 4732-5078/org.atalk.android I/NetworkManagementSocketTagger: untagSocket(74)
2019-10-18 13:29:06.669 4732-5078/org.atalk.android I/System.out: RequestProcessor[31289853]: Receive thread 1 calls detatch()
2019-10-18 13:29:06.689 4732-5086/org.atalk.android E/(AndroidOmemoService.java:123)#initializationFailed: OmemoManager init failed
org.jivesoftware.smack.SmackException$NotConnectedException: The connection XMPPBOSHConnection[swordfish@atalk.sytes.net/atalk] (0) is no longer connected while waiting for response with IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=62U8K-91)), : fromFilter (OrFilter: (FromMatchesFilter (full): null, FromMatchesFilter (ignoreResourcepart): swordfish@atalk.sytes.net, FromMatchesFilter (full): atalk.sytes.net)) because of org.igniterealtime.jbosh.BOSHException: Could not parse body:
<?xml version='1.0'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<h1>400 Bad Request</h1>
at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:276)
at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:228)
at org.jivesoftware.smackx.pubsub.LeafNode.publish(LeafNode.java:330)
at org.jivesoftware.smackx.pubsub.LeafNode.publish(LeafNode.java:309)
at org.jivesoftware.smackx.pubsub.PubSubManager.tryToPublishAndPossibleAutoCreate(PubSubManager.java:452)
at org.jivesoftware.smackx.pep.PepManager.publish(PepManager.java:165)
at org.jivesoftware.smackx.omemo.OmemoService.publishBundle(OmemoService.java:592)
at org.jivesoftware.smackx.omemo.OmemoService.init(OmemoService.java:260)
at org.jivesoftware.smackx.omemo.OmemoManager.initialize(OmemoManager.java:251)
at org.jivesoftware.smackx.omemo.OmemoManager$2.run(OmemoManager.java:266)
at java.lang.Thread.run(Thread.java:764)
Caused by: org.igniterealtime.jbosh.BOSHException: Could not parse body:
<?xml version='1.0'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<h1>400 Bad Request</h1>
at org.igniterealtime.jbosh.BodyParserXmlPull.parse(BodyParserXmlPull.java:132)
at org.igniterealtime.jbosh.StaticBody.fromString(StaticBody.java:114)
at org.igniterealtime.jbosh.ApacheHTTPResponse.awaitResponse(ApacheHTTPResponse.java:246)
at org.igniterealtime.jbosh.ApacheHTTPResponse.getBody(ApacheHTTPResponse.java:192)
at org.igniterealtime.jbosh.BOSHClient.processExchange(BOSHClient.java:1122)
at org.igniterealtime.jbosh.BOSHClient.processMessages(BOSHClient.java:998)
at org.igniterealtime.jbosh.BOSHClient.access$300(BOSHClient.java:100)
at org.igniterealtime.jbosh.BOSHClient$RequestProcessor.run(BOSHClient.java:1727)
... 1 more
Caused by: java.lang.IllegalStateException: Root element was not 'body' in the 'http://jabber.org/protocol/httpbind' namespace. (Was 'h1' in '')
at org.igniterealtime.jbosh.BodyParserXmlPull.parse(BodyParserXmlPull.java:98)
at org.igniterealtime.jbosh.BodyParserXmlPull.parse(BodyParserXmlPull.java:132)
at org.igniterealtime.jbosh.StaticBody.fromString(StaticBody.java:114)
at org.igniterealtime.jbosh.ApacheHTTPResponse.awaitResponse(ApacheHTTPResponse.java:246)
at org.igniterealtime.jbosh.ApacheHTTPResponse.getBody(ApacheHTTPResponse.java:192)
at org.igniterealtime.jbosh.BOSHClient.processExchange(BOSHClient.java:1122)
at org.igniterealtime.jbosh.BOSHClient.processMessages(BOSHClient.java:998)
at org.igniterealtime.jbosh.BOSHClient.access$300(BOSHClient.java:100)
at org.igniterealtime.jbosh.BOSHClient$RequestProcessor.run(BOSHClient.java:1727)
2019-10-18 13:29:06.697 4732-5094/org.atalk.android W/aTalk: [88438] org.jivesoftware.smack.AbstractXMPPConnection.callConnectionClosedOnErrorListener() Connection XMPPBOSHConnection[swordfish@atalk.sytes.net/atalk] (0) closed with error
org.igniterealtime.jbosh.BOSHException: Could not parse body:
<?xml version='1.0'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<h1>400 Bad Request</h1>
at org.igniterealtime.jbosh.BodyParserXmlPull.parse(BodyParserXmlPull.java:132)
at org.igniterealtime.jbosh.StaticBody.fromString(StaticBody.java:114)
at org.igniterealtime.jbosh.ApacheHTTPResponse.awaitResponse(ApacheHTTPResponse.java:246)
at org.igniterealtime.jbosh.ApacheHTTPResponse.getBody(ApacheHTTPResponse.java:192)
at org.igniterealtime.jbosh.BOSHClient.processExchange(BOSHClient.java:1122)
at org.igniterealtime.jbosh.BOSHClient.processMessages(BOSHClient.java:998)
at org.igniterealtime.jbosh.BOSHClient.access$300(BOSHClient.java:100)
at org.igniterealtime.jbosh.BOSHClient$RequestProcessor.run(BOSHClient.java:1727)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.IllegalStateException: Root element was not 'body' in the 'http://jabber.org/protocol/httpbind' namespace. (Was 'h1' in '')
at org.igniterealtime.jbosh.BodyParserXmlPull.parse(BodyParserXmlPull.java:98)
at org.igniterealtime.jbosh.StaticBody.fromString(StaticBody.java:114)
at org.igniterealtime.jbosh.ApacheHTTPResponse.awaitResponse(ApacheHTTPResponse.java:246)
at org.igniterealtime.jbosh.ApacheHTTPResponse.getBody(ApacheHTTPResponse.java:192)
at org.igniterealtime.jbosh.BOSHClient.processExchange(BOSHClient.java:1122)
at org.igniterealtime.jbosh.BOSHClient.processMessages(BOSHClient.java:998)
at org.igniterealtime.jbosh.BOSHClient.access$300(BOSHClient.java:100)
at org.igniterealtime.jbosh.BOSHClient$RequestProcessor.run(BOSHClient.java:1727)
at java.lang.Thread.run(Thread.java:764)
Finally found the causes of the problem in BOSH connection (see below log)
The reason is AbstractXMPPConnection#incomingStreamXmlEnvironment parameter is initialized with called from XMPPTCPConnection
parsePackets {
case "stream":
onStreamOpen(parser);
break;
}
on receive of <Steam:stream/> Nonza which is not present when using BOSHConnection.
Below is the patch to make BoshConnection work. The patch includes a temporary patch (for aTalk) to init the incomingStreamXmlEnvironment which requires further work by smack team.
============= aTalk BoshConnection log =============
2019-10-18 18:12:34.792 32593-32722/org.atalk.android W/aTalk: [89545] org.jivesoftware.smack.AbstractXMPPConnection.callConnectionClosedOnErrorListener() Connection XMPPBOSHConnection[swordfish@atalk.sytes.net/atalk] (0) closed with error
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String org.jivesoftware.smack.packet.XmlEnvironment.getEffectiveLanguage()' on a null object reference
at org.jivesoftware.smack.util.ParserUtils.getXmlLang(ParserUtils.java:350)
at org.jivesoftware.smack.util.PacketParserUtils.parseCommonStanzaAttributes(PacketParserUtils.java:134)
at org.jivesoftware.smack.util.PacketParserUtils.parseMessage(PacketParserUtils.java:159)
at org.jivesoftware.smack.util.PacketParserUtils.parseStanza(PacketParserUtils.java:114)
at org.jivesoftware.smack.AbstractXMPPConnection.parseAndProcessStanza(AbstractXMPPConnection.java:1330)
at org.jivesoftware.smack.bosh.XMPPBOSHConnection.access$1600(XMPPBOSHConnection.java:68)
at org.jivesoftware.smack.bosh.XMPPBOSHConnection$BOSHPacketReader.responseReceived(XMPPBOSHConnection.java:512)
at org.igniterealtime.jbosh.BOSHClient.fireResponseReceived(BOSHClient.java:1609)
at org.igniterealtime.jbosh.BOSHClient.processExchange(BOSHClient.java:1144)
at org.igniterealtime.jbosh.BOSHClient.processMessages(BOSHClient.java:998)
at org.igniterealtime.jbosh.BOSHClient.access$300(BOSHClient.java:100)
at org.igniterealtime.jbosh.BOSHClient$RequestProcessor.run(BOSHClient.java:1727)
at java.lang.Thread.run(Thread.java:764)
It seems that currently there is also problem in error handling when there is an BOSHException
2019-10-19 10:03:58.769 23709-24548/org.atalk.android E/(AndroidOmemoService.java:123)#initializationFailed: OmemoManager init failed
org.jivesoftware.smack.SmackException$NotConnectedException: The connection XMPPBOSHConnection[swordfish@atalk.sytes.net/atalk] (0) is no longer connected while waiting for response with IQReplyFilter: iqAndIdFilter (AndFilter: (OrFilter: (IQTypeFilter: type=error, IQTypeFilter: type=result), StanzaIdFilter: id=172IL-91)), : fromFilter (OrFilter: (FromMatchesFilter (full): null, FromMatchesFilter (ignoreResourcepart): swordfish@atalk.sytes.net, FromMatchesFilter (full): atalk.sytes.net)) because of org.igniterealtime.jbosh.BOSHException: Could not parse body:
<?xml version='1.0'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<h1>400 Bad Request</h1>
at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:276)
at org.jivesoftware.smack.StanzaCollector.nextResultOrThrow(StanzaCollector.java:228)
at org.jivesoftware.smackx.pubsub.LeafNode.publish(LeafNode.java:330)
at org.jivesoftware.smackx.pubsub.LeafNode.publish(LeafNode.java:309)
at org.jivesoftware.smackx.pubsub.PubSubManager.tryToPublishAndPossibleAutoCreate(PubSubManager.java:452)
at org.jivesoftware.smackx.pep.PepManager.publish(PepManager.java:165)
at org.jivesoftware.smackx.omemo.OmemoService.publishBundle(OmemoService.java:592)
at org.jivesoftware.smackx.omemo.OmemoService.init(OmemoService.java:260)
at org.jivesoftware.smackx.omemo.OmemoManager.initialize(OmemoManager.java:251)
at org.jivesoftware.smackx.omemo.OmemoManager$2.run(OmemoManager.java:266)
at java.lang.Thread.run(Thread.java:764)
Caused by: org.igniterealtime.jbosh.BOSHException: Could not parse body:
<?xml version='1.0'?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<h1>400 Bad Request</h1>
at org.igniterealtime.jbosh.BodyParserXmlPull.parse(BodyParserXmlPull.java:132)
at org.igniterealtime.jbosh.StaticBody.fromString(StaticBody.java:114)
at org.igniterealtime.jbosh.ApacheHTTPResponse.awaitResponse(ApacheHTTPResponse.java:246)
at org.igniterealtime.jbosh.ApacheHTTPResponse.getBody(ApacheHTTPResponse.java:192)
at org.igniterealtime.jbosh.BOSHClient.processExchange(BOSHClient.java:1122)
at org.igniterealtime.jbosh.BOSHClient.processMessages(BOSHClient.java:998)
at org.igniterealtime.jbosh.BOSHClient.access$300(BOSHClient.java:100)
at org.igniterealtime.jbosh.BOSHClient$RequestProcessor.run(BOSHClient.java:1727)
... 1 more
Caused by: java.lang.IllegalStateException: Root element was not 'body' in the 'http://jabber.org/protocol/httpbind' namespace. (Was 'h1' in '')
at org.igniterealtime.jbosh.BodyParserXmlPull.parse(BodyParserXmlPull.java:98)
at org.igniterealtime.jbosh.BodyParserXmlPull.parse(BodyParserXmlPull.java:132)
at org.igniterealtime.jbosh.StaticBody.fromString(StaticBody.java:114)
at org.igniterealtime.jbosh.ApacheHTTPResponse.awaitResponse(ApacheHTTPResponse.java:246)
at org.igniterealtime.jbosh.ApacheHTTPResponse.getBody(ApacheHTTPResponse.java:192)
at org.igniterealtime.jbosh.BOSHClient.processExchange(BOSHClient.java:1122)
at org.igniterealtime.jbosh.BOSHClient.processMessages(BOSHClient.java:998)
at org.igniterealtime.jbosh.BOSHClient.access$300(BOSHClient.java:100)
at org.igniterealtime.jbosh.BOSHClient$RequestProcessor.run(BOSHClient.java:1727)