def send(self, data, mask=None, timeout=RESPONSE_TIMEOUT, priority=5): """ A wrapper for send_raw for sending stanza objects. May optionally block until an expected response is received. Arguments: data -- The stanza object to send on the stream. mask -- Deprecated. An XML snippet matching the structure of the expected response. Execution will block in this thread until the response is received or a timeout occurs. timeout -- Time in seconds to wait for a response before continuing. Defaults to RESPONSE_TIMEOUT. """ if hasattr(mask, 'xml'): mask = mask.xml data = str(data) if mask is not None: from sleekxmpp.xmlstream.matcher import MatchXMLMask log.warning("Use of send mask waiters is deprecated.") wait_for = Waiter("SendWait_%s" % self.new_id(), MatchXMLMask(mask)) self.register_handler(wait_for) self.send_raw(data, priority) if mask is not None: return wait_for.wait(timeout)
def send(self, data, mask=None, timeout=None, now=False): """ A wrapper for send_raw for sending stanza objects. May optionally block until an expected response is received. Arguments: data -- The stanza object to send on the stream. mask -- Deprecated. An XML snippet matching the structure of the expected response. Execution will block in this thread until the response is received or a timeout occurs. timeout -- Time in seconds to wait for a response before continuing. Defaults to RESPONSE_TIMEOUT. now -- Indicates if the send queue should be skipped, sending the stanza immediately. Useful mainly for stream initialization stanzas. Defaults to False. """ if timeout is None: timeout = self.response_timeout if hasattr(mask, 'xml'): mask = mask.xml data = str(data) if mask is not None: log.warning("Use of send mask waiters is deprecated.") wait_for = Waiter("SendWait_%s" % self.new_id(), MatchXMLMask(mask)) self.register_handler(wait_for) self.send_raw(data, now) if mask is not None: return wait_for.wait(timeout)
def prerun(self, payload): """ Store the XML contents of the stanza to return to the waiting event handler. Overrides Waiter.prerun Arguments: payload -- The matched stanza object. """ Waiter.prerun(self, payload.xml)
def send(self, block=True, timeout=None, callback=None, now=False): """ Send an <iq> stanza over the XML stream. The send call can optionally block until a response is received or a timeout occurs. Be aware that using blocking in non-threaded event handlers can drastically impact performance. Otherwise, a callback handler can be provided that will be executed when the Iq stanza's result reply is received. Be aware though that that the callback handler will not be executed in its own thread. Using both block and callback is not recommended, and only the callback argument will be used in that case. Overrides StanzaBase.send Arguments: block -- Specify if the send call will block until a response is received, or a timeout occurs. Defaults to True. timeout -- The length of time (in seconds) to wait for a response before exiting the send call if blocking is used. Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT callback -- Optional reference to a stream handler function. Will be executed when a reply stanza is received. now -- Indicates if the send queue should be skipped and send the stanza immediately. Used during stream initialization. Defaults to False. """ if timeout is None: timeout = self.stream.response_timeout if callback is not None and self['type'] in ('get', 'set'): handler_name = 'IqCallback_%s' % self['id'] handler = Callback(handler_name, MatcherId(self['id']), callback, once=True) self.stream.register_handler(handler) StanzaBase.send(self, now=now) return handler_name elif block and self['type'] in ('get', 'set'): waitfor = Waiter('IqWait_%s' % self['id'], MatcherId(self['id'])) self.stream.register_handler(waitfor) StanzaBase.send(self, now=now) result = waitfor.wait(timeout) if not result: raise IqTimeout(self) if result['type'] == 'error': raise IqError(result) return result else: return StanzaBase.send(self, now=now)
def sendStreamPacket(self, data, block=False): try: log.debug("SSEND: %s" % data) #SSEND means stream send :) if not block: self.socket.sendall(data.encode('utf-8')) else: waitfor = Waiter('IqWait_%s' % data['id'], MatcherId(data['id'])) self.register_handler(waitfor) self.socket.sendall(tostring(data.xml).encode('utf-8')) return waitfor.wait() except Exception as ex: logging.warning("SEND FAILED: %s\n%s", ex, data) if self.auto_reconnect: self.reconnect() else: self.disconnect(self)
def send_wait(self, iq, timeout=None): """ :param iq: Stanza to send :param int timeout: The number of seconds to wait for the stanza to arrive. Defaults to the the stream's :class:`~sleekxmpp.xmlstream.xmlstream.XMLStream.response_timeout` value. """ iq_id = iq.get('id') self.send(iq) waiter = Waiter("SendWait_%s" % self.new_id(), MatcherId(iq_id)) self.register_handler(waiter) return waiter.wait(timeout)
def _handle_sm_feature(self, features): """ Enable or resume stream management. If no SM-ID is stored, and resource binding has taken place, stream management will be enabled. If an SM-ID is known, and the server allows resumption, the previous stream will be resumed. """ if 'stream_management' in self.xmpp.features: # We've already negotiated stream management, # so no need to do it again. return False if not self.sm_id: if 'bind' in self.xmpp.features: self.enabled.set() enable = stanza.Enable(self.xmpp) enable['resume'] = self.allow_resume enable.send(now=True) self.handled = 0 elif self.sm_id and self.allow_resume: self.enabled.set() resume = stanza.Resume(self.xmpp) resume['h'] = self.handled resume['previd'] = self.sm_id resume.send(now=True) # Wait for a response before allowing stream feature processing # to continue. The actual result processing will be done in the # _handle_resumed() or _handle_failed() methods. waiter = Waiter( 'resumed_or_failed', MatchMany([ MatchXPath(stanza.Resumed.tag_name()), MatchXPath(stanza.Failed.tag_name()) ])) self.xmpp.register_handler(waiter) result = waiter.wait() if result is not None and result.name == 'resumed': return True return False
def _handle_sm_feature(self, features): """ Enable or resume stream management. If no SM-ID is stored, and resource binding has taken place, stream management will be enabled. If an SM-ID is known, and the server allows resumption, the previous stream will be resumed. """ if 'stream_management' in self.xmpp.features: # We've already negotiated stream management, # so no need to do it again. return False if not self.sm_id: if 'bind' in self.xmpp.features: self.enabled.set() enable = stanza.Enable(self.xmpp) enable['resume'] = self.allow_resume enable.send(now=True) self.handled = 0 elif self.sm_id and self.allow_resume: self.enabled.set() resume = stanza.Resume(self.xmpp) resume['h'] = self.handled resume['previd'] = self.sm_id resume.send(now=True) # Wait for a response before allowing stream feature processing # to continue. The actual result processing will be done in the # _handle_resumed() or _handle_failed() methods. waiter = Waiter('resumed_or_failed', MatchMany([ MatchXPath(stanza.Resumed.tag_name()), MatchXPath(stanza.Failed.tag_name())])) self.xmpp.register_handler(waiter) result = waiter.wait() if result is not None and result.name == 'resumed': return True return False
def send(self, block=True, timeout=RESPONSE_TIMEOUT): """ Send an <iq> stanza over the XML stream. The send call can optionally block until a response is received or a timeout occurs. Be aware that using blocking in non-threaded event handlers can drastically impact performance. Overrides StanzaBase.send Arguments: block -- Specify if the send call will block until a response is received, or a timeout occurs. Defaults to True. timeout -- The length of time (in seconds) to wait for a response before exiting the send call if blocking is used. Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT """ if block and self['type'] in ('get', 'set'): waitfor = Waiter('IqWait_%s' % self['id'], MatcherId(self['id'])) self.stream.registerHandler(waitfor) StanzaBase.send(self) return waitfor.wait(timeout) else: return StanzaBase.send(self)
def send(self, block=True, timeout=RESPONSE_TIMEOUT, priority=5): """ Send an <iq> stanza over the XML stream. The send call can optionally block until a response is received or a timeout occurs. Be aware that using blocking in non-threaded event handlers can drastically impact performance. Overrides StanzaBase.send Arguments: block -- Specify if the send call will block until a response is received, or a timeout occurs. Defaults to True. timeout -- The length of time (in seconds) to wait for a response before exiting the send call if blocking is used. Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT """ if block and self['type'] in ('get', 'set'): waitfor = Waiter('IqWait_%s' % self['id'], MatcherId(self['id'])) self.stream.registerHandler(waitfor) StanzaBase.send(self, priority) return waitfor.wait(timeout) else: return StanzaBase.send(self, priority)
def send(self, block=True, timeout=None, callback=None, now=False, timeout_callback=None): """ Send an <iq> stanza over the XML stream. The send call can optionally block until a response is received or a timeout occurs. Be aware that using blocking in non-threaded event handlers can drastically impact performance. Otherwise, a callback handler can be provided that will be executed when the Iq stanza's result reply is received. Be aware though that that the callback handler will not be executed in its own thread. Using both block and callback is not recommended, and only the callback argument will be used in that case. Overrides StanzaBase.send Arguments: block -- Specify if the send call will block until a response is received, or a timeout occurs. Defaults to True. timeout -- The length of time (in seconds) to wait for a response before exiting the send call if blocking is used. Defaults to sleekxmpp.xmlstream.RESPONSE_TIMEOUT callback -- Optional reference to a stream handler function. Will be executed when a reply stanza is received. now -- Indicates if the send queue should be skipped and send the stanza immediately. Used during stream initialization. Defaults to False. timeout_callback -- Optional reference to a stream handler function. Will be executed when the timeout expires before a response has been received with the originally-sent IQ stanza. Only called if there is a callback parameter (and therefore are in async mode). """ if timeout is None: timeout = self.stream.response_timeout if self.stream.session_bind_event.is_set(): matcher = MatchIDSender({ 'id': self['id'], 'self': self.stream.boundjid, 'peer': self['to'] }) else: matcher = MatcherId(self['id']) if callback is not None and self['type'] in ('get', 'set'): handler_name = 'IqCallback_%s' % self['id'] if timeout_callback: self.callback = callback self.timeout_callback = timeout_callback self.stream.schedule('IqTimeout_%s' % self['id'], timeout, self._fire_timeout, repeat=False) handler = Callback(handler_name, matcher, self._handle_result, once=True) else: handler = Callback(handler_name, matcher, callback, once=True) self.stream.register_handler(handler) StanzaBase.send(self, now=now) return handler_name elif block and self['type'] in ('get', 'set'): waitfor = Waiter('IqWait_%s' % self['id'], matcher) self.stream.register_handler(waitfor) StanzaBase.send(self, now=now) result = waitfor.wait(timeout) if not result: raise IqTimeout(self) if result['type'] == 'error': raise IqError(result) return result else: return StanzaBase.send(self, now=now)