mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-12-26 14:17:57 +01:00
[tcp] Do not send SM ack after we send a </stream:stream>
Do net put an ack to the queue if it has already been shutdown. Some servers, like ejabberd, like to request an ack even after we have send a stream close (and hance the queue was shutdown). If we would not check here, then the ack would dangle around in the queue, and be send on the next re-connection attempt even before the stream open. See the following trace of the MUC bookmarks integration test. The fact that it is a MUC test does not matter, but this test does disconnect the connection and reconnect it. Not how the server, ejabberd in this case, requests an SM ack by sending an <r/> even though we already send the </stream:stream>: 22:22:05 SENT (4): <iq id='MD4UC-61' type='set'> <query xmlns='jabber:iq:private'> <storage xmlns='storage:bookmarks'> <conference name='Smack Inttest: 7in7j' autojoin='true' jid='y9jcn5@conference.salem.geekplace.eu'> <nick> Nick-P2VXD7 </nick> </conference> </storage> </query> </iq> 22:22:05 RECV (4): <r xmlns='urn:xmpp:sm:3'/> 22:22:05 SENT (4): <a xmlns='urn:xmpp:sm:3' h='29'/> 22:22:05 RECV (4): <message to='sinttest-7in7j-4@salem.geekplace.eu' from='sinttest-7in7j-4@salem.geekplace.eu' type='headline'> <event xmlns='http://jabber.org/protocol/pubsub#event'> <items node='storage:bookmarks'> <item id='current'> <storage xmlns='storage:bookmarks'> <conference name='Smack Inttest: 7in7j' autojoin='true' jid='y9jcn5@conference.salem.geekplace.eu'> <nick> Nick-P2VXD7 </nick> </conference> </storage> </item> </items> </event> <addresses xmlns='http://jabber.org/protocol/address'> <address jid='sinttest-7in7j-4@salem.geekplace.eu/1415073683806426185213090' type='replyto'/> </addresses> </message> 22:22:05 RECV (4): <iq xml:lang='en-US' to='sinttest-7in7j-4@salem.geekplace.eu/1415073683806426185213090' from='sinttest-7in7j-4@salem.geekplace.eu' type='result' id='MD4UC-61'/> 22:22:05 SENT (4): <presence id='6MS6J-20' type='unavailable'/> <a xmlns='urn:xmpp:sm:3' h='31'/> <!-- We have closed the stream --> </stream:stream> <!-- But the server still requests an SM ack --> 22:22:05 RECV (4): <r xmlns='urn:xmpp:sm:3'/> 22:22:05 RECV (4): </stream:stream> 22:22:05 XMPPConnection closed (XMPPTCPConnection[sinttest-7in7j-4@salem.geekplace.eu/1415073683806426185213090] (4)) 22:22:05 SENT (4): <a xmlns='urn:xmpp:sm:3' h='31'/> 22:22:05 SENT (4): <stream:stream xmlns='jabber:client' to='salem.geekplace.eu' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='sinttest-7in7j-4@salem.geekplace.eu' xml:lang='en-US'> 22:22:05 RECV (4): ?xml version='1.0'?> <stream:stream id='3379123514446782311' ver 22:22:05 RECV (4): sion='1.0' xml:lang='en' xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client'> <stream:error> <invalid-xml xmlns='urn:ietf:params:xml:ns:xmpp-streams'/> </stream:error> </stream:stream> 22:22:05 XMPPConnection closed due to an exception (XMPPTCPConnection[sinttest-7in7j-4@salem.geekplace.eu/1415073683806426185213090] (4)) org.jivesoftware.smack.XMPPException$StreamErrorException: invalid-xml You can read more about the meaning of this stream error at http://xmpp.org/rfcs/rfc6120.html#streams-error-conditions <stream:error><invalid-xml xmlns='urn:ietf:params:xml:ns:xmpp-streams'/></stream:error> at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:981) at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$700(XMPPTCPConnection.java:913) at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:936) at java.base/java.lang.Thread.run(Thread.java:834)
This commit is contained in:
parent
488d01796a
commit
525ee09ea1
2 changed files with 30 additions and 1 deletions
|
@ -293,6 +293,30 @@ public class ArrayBlockingQueueWithShutdown<E> extends AbstractQueue<E> implemen
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Put if the queue has not been shutdown yet.
|
||||
*
|
||||
* @param e the element to put into the queue.
|
||||
* @return <code>true</code> if the element has been put into the queue, <code>false</code> if the queue was shutdown.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
* @since 4.4
|
||||
*/
|
||||
public boolean putIfNotShutdown(E e) throws InterruptedException {
|
||||
checkNotNull(e);
|
||||
lock.lockInterruptibly();
|
||||
|
||||
try {
|
||||
if (isShutdown) {
|
||||
return false;
|
||||
}
|
||||
|
||||
putInternal(e, true);
|
||||
return true;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void putAll(Collection<? extends E> elements) throws InterruptedException {
|
||||
checkNotNull(elements);
|
||||
lock.lockInterruptibly();
|
||||
|
|
|
@ -1592,7 +1592,12 @@ public class XMPPTCPConnection extends AbstractXMPPConnection {
|
|||
}
|
||||
|
||||
private void sendSmAcknowledgementInternal() throws NotConnectedException, InterruptedException {
|
||||
packetWriter.sendStreamElement(new AckAnswer(clientHandledStanzasCount));
|
||||
AckAnswer ackAnswer = new AckAnswer(clientHandledStanzasCount);
|
||||
// Do net put an ack to the queue if it has already been shutdown. Some servers, like ejabberd, like to request
|
||||
// an ack even after we have send a stream close (and hance the queue was shutdown). If we would not check here,
|
||||
// then the ack would dangle around in the queue, and be send on the next re-connection attempt even before the
|
||||
// stream open.
|
||||
packetWriter.queue.putIfNotShutdown(ackAnswer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue