From f6b3a0c6cffa5ebf10d20c20b5cadd575c91fe81 Mon Sep 17 00:00:00 2001 From: mathieui Date: Thu, 12 Feb 2015 12:17:01 +0100 Subject: Fix the uses of stanza.reply() This is relying on the stanzas being copied for each handler. We no longer do that for performance reasons, so instead of editing the copy in-place, stanza.reply() now returns a new stanza. --- slixmpp/stanza/iq.py | 14 +++++++------- slixmpp/stanza/message.py | 16 +++++++--------- slixmpp/stanza/presence.py | 7 ++++--- slixmpp/stanza/rootstanza.py | 40 ++++++++++++++++++++-------------------- 4 files changed, 38 insertions(+), 39 deletions(-) (limited to 'slixmpp/stanza') diff --git a/slixmpp/stanza/iq.py b/slixmpp/stanza/iq.py index e2b3c1f9..c9f29f17 100644 --- a/slixmpp/stanza/iq.py +++ b/slixmpp/stanza/iq.py @@ -88,10 +88,10 @@ class Iq(RootStanza): Overrides StanzaBase.unhandled. """ if self['type'] in ('get', 'set'): - self.reply() - self['error']['condition'] = 'feature-not-implemented' - self['error']['text'] = 'No handlers registered for this request.' - self.send() + reply = self.reply() + reply['error']['condition'] = 'feature-not-implemented' + reply['error']['text'] = 'No handlers registered for this request.' + reply.send() def set_payload(self, value): """ @@ -154,9 +154,9 @@ class Iq(RootStanza): clear -- Indicates if existing content should be removed before replying. Defaults to True. """ - self['type'] = 'result' - StanzaBase.reply(self, clear) - return self + new_iq = StanzaBase.reply(self, clear=clear) + new_iq['type'] = 'result' + return new_iq def send(self, callback=None, timeout=None, timeout_callback=None): """Send an stanza over the XML stream. diff --git a/slixmpp/stanza/message.py b/slixmpp/stanza/message.py index 09e44ad8..7f9e90f5 100644 --- a/slixmpp/stanza/message.py +++ b/slixmpp/stanza/message.py @@ -133,21 +133,19 @@ class Message(RootStanza): clear -- Indicates if existing content should be removed before replying. Defaults to True. """ - thread = self['thread'] - parent = self['parent_thread'] + new_message = StanzaBase.reply(self, clear) - StanzaBase.reply(self, clear) if self['type'] == 'groupchat': - self['to'] = self['to'].bare + new_message['to'] = new_message['to'].bare - self['thread'] = thread - self['parent_thread'] = parent + new_message['thread'] = self['thread'] + new_message['parent_thread'] = self['parent_thread'] - del self['id'] + del new_message['id'] if body is not None: - self['body'] = body - return self + new_message['body'] = body + return new_message def get_mucroom(self): """ diff --git a/slixmpp/stanza/presence.py b/slixmpp/stanza/presence.py index 2c77a878..e1b8c0bc 100644 --- a/slixmpp/stanza/presence.py +++ b/slixmpp/stanza/presence.py @@ -174,8 +174,9 @@ class Presence(RootStanza): clear -- Indicates if the stanza contents should be removed before replying. Defaults to True. """ + new_presence = StanzaBase.reply(self, clear) if self['type'] == 'unsubscribe': - self['type'] = 'unsubscribed' + new_presence['type'] = 'unsubscribed' elif self['type'] == 'subscribe': - self['type'] = 'subscribed' - return StanzaBase.reply(self, clear) + new_presence['type'] = 'subscribed' + return new_presence diff --git a/slixmpp/stanza/rootstanza.py b/slixmpp/stanza/rootstanza.py index 7bd0c32d..ff139382 100644 --- a/slixmpp/stanza/rootstanza.py +++ b/slixmpp/stanza/rootstanza.py @@ -46,37 +46,37 @@ class RootStanza(StanzaBase): # locally. Using the condition/text from that error # response could leak too much information, so we'll # only use a generic error here. - self.reply() - self['error']['condition'] = 'undefined-condition' - self['error']['text'] = 'External error' - self['error']['type'] = 'cancel' + reply = self.reply() + reply['error']['condition'] = 'undefined-condition' + reply['error']['text'] = 'External error' + reply['error']['type'] = 'cancel' log.warning('You should catch IqError exceptions') - self.send() + reply.send() elif isinstance(e, IqTimeout): - self.reply() - self['error']['condition'] = 'remote-server-timeout' - self['error']['type'] = 'wait' + reply = self.reply() + reply['error']['condition'] = 'remote-server-timeout' + reply['error']['type'] = 'wait' log.warning('You should catch IqTimeout exceptions') - self.send() + reply.send() elif isinstance(e, XMPPError): # We raised this deliberately - self.reply(clear=e.clear) - self['error']['condition'] = e.condition - self['error']['text'] = e.text - self['error']['type'] = e.etype + reply = self.reply(clear=e.clear) + reply['error']['condition'] = e.condition + reply['error']['text'] = e.text + reply['error']['type'] = e.etype if e.extension is not None: # Extended error tag extxml = ET.Element("{%s}%s" % (e.extension_ns, e.extension), e.extension_args) - self['error'].append(extxml) - self.send() + reply['error'].append(extxml) + reply.send() else: # We probably didn't raise this on purpose, so send an error stanza - self.reply() - self['error']['condition'] = 'undefined-condition' - self['error']['text'] = "Slixmpp got into trouble." - self['error']['type'] = 'cancel' - self.send() + reply = self.reply() + reply['error']['condition'] = 'undefined-condition' + reply['error']['text'] = "Slixmpp got into trouble." + reply['error']['type'] = 'cancel' + reply.send() # log the error log.exception('Error handling {%s}%s stanza', self.namespace, self.name) -- cgit v1.2.3