Hello community,

here is the log from the commit of package python-nbxmpp for openSUSE:Factory 
checked in at 2017-11-09 14:07:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-nbxmpp (Old)
 and      /work/SRC/openSUSE:Factory/.python-nbxmpp.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-nbxmpp"

Thu Nov  9 14:07:42 2017 rev:15 rq:540013 version:0.6.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-nbxmpp/python-nbxmpp.changes      
2017-06-12 15:29:05.184669150 +0200
+++ /work/SRC/openSUSE:Factory/.python-nbxmpp.new/python-nbxmpp.changes 
2017-11-09 14:07:43.781401975 +0100
@@ -1,0 +2,11 @@
+Sun Nov  5 16:38:49 UTC 2017 - [email protected]
+
+- Update to version 0.6.0:
+  * Add new getOriginID/SetOriginID method for Messages
+  * Add new getJid() method for Protocol
+  * getTagAttr() accepts now a namespace argument
+  * Add new `protocol` argument for getTag()
+  * Add new XEP Namespaces
+  * Support XEP-0198 Version 1.5.2
+
+-------------------------------------------------------------------

Old:
----
  nbxmpp-0.5.5.tar.gz

New:
----
  nbxmpp-0.6.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-nbxmpp.spec ++++++
--- /var/tmp/diff_new_pack.A0ipKn/_old  2017-11-09 14:07:45.101353874 +0100
+++ /var/tmp/diff_new_pack.A0ipKn/_new  2017-11-09 14:07:45.105353729 +0100
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define _name   nbxmpp
 Name:           python-nbxmpp
-Version:        0.5.5
+Version:        0.6.0
 Release:        0
 Summary:        XMPP library by Gajim team
 License:        GPL-3.0+

++++++ nbxmpp-0.5.5.tar.gz -> nbxmpp-0.6.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nbxmpp-0.5.5/ChangeLog new/nbxmpp-0.6.0/ChangeLog
--- old/nbxmpp-0.5.5/ChangeLog  2017-01-30 22:34:33.000000000 +0100
+++ new/nbxmpp-0.6.0/ChangeLog  2017-09-25 22:18:45.000000000 +0200
@@ -1,3 +1,16 @@
+python-nbxmpp 0.6.0 (25 September 2017)
+
+ * Add new getOriginID/SetOriginID method for Messages
+ * Add new getJid() method for Protocol
+ * getTagAttr() accepts now a namespace argument
+ * Add new `protocol` argument for getTag()
+ * Add new XEP Namespaces
+
+python-nbxmpp 0.5.6 (03 June 2017)
+
+  * Support XEP-0198 Version 1.5.2
+  * Add new XEP Namespaces
+
 python-nbxmpp 0.5.5 (30 January 2017)
 
   * Some cleanup
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nbxmpp-0.5.5/PKG-INFO new/nbxmpp-0.6.0/PKG-INFO
--- old/nbxmpp-0.5.5/PKG-INFO   2017-01-30 22:49:18.000000000 +0100
+++ new/nbxmpp-0.6.0/PKG-INFO   2017-09-25 22:20:36.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: nbxmpp
-Version: 0.5.5
+Version: 0.6.0
 Summary: Non blocking Jabber/XMPP module
 Home-page: http://dev.gajim.org/gajim/python-nbxmpp
 Author: Yann Leboulanger
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nbxmpp-0.5.5/nbxmpp/__init__.py 
new/nbxmpp-0.6.0/nbxmpp/__init__.py
--- old/nbxmpp-0.5.5/nbxmpp/__init__.py 2017-01-30 22:40:44.000000000 +0100
+++ new/nbxmpp-0.6.0/nbxmpp/__init__.py 2017-09-25 22:18:45.000000000 +0200
@@ -17,4 +17,4 @@
 from .plugin import PlugIn
 from .smacks import Smacks
 
-__version__ = "0.5.5"
+__version__ = "0.6.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nbxmpp-0.5.5/nbxmpp/auth_nb.py 
new/nbxmpp-0.6.0/nbxmpp/auth_nb.py
--- old/nbxmpp-0.5.5/nbxmpp/auth_nb.py  2017-01-01 23:13:23.000000000 +0100
+++ new/nbxmpp-0.6.0/nbxmpp/auth_nb.py  2017-06-04 14:17:22.000000000 +0200
@@ -731,12 +731,13 @@
                 self.bound.append(resp.getTag('bind').getTagData('jid'))
                 log.info('Successfully bound %s.' % self.bound[-1])
                 jid = JID(resp.getTag('bind').getTagData('jid'))
+                self._owner._registered_name = jid
                 self._owner.User = jid.getNode()
                 self._owner.Resource = jid.getResource()
                 # Only negociate stream management after bounded
-                sm = self._owner._caller.sm
                 if self.supports_sm:
                     # starts negociation
+                    sm = self._owner._caller.sm
                     sm.supports_sm = True
                     sm.set_owner(self._owner)
                     sm.negociate()
@@ -745,6 +746,7 @@
                 if hasattr(self, 'session') and self.session == -1:
                     # Server don't want us to initialize a session
                     log.info('No session required.')
+                    self._owner._caller.sm.resend_queue()   #resend old 
messages still in the smacks queue
                     self.on_bound('ok')
                 else:
                     self._owner.SendAndWaitForResponse(Protocol('iq', 
typ='set',
@@ -763,6 +765,7 @@
         if isResultNode(resp):
             log.info('Successfully opened session.')
             self.session = 1
+            self._owner._caller.sm.resend_queue()   #resend old messages still 
in the smacks queue
             self.on_bound('ok')
         else:
             log.error('Session open failed.')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nbxmpp-0.5.5/nbxmpp/dispatcher_nb.py 
new/nbxmpp-0.6.0/nbxmpp/dispatcher_nb.py
--- old/nbxmpp-0.5.5/nbxmpp/dispatcher_nb.py    2017-01-01 23:13:23.000000000 
+0100
+++ new/nbxmpp-0.6.0/nbxmpp/dispatcher_nb.py    2017-06-04 14:17:22.000000000 
+0200
@@ -23,12 +23,14 @@
 from __future__ import unicode_literals
 from . import simplexml
 import sys
+import time
 import locale
 import re
 import uuid
+import copy
 from xml.parsers.expat import ExpatError
 from .plugin import PlugIn
-from .protocol import (NS_STREAMS, NS_XMPP_STREAMS, NS_HTTP_BIND, Iq, Presence,
+from .protocol import (NS_DELAY2, NS_STREAMS, NS_XMPP_STREAMS, NS_HTTP_BIND, 
Iq, Presence,
         Message, Protocol, Node, Error, ERR_FEATURE_NOT_IMPLEMENTED, 
StreamError)
 import logging
 
@@ -387,7 +389,7 @@
 
     def UnregisterCycleHandler(self, handler):
         """
-        Unregister handler that will is called on every Dispatcher.Process() 
call
+        Unregister handler that will be called on every Dispatcher.Process() 
call
         """
         if handler in self._cycleHandlers:
             self._cycleHandlers.remove(handler)
@@ -569,14 +571,25 @@
                 if self._owner._registered_name and not stanza.getAttr('from'):
                     stanza.setAttr('from', self._owner._registered_name)
 
+        self._owner.Connection.send(stanza, now)
+
         # If no ID then it is a whitespace
         if self.sm and self.sm.enabled and ID:
+            # add timestamp to message stanza in queue
+            if (stanza.getName() == 'message' and
+                    stanza.getType() in ('chat', 'groupchat')):
+                timestamp = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
+                attrs = {'stamp': timestamp}
+                if stanza.getType() != 'groupchat':
+                    # Dont leak our JID to Groupchats
+                    attrs['from'] = stanza.getAttr('from')
+                stanza.addChild('delay', namespace=NS_DELAY2, attrs=attrs)
             self.sm.uqueue.append(stanza)
             self.sm.out_h += 1
+
             if len(self.sm.uqueue) > self.sm.max_queue:
                 self.sm.request_ack()
 
-        self._owner.Connection.send(stanza, now)
         return ID
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nbxmpp-0.5.5/nbxmpp/protocol.py 
new/nbxmpp-0.6.0/nbxmpp/protocol.py
--- old/nbxmpp-0.5.5/nbxmpp/protocol.py 2017-01-30 22:24:18.000000000 +0100
+++ new/nbxmpp-0.6.0/nbxmpp/protocol.py 2017-08-05 21:17:49.000000000 +0200
@@ -24,6 +24,7 @@
 import time
 import string
 import hashlib
+from base64 import b64encode
 
 def ascii_upper(s):
     return s.upper()
@@ -88,6 +89,7 @@
 NS_HTTP_BIND      = 'http://jabber.org/protocol/httpbind'             # 
XEP-0124
 NS_HTTPUPLOAD     = 'urn:xmpp:http:upload'                            # 
XEP-0363
 NS_IBB            = 'http://jabber.org/protocol/ibb'
+NS_IDLE           = 'urn:xmpp:idle:1'                                 # 
XEP-0319
 NS_INVISIBLE      = 'presence-invisible'                              # 
Jabberd2
 NS_IQ             = 'iq'                                              # 
Jabberd2
 NS_JINGLE         ='urn:xmpp:jingle:1'                                # 
XEP-0166
@@ -95,7 +97,8 @@
 NS_JINGLE_RTP     = 'urn:xmpp:jingle:apps:rtp:1'                      # 
XEP-0167
 NS_JINGLE_RTP_AUDIO = 'urn:xmpp:jingle:apps:rtp:audio'                # 
XEP-0167
 NS_JINGLE_RTP_VIDEO = 'urn:xmpp:jingle:apps:rtp:video'                # 
XEP-0167
-NS_JINGLE_FILE_TRANSFER ='urn:xmpp:jingle:apps:file-transfer:3'        # 
XEP-0234
+NS_JINGLE_FILE_TRANSFER = 'urn:xmpp:jingle:apps:file-transfer:3'      # 
XEP-0234
+NS_JINGLE_FILE_TRANSFER_5 = 'urn:xmpp:jingle:apps:file-transfer:5'    # 
XEP-0234
 NS_JINGLE_XTLS='urn:xmpp:jingle:security:xtls:0'                      # XTLS: 
EXPERIMENTAL security layer of jingle
 NS_JINGLE_RAW_UDP = 'urn:xmpp:jingle:transports:raw-udp:1'            # 
XEP-0177
 NS_JINGLE_ICE_UDP = 'urn:xmpp:jingle:transports:ice-udp:1'            # 
XEP-0176
@@ -104,6 +107,8 @@
 NS_LAST           = 'jabber:iq:last'
 NS_LOCATION       = 'http://jabber.org/protocol/geoloc'               # 
XEP-0080
 NS_MAM            = 'urn:xmpp:mam:0'                                  # 
XEP-0313
+NS_MAM_1          = 'urn:xmpp:mam:1'                                  # 
XEP-0313
+NS_MAM_2          = 'urn:xmpp:mam:2'                                  # 
XEP-0313
 NS_MESSAGE        = 'message'                                         # 
Jabberd2
 NS_MOOD           = 'http://jabber.org/protocol/mood'                 # 
XEP-0107
 NS_MUC            = 'http://jabber.org/protocol/muc'
@@ -140,6 +145,7 @@
 NS_SESSION        = 'urn:ietf:params:xml:ns:xmpp-session'
 NS_SI             = 'http://jabber.org/protocol/si'                   # 
XEP-0096
 NS_SI_PUB         = 'http://jabber.org/protocol/sipub'                # 
XEP-0137
+NS_SID            = 'urn:xmpp:sid:0'                                  # 
XEP-0359
 NS_SIGNED         = 'jabber:x:signed'                                 # 
XEP-0027
 NS_SIMS           = 'urn:xmpp:sims:1'                                 # 
XEP-0385
 NS_SSN            = 'urn:xmpp:ssn'                                    # 
XEP-0155
@@ -169,12 +175,17 @@
 NS_PUBKEY_PUBKEY  = 'urn:xmpp:pubkey:2'                                        
      # XEP-0189
 NS_PUBKEY_REVOKE  = 'urn:xmpp:revoke:2'
 NS_PUBKEY_ATTEST  = 'urn:xmpp:attest:2'
-NS_STREAM_MGMT    = 'urn:xmpp:sm:2'                                   # XEP-198
+NS_STREAM_MGMT    = 'urn:xmpp:sm:3'                                   # XEP-198
 NS_HASHES         = 'urn:xmpp:hashes:1'                               # XEP-300
-NS_HASHES_MD5     = 'urn:xmpp:hash-function-textual-names:md5'
-NS_HASHES_SHA1    = 'urn:xmpp:hash-function-textual-names:sha-1'
-NS_HASHES_SHA256  = 'urn:xmpp:hash-function-textual-names:sha-256'
-NS_HASHES_SHA512  = 'urn:xmpp:hash-function-textual-names:sha-512'
+NS_HASHES_2       = 'urn:xmpp:hashes:2'                               # XEP-300
+NS_HASHES_MD5     = 'urn:xmpp:hash-function-text-names:md5'
+NS_HASHES_SHA1    = 'urn:xmpp:hash-function-text-names:sha-1'
+NS_HASHES_SHA256  = 'urn:xmpp:hash-function-text-names:sha-256'
+NS_HASHES_SHA512  = 'urn:xmpp:hash-function-text-names:sha-512'
+NS_HASHES_SHA3_256 = 'urn:xmpp:hash-function-text-names:sha3-256'
+NS_HASHES_SHA3_512 = 'urn:xmpp:hash-function-text-names:sha3-512'
+NS_HASHES_BLAKE2B_256 = 'urn:xmpp:hash-function-text-names:id-blake2b256'
+NS_HASHES_BLAKE2B_512 = 'urn:xmpp:hash-function-text-names:id-blake2b512'
 
 #xmpp_stream_error_conditions = '''
 #bad-format --  --  -- The entity has sent XML that cannot be processed.
@@ -825,6 +836,15 @@
             return self.timestamp
         return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
 
+    def getJid(self):
+        """
+        Return the value of the 'jid' attribute
+        """
+        attr = self.getAttr('jid')
+        if attr:
+            return JID(attr)
+        return attr
+
     def getID(self):
         """
         Return the value of the 'id' attribute
@@ -937,6 +957,19 @@
                 props.append(prop)
         return props
 
+    def getTag(self, name, attrs=None, namespace=None, protocol=False):
+        """
+        Return the Node instance for the tag.
+        If protocol is True convert to a new Protocol/Message instance.
+        """
+        tag = Node.getTag(self, name, attrs, namespace)
+        if protocol and tag:
+            if name == 'message':
+                return Message(node=tag)
+            else:
+                return Protocol(node=tag)
+        return tag
+
     def __setitem__(self, item, val):
         """
         Set the item 'item' to the value 'val'
@@ -1004,6 +1037,12 @@
         """
         return self.getTagData('thread')
 
+    def getOriginID(self):
+        """
+        Return origin-id of the message
+        """
+        return self.getTagAttr('origin-id', namespace=NS_SID, attr='id')
+
     def setBody(self, val):
         """
         Set the text of the message"""
@@ -1041,6 +1080,12 @@
         """
         self.setTagData('thread', val)
 
+    def setOriginID(self, val):
+        """
+        Sets the origin-id of the message
+        """
+        self.setTag('origin-id', namespace=NS_SID, attrs={'id': val})
+
     def buildReply(self, text=None):
         """
         Builds and returns another message object with specified text. The to,
@@ -1345,6 +1390,62 @@
                 hash_ = hl.hexdigest()
         return hash_
 
+class Hashes2(Node):
+    """
+    Hash elements for various XEPs as defined in XEP-300
+    """
+
+    """
+    RECOMENDED HASH USE:
+    Algorithm     Support
+    MD2           MUST NOT
+    MD4           MUST NOT
+    MD5           MUST NOT
+    SHA-1         SHOULD NOT
+    SHA-256       MUST
+    SHA-512       SHOULD
+    SHA3-256      MUST
+    SHA3-512      SHOULD
+    BLAKE2b256    MUST
+    BLAKE2b512    SHOULD
+    """
+
+    supported = ('sha-256', 'sha-512', 'sha3-256', 'sha3-512', 'blake2b-256', 
'blake2b-512')
+
+    def __init__(self, nsp=NS_HASHES):
+        Node.__init__(self, None, {}, [], None, None, False, None)
+        self.setNamespace(nsp)
+        self.setName('hash')
+
+    def calculateHash(self, algo, file_string):
+        """
+        Calculate the hash and add it. It is preferable doing it here
+        instead of doing it all over the place in Gajim.
+        """
+        hl = None
+        hash_ = None
+        if algo == 'sha-256':
+            hl = hashlib.sha256()
+        elif algo == 'sha-512':
+            hl = hashlib.sha512()
+        elif algo == 'sha3-256':
+            hl = hashlib.sha3_256()
+        elif algo == 'sha3-512':
+            hl = hashlib.sha3_512()
+        elif algo == 'blake2b-256':
+            hl = hashlib.blake2b(digest_size=32)
+        elif algo == 'blake2b-512':
+            hl = hashlib.blake2b(digest_size=64)
+        # file_string can be a string or a file
+        if hl is not None:
+            if isinstance(file_string, bytes):
+                hl.update(file_string)
+            else: # if it is a file
+                for line in file_string:
+                    hl.update(line)
+            hash_ = b64encode(hl.digest()).decode('ascii')
+        return hash_
+
     def addHash(self, hash_, algo):
         self.setAttr('algo', algo)
         self.setData(hash_)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nbxmpp-0.5.5/nbxmpp/simplexml.py 
new/nbxmpp-0.6.0/nbxmpp/simplexml.py
--- old/nbxmpp-0.5.5/nbxmpp/simplexml.py        2017-01-04 14:11:04.000000000 
+0100
+++ new/nbxmpp-0.6.0/nbxmpp/simplexml.py        2017-08-05 21:17:49.000000000 
+0200
@@ -331,13 +331,13 @@
         """
         return self.getTags(name, attrs, namespace, one=1)
 
-    def getTagAttr(self, tag, attr):
+    def getTagAttr(self, tag, attr, namespace=None):
         """
         Return attribute value of the child with specified name (or None if no
         such attribute)
         """
         try:
-            return self.getTag(tag).attrs[attr]
+            return self.getTag(tag, namespace=namespace).attrs[attr]
         except:
             return None
 
@@ -445,15 +445,15 @@
         else:
             return self.addChild(name, attrs, namespace=namespace)
 
-    def setTagAttr(self, tag, attr, val):
+    def setTagAttr(self, tag, attr, val, namespace=None):
         """
         Create new node (if not already present) with name "tag" and set it's
         attribute "attr" to value "val"
         """
         try:
-            self.getTag(tag).attrs[attr] = val
+            self.getTag(tag, namespace=namespace).attrs[attr] = val
         except Exception:
-            self.addChild(tag, attrs={attr: val})
+            self.addChild(tag, namespace=namespace, attrs={attr: val})
 
     def setTagData(self, tag, val, attrs=None):
         """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nbxmpp-0.5.5/nbxmpp/smacks.py 
new/nbxmpp-0.6.0/nbxmpp/smacks.py
--- old/nbxmpp-0.5.5/nbxmpp/smacks.py   2017-01-01 23:13:23.000000000 +0100
+++ new/nbxmpp-0.6.0/nbxmpp/smacks.py   2017-06-04 14:17:22.000000000 +0200
@@ -1,5 +1,6 @@
 from .protocol import Acks
 from .protocol import NS_STREAM_MGMT
+from .transports_nb import CONNECTED, CONNECTING, DISCONNECTED, DISCONNECTING
 import logging
 log = logging.getLogger('nbxmpp.smacks')
 
@@ -22,7 +23,8 @@
         self.session_id = None
         self.resumption = False # If server supports resume
         # Max number of stanzas in queue before making a request
-        self.max_queue = 5
+        #be more agressive here (every message must be acked), this creates 
fewer message duplicates on failed resume)
+        self.max_queue = 0
         self._owner = None
         self.resuming = False
         self.enabled = False # If SM is enabled
@@ -47,6 +49,7 @@
 
     def _neg_response(self, disp, stanza):
         r = stanza.getAttr('resume')
+        log.info("Session resumption: %s" % r)
         if r == 'true' or r == 'True' or r == '1':
             self.resumption = True
             self.session_id = stanza.getAttr('id')
@@ -62,8 +65,8 @@
     def negociate(self, resume=True):
         # Every time we attempt to negociate, we must erase all previous info
         # about any previous session
+        log.debug("Clearing smacks uqueue")
         self.uqueue = []
-        self.old_uqueue = []
         self.in_h = 0
         self.out_h = 0
         self.session_id = None
@@ -73,12 +76,26 @@
         stanza.buildEnable(resume)
         self._owner.Connection.send(stanza, now=True)
 
+    def resend_queue(self):
+        """
+        Resends unsent stanzas when a new session is established.
+        This way there won't be any lost outgoing messages even on failed 
smacks resumes (but message duplicates are possible).
+        If your server supports revision 1.5 of smacks then even message 
duplicates are eliminated here :)
+        """
+        if self.old_uqueue:
+            log.info('Session resumption failed, replaying %s stanzas 
anyways...' % len(self.old_uqueue))
+            for i in self.old_uqueue:
+                self._owner.Dispatcher.send(i, False)   #use this send so that 
our stanzas actually increment out_h
+            self.old_uqueue = []
+        
     def resume_request(self):
         if not self.session_id:
             self.resuming = False
             log.error('Attempted to resume without a valid session id ')
             return
-        self.old_uqueue = self.uqueue    #save old messages in an extra 
"queue" to avoid race conditions
+        #save old messages in an extra "queue" to avoid race conditions and to 
make it possible to replay stanzas even when resuming fails
+        #add messages here (instead of overwriting) so that repeated 
connection errors don't delete unacked stanzas (uqueue should be empty in this 
case anyways)
+        self.old_uqueue += self.uqueue
         self.uqueue = []
         resume = Acks()
         resume.buildResume(self.in_h, self.session_id)
@@ -88,6 +105,14 @@
         ack = Acks()
         ack.buildAnswer(self.in_h)
         self._owner.Connection.send(ack, False)
+    
+    def send_closing_ack(self):
+        if self._owner.Connection.get_state() != DISCONNECTING:
+            log.error("Not allowed to send closing smacks ack when not 
disconnecting!")
+            return
+        ack = Acks()
+        ack.buildAnswer(self.in_h)
+        self._owner.Connection.send(ack, True)
 
     def request_ack(self):
         r = Acks()
@@ -108,13 +133,13 @@
         diff = self.out_h - h
 
         if diff < 0:
-            log.error('Server and client number of stanzas handled mismatch 
(our h: %d, server h: %d)' % (self.out_h, h))
+            log.error('Server and client number of stanzas handled mismatch 
(our h: %d, server h: %d, #queue: %d)' % (self.out_h, h, len(self.uqueue)))
             while (len(self.uqueue)):        #don't accumulate all messages in 
this case (they would otherwise all be resent on the next reconnect)
                 self.uqueue.pop(0)
         elif len(self.uqueue) < diff:
-            log.error('Server and client number of stanzas handled mismatch 
(our h: %d, server h: %d)' % (self.out_h, h))
+            log.error('Server and client number of stanzas handled mismatch 
(our h: %d, server h: %d, #queue: %d)' % (self.out_h, h, len(self.uqueue)))
         else:
-            log.debug('Got ack for outgoing stanzas (our h: %d, server h: %d), 
removing %d messages from queue...' % (self.out_h, h, len(self.uqueue) - diff))
+            log.debug('Got ack for outgoing stanzas (our h: %d, server h: %d, 
#queue: %d), removing %d messages from queue...' % (self.out_h, h, 
len(self.uqueue), len(self.uqueue) - diff))
             while (len(self.uqueue) > diff):
                 self.uqueue.pop(0)
                     
@@ -124,6 +149,7 @@
         number of stanzas received by the server. Resends stanzas not received
         by the server in the last session.
         """
+        log.info("Session resumption succeeded")
         h = stanza.getAttr('h')
         if not h:
             log.error('Server did not send h attribute')
@@ -132,12 +158,12 @@
         diff = self.out_h - h
 
         if diff < 0:
-            log.error('Server and client number of stanzas handled mismatch on 
session resumption (our h: %d, server h: %d)' % (self.out_h, h))
+            log.error('Server and client number of stanzas handled mismatch on 
session resumption (our h: %d, server h: %d. #queue: %d)' % (self.out_h, h, 
len(self.old_uqueue)))
             self.old_uqueue = []        #that's weird, but we don't resend 
this stanzas if the server says we don't need to
         elif len(self.old_uqueue) < diff:
-            log.error('Server and client number of stanzas handled mismatch on 
session resumption (our h: %d, server h: %d)' % (self.out_h, h))
+            log.error('Server and client number of stanzas handled mismatch on 
session resumption (our h: %d, server h: %d, #queue: %d)' % (self.out_h, h, 
len(self.old_uqueue)))
         else:
-            log.info('Removing %d already received stanzas from old outgoing 
queue (our h: %d, server h: %d, remaining in queue: %d)' % 
(len(self.old_uqueue) - diff, self.out_h, h, diff))
+            log.info('Removing %d already acked stanzas from old outgoing 
queue (our h: %d, server h: %d, #queue: %d, remaining in queue: %d)' % 
(len(self.old_uqueue) - diff, self.out_h, h, len(self.old_uqueue), diff))
             while (len(self.old_uqueue) > diff):
                 self.old_uqueue.pop(0)
 
@@ -160,14 +186,33 @@
             self._owner.NonBlockingBind.resuming = False
             self._owner._on_auth_bind(None)
             self.failed_resume = True
+            
+            h = stanza.getAttr('h')
+            log.info('Session resumption failed (item-not-found), server h: 
%s' % str(h))
+            if not h:
+                return
+            #prepare old_queue to contain only unacked stanzas for later 
resend (which is happening after our session is established properly)
+            h = int(h)
+            diff = self.out_h - h
+
+            if diff < 0:
+                log.error('Server and client number of stanzas handled 
mismatch on session resumption (our h: %d, server h: %d, #queue: %d)' % 
(self.out_h, h, len(self.old_uqueue)))
+                self.old_uqueue = []        #that's weird, but we don't resend 
this stanzas if the server says we don't need to
+            elif len(self.old_uqueue) < diff:
+                log.error('Server and client number of stanzas handled 
mismatch on session resumption (our h: %d, server h: %d, #queue: %d)' % 
(self.out_h, h, len(self.old_uqueue)))
+            else:
+                log.info('Removing %d already acked stanzas from old outgoing 
queue (our h: %d, server h: %d, #queue: %d, remaining in queue: %d)' % 
(len(self.old_uqueue) - diff, self.out_h, h, len(self.old_uqueue), diff))
+                while (len(self.old_uqueue) > diff):
+                    self.old_uqueue.pop(0)
             return
 
         # Doesn't support resumption
         if stanza.getTag('feature-not-implemented'):
+            log.info('Session resumption failed (feature-not-implemented)')
             self.negociate(False)
             return
 
         if stanza.getTag('unexpected-request'):
-            self.enabled = False
             log.error('Gajim failed to negociate Stream Management')
+            self.enabled = False
             return
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nbxmpp-0.5.5/nbxmpp/transports_nb.py 
new/nbxmpp-0.6.0/nbxmpp/transports_nb.py
--- old/nbxmpp-0.5.5/nbxmpp/transports_nb.py    2017-01-01 23:13:23.000000000 
+0100
+++ new/nbxmpp-0.6.0/nbxmpp/transports_nb.py    2017-06-04 14:17:22.000000000 
+0200
@@ -304,6 +304,8 @@
     # FIXME: where and why does this need to be called
     def start_disconnect(self):
         self.set_state(DISCONNECTING)
+        if self._owner._caller.sm and self._owner._caller.sm.enabled:
+            self._owner._caller.sm.send_closing_ack()
 
 
 class NonBlockingTCP(NonBlockingTransport, IdleObject):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nbxmpp-0.5.5/setup.py new/nbxmpp-0.6.0/setup.py
--- old/nbxmpp-0.5.5/setup.py   2017-01-30 22:40:36.000000000 +0100
+++ new/nbxmpp-0.6.0/setup.py   2017-09-25 22:18:45.000000000 +0200
@@ -3,7 +3,7 @@
 from distutils.core import setup
 
 setup(name='nbxmpp',
-      version='0.5.5',
+      version='0.6.0',
       description='Non blocking Jabber/XMPP module',
       author='Yann Leboulanger',
       author_email='[email protected]',


Reply via email to