summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sleekxmpp/basexmpp.py6
-rw-r--r--sleekxmpp/clientxmpp.py1
-rw-r--r--sleekxmpp/features/feature_bind/bind.py3
-rw-r--r--sleekxmpp/jid.py60
-rw-r--r--sleekxmpp/plugins/xep_0078/legacyauth.py16
5 files changed, 54 insertions, 32 deletions
diff --git a/sleekxmpp/basexmpp.py b/sleekxmpp/basexmpp.py
index f26c048f..4df7f11a 100644
--- a/sleekxmpp/basexmpp.py
+++ b/sleekxmpp/basexmpp.py
@@ -69,12 +69,12 @@ class BaseXMPP(XMLStream):
self.stream_id = None
#: The JabberID (JID) requested for this connection.
- self.requested_jid = JID(jid)
+ self.requested_jid = JID(jid, cache_lock=True)
#: The JabberID (JID) used by this connection,
#: as set after session binding. This may even be a
#: different bare JID than what was requested.
- self.boundjid = JID(jid)
+ self.boundjid = JID(jid, cache_lock=True)
self._expected_server_name = self.boundjid.host
self._redirect_attempts = 0
@@ -665,7 +665,7 @@ class BaseXMPP(XMLStream):
def set_jid(self, jid):
"""Rip a JID apart and claim it as our own."""
log.debug("setting jid to %s", jid)
- self.boundjid.full = jid
+ self.boundjid = JID(jid, cache_lock=True)
def getjidresource(self, fulljid):
if '/' in fulljid:
diff --git a/sleekxmpp/clientxmpp.py b/sleekxmpp/clientxmpp.py
index ec64664c..3fa158af 100644
--- a/sleekxmpp/clientxmpp.py
+++ b/sleekxmpp/clientxmpp.py
@@ -64,7 +64,6 @@ class ClientXMPP(BaseXMPP):
escape_quotes=True, sasl_mech=None, lang='en'):
BaseXMPP.__init__(self, jid, 'jabber:client')
- self.set_jid(jid)
self.escape_quotes = escape_quotes
self.plugin_config = plugin_config
self.plugin_whitelist = plugin_whitelist
diff --git a/sleekxmpp/features/feature_bind/bind.py b/sleekxmpp/features/feature_bind/bind.py
index 0584b308..0f97952d 100644
--- a/sleekxmpp/features/feature_bind/bind.py
+++ b/sleekxmpp/features/feature_bind/bind.py
@@ -8,6 +8,7 @@
import logging
+from sleekxmpp.jid import JID
from sleekxmpp.stanza import Iq, StreamFeatures
from sleekxmpp.features.feature_bind import stanza
from sleekxmpp.xmlstream import register_stanza_plugin
@@ -48,7 +49,7 @@ class FeatureBind(BasePlugin):
iq['bind']['resource'] = self.xmpp.boundjid.resource
response = iq.send(now=True)
- self.xmpp.set_jid(response['bind']['jid'])
+ self.xmpp.boundjid = JID(response['bind']['jid'], cache_lock=True)
self.xmpp.bound = True
self.xmpp.event('session_bind', self.xmpp.boundjid, direct=True)
self.xmpp.session_bind_event.set()
diff --git a/sleekxmpp/jid.py b/sleekxmpp/jid.py
index eac51dad..feab4082 100644
--- a/sleekxmpp/jid.py
+++ b/sleekxmpp/jid.py
@@ -16,6 +16,7 @@ from __future__ import unicode_literals
import re
import socket
import stringprep
+import threading
import encodings.idna
from sleekxmpp.util import stringprep_profiles
@@ -65,6 +66,7 @@ JID_UNESCAPE_TRANSFORMATIONS = {'\\20': ' ',
'\\5c': '\\'}
JID_CACHE = OrderedDict()
+JID_CACHE_LOCK = threading.Lock()
JID_CACHE_MAX_SIZE = 1024
@@ -416,37 +418,49 @@ class JID(object):
# pylint: disable=W0212
def __init__(self, jid=None, **kwargs):
- self._jid = (None, None, None)
+ jid_data = (jid, kwargs.get('local', None),
+ kwargs.get('domain', None),
+ kwargs.get('resource', None))
- if jid is None or jid == '':
- jid = ''
+ locked = kwargs.get('cache_lock', False)
- if not jid:
- jid = (None, None, None)
- elif jid in JID_CACHE:
- jid = JID_CACHE[jid]
- elif not isinstance(jid, JID):
- jid = _parse_jid(jid)
+ if jid_data in JID_CACHE:
+ parsed_jid, locked = JID_CACHE[jid_data]
+ self._jid = parsed_jid
else:
- jid = jid._jid
+ if jid is None:
+ jid = ''
- local, domain, resource = jid
+ if not jid:
+ parsed_jid = (None, None, None)
+ elif not isinstance(jid, JID):
+ parsed_jid = _parse_jid(jid)
+ else:
+ parsed_jid = jid._jid
- local = kwargs.get('local', local)
- domain = kwargs.get('domain', domain)
- resource = kwargs.get('resource', resource)
+ local, domain, resource = parsed_jid
- if 'local' in kwargs:
- local = _escape_node(local)
- if 'domain' in kwargs:
- domain = _validate_domain(domain)
- if 'resource' in kwargs:
- resource = _validate_resource(resource)
+ local = kwargs.get('local', local)
+ domain = kwargs.get('domain', domain)
+ resource = kwargs.get('resource', resource)
- self._jid = (local, domain, resource)
- JID_CACHE[_format_jid(*self._jid)] = self._jid
+ if 'local' in kwargs:
+ local = _escape_node(local)
+ if 'domain' in kwargs:
+ domain = _validate_domain(domain)
+ if 'resource' in kwargs:
+ resource = _validate_resource(resource)
+
+ self._jid = (local, domain, resource)
+
+ JID_CACHE[jid_data] = (self._jid, locked)
if len(JID_CACHE) > JID_CACHE_MAX_SIZE:
- JID_CACHE.popitem(False)
+ with JID_CACHE_LOCK:
+ key, item = JID_CACHE.popitem(False)
+ if item[1]:
+ # Need to reinsert locked JIDs
+ JID_CACHE[key] = item
+
def unescape(self):
"""Return an unescaped JID object.
diff --git a/sleekxmpp/plugins/xep_0078/legacyauth.py b/sleekxmpp/plugins/xep_0078/legacyauth.py
index be9fe3c5..7e2d7bdf 100644
--- a/sleekxmpp/plugins/xep_0078/legacyauth.py
+++ b/sleekxmpp/plugins/xep_0078/legacyauth.py
@@ -11,6 +11,7 @@ import hashlib
import random
import sys
+from sleekxmpp.jid import JID
from sleekxmpp.exceptions import IqError, IqTimeout
from sleekxmpp.stanza import Iq, StreamFeatures
from sleekxmpp.xmlstream import ElementBase, ET, register_stanza_plugin
@@ -95,10 +96,11 @@ class XEP_0078(BasePlugin):
iq['auth']['username'] = self.xmpp.requested_jid.user
# A resource is required, so create a random one if necessary
- if self.xmpp.requested_jid.resource:
- iq['auth']['resource'] = self.xmpp.requested_jid.resource
- else:
- iq['auth']['resource'] = '%s' % random.random()
+ resource = self.xmpp.requested_jid.resource
+ if not resource:
+ resource = uuid.uuid4()
+
+ iq['auth']['resource'] = resource
if 'digest' in resp['auth']['fields']:
log.debug('Authenticating via jabber:iq:auth Digest')
@@ -130,6 +132,12 @@ class XEP_0078(BasePlugin):
self.xmpp.features.add('auth')
self.xmpp.authenticated = True
+
+ self.xmpp.boundjid = JID(self.xmpp.requested_jid,
+ resource=resource,
+ cache_lock=True)
+ self.xmpp.event('session_bind', self.xmpp.boundjid, direct=True)
+
log.debug("Established Session")
self.xmpp.sessionstarted = True
self.xmpp.session_started_event.set()