summaryrefslogtreecommitdiff
path: root/sleekxmpp/xmlstream
diff options
context:
space:
mode:
Diffstat (limited to 'sleekxmpp/xmlstream')
-rw-r--r--sleekxmpp/xmlstream/cert.py2
-rw-r--r--sleekxmpp/xmlstream/stanzabase.py14
-rw-r--r--sleekxmpp/xmlstream/xmlstream.py55
3 files changed, 45 insertions, 26 deletions
diff --git a/sleekxmpp/xmlstream/cert.py b/sleekxmpp/xmlstream/cert.py
index 71146f36..d357b326 100644
--- a/sleekxmpp/xmlstream/cert.py
+++ b/sleekxmpp/xmlstream/cert.py
@@ -181,4 +181,4 @@ def verify(expected, raw_cert):
return True
raise CertificateError(
- 'Could not match certficate against hostname: %s' % expected)
+ 'Could not match certificate against hostname: %s' % expected)
diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py
index 97107098..c2e0f718 100644
--- a/sleekxmpp/xmlstream/stanzabase.py
+++ b/sleekxmpp/xmlstream/stanzabase.py
@@ -19,6 +19,7 @@ import logging
import weakref
from xml.etree import cElementTree as ET
+from sleekxmpp.util import safedict
from sleekxmpp.xmlstream import JID
from sleekxmpp.xmlstream.tostring import tostring
from sleekxmpp.thirdparty import OrderedDict
@@ -562,10 +563,13 @@ class ElementBase(object):
.. versionadded:: 1.0-Beta1
"""
- values = {}
+ values = OrderedDict()
values['lang'] = self['lang']
for interface in self.interfaces:
- values[interface] = self[interface]
+ if isinstance(self[interface], JID):
+ values[interface] = self[interface].jid
+ else:
+ values[interface] = self[interface]
if interface in self.lang_interfaces:
values['%s|*' % interface] = self['%s|*' % interface]
for plugin, stanza in self.plugins.items():
@@ -676,6 +680,8 @@ class ElementBase(object):
if lang and attrib in self.lang_interfaces:
kwargs['lang'] = lang
+ kwargs = safedict(kwargs)
+
if attrib == 'substanzas':
return self.iterables
elif attrib in self.interfaces or attrib == 'lang':
@@ -752,6 +758,8 @@ class ElementBase(object):
if lang and attrib in self.lang_interfaces:
kwargs['lang'] = lang
+ kwargs = safedict(kwargs)
+
if attrib in self.interfaces or attrib == 'lang':
if value is not None:
set_method = "set_%s" % attrib.lower()
@@ -838,6 +846,8 @@ class ElementBase(object):
if lang and attrib in self.lang_interfaces:
kwargs['lang'] = lang
+ kwargs = safedict(kwargs)
+
if attrib in self.interfaces or attrib == 'lang':
del_method = "del_%s" % attrib.lower()
del_method2 = "del%s" % attrib.title()
diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py
index 66985f3d..62d46100 100644
--- a/sleekxmpp/xmlstream/xmlstream.py
+++ b/sleekxmpp/xmlstream/xmlstream.py
@@ -114,7 +114,8 @@ class XMLStream(object):
:param int port: The port to use for the connection. Defaults to 0.
"""
- def __init__(self, socket=None, host='', port=0):
+ def __init__(self, socket=None, host='', port=0, certfile=None,
+ keyfile=None, ca_certs=None, **kwargs):
#: Most XMPP servers support TLSv1, but OpenFire in particular
#: does not work well with it. For OpenFire, set
#: :attr:`ssl_version` to use ``SSLv23``::
@@ -136,16 +137,16 @@ class XMLStream(object):
#:
#: On Mac OS X, certificates in the system keyring will
#: be consulted, even if they are not in the provided file.
- self.ca_certs = None
+ self.ca_certs = ca_certs
#: Path to a file containing a client certificate to use for
#: authenticating via SASL EXTERNAL. If set, there must also
#: be a corresponding `:attr:keyfile` value.
- self.certfile = None
+ self.certfile = certfile
#: Path to a file containing the private key for the selected
#: client certificate to use for authenticating via SASL EXTERNAL.
- self.keyfile = None
+ self.keyfile = keyfile
self._der_cert = None
@@ -291,7 +292,7 @@ class XMLStream(object):
self.event_queue = Queue()
#: A queue of string data to be sent over the stream.
- self.send_queue = Queue()
+ self.send_queue = Queue(maxsize=256)
self.send_queue_lock = threading.Lock()
self.send_lock = threading.RLock()
@@ -460,9 +461,11 @@ class XMLStream(object):
def _connect(self, reattempt=True):
self.scheduler.remove('Session timeout check')
- if self.reconnect_delay is None or not reattempt:
+ if self.reconnect_delay is None:
delay = 1.0
- else:
+ self.reconnect_delay = delay
+
+ if reattempt:
delay = min(self.reconnect_delay * 2, self.reconnect_max_delay)
delay = random.normalvariate(delay, delay * 0.1)
log.debug('Waiting %s seconds before connecting.', delay)
@@ -523,7 +526,8 @@ class XMLStream(object):
'keyfile': self.keyfile,
'ca_certs': self.ca_certs,
'cert_reqs': cert_policy,
- 'do_handshake_on_connect': False
+ 'do_handshake_on_connect': False,
+ "ssl_version": self.ssl_version
})
if sys.version_info >= (2, 7):
@@ -847,13 +851,14 @@ class XMLStream(object):
'keyfile': self.keyfile,
'ca_certs': self.ca_certs,
'cert_reqs': cert_policy,
- 'do_handshake_on_connect': False
+ 'do_handshake_on_connect': False,
+ "ssl_version": self.ssl_version
})
if sys.version_info >= (2, 7):
ssl_args['ciphers'] = self.ciphers
- ssl_socket = ssl.wrap_socket(self.socket, **ssl_args);
+ ssl_socket = ssl.wrap_socket(self.socket, **ssl_args)
if hasattr(self.socket, 'socket'):
# We are using a testing socket, so preserve the top
@@ -938,12 +943,13 @@ class XMLStream(object):
self.whitespace_keepalive_interval = 300
"""
- self.schedule('Whitespace Keepalive',
- self.whitespace_keepalive_interval,
- self.send_raw,
- args=(' ',),
- kwargs={'now': True},
- repeat=True)
+ if self.whitespace_keepalive:
+ self.schedule('Whitespace Keepalive',
+ self.whitespace_keepalive_interval,
+ self.send_raw,
+ args=(' ',),
+ kwargs={'now': True},
+ repeat=True)
def _remove_schedules(self, event):
"""Remove whitespace keepalive and certificate expiration schedules."""
@@ -1148,7 +1154,7 @@ class XMLStream(object):
"""
return len(self.__event_handlers.get(name, []))
- def event(self, name, data={}, direct=False):
+ def event(self, name, data=None, direct=False):
"""Manually trigger a custom event.
:param name: The name of the event to trigger.
@@ -1159,6 +1165,9 @@ class XMLStream(object):
event queue. All event handlers will run in the
same thread.
"""
+ if not data:
+ data = {}
+
log.debug("Event triggered: " + name)
handlers = self.__event_handlers.get(name, [])
@@ -1318,9 +1327,6 @@ class XMLStream(object):
try:
sent += self.socket.send(data[sent:])
count += 1
- except Socket.error as serr:
- if serr.errno != errno.EINTR:
- raise
except ssl.SSLError as serr:
if tries >= self.ssl_retry_max:
log.debug('SSL error: max retries reached')
@@ -1335,6 +1341,9 @@ class XMLStream(object):
if not self.stop.is_set():
time.sleep(self.ssl_retry_delay)
tries += 1
+ except Socket.error as serr:
+ if serr.errno != errno.EINTR:
+ raise
if count > 1:
log.debug('SENT: %d chunks', count)
except (Socket.error, ssl.SSLError) as serr:
@@ -1744,9 +1753,6 @@ class XMLStream(object):
try:
sent += self.socket.send(enc_data[sent:])
count += 1
- except Socket.error as serr:
- if serr.errno != errno.EINTR:
- raise
except ssl.SSLError as serr:
if tries >= self.ssl_retry_max:
log.debug('SSL error: max retries reached')
@@ -1759,6 +1765,9 @@ class XMLStream(object):
if not self.stop.is_set():
time.sleep(self.ssl_retry_delay)
tries += 1
+ except Socket.error as serr:
+ if serr.errno != errno.EINTR:
+ raise
if count > 1:
log.debug('SENT: %d chunks', count)
self.send_queue.task_done()