with self.lock:<EOL><INDENT>if self.stream:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>self._close_stream()<EOL><DEDENT>transport = TCPTransport(self.settings)<EOL>addr = self.settings["<STR_LIT>"]<EOL>if addr:<EOL><INDENT>service = None<EOL><DEDENT>else:<EOL><INDENT>addr = self.jid.domain<EOL>service = self.settings["<STR_LIT>"]<EOL><DEDENT>transport.connect(addr, self.settings["<STR_LIT>"], service)<EOL>handlers = self._base_handlers[:]<EOL>handlers += self.handlers + [self]<EOL>self.clear_response_handlers()<EOL>self.setup_stanza_handlers(handlers, "<STR_LIT>")<EOL>stream = ClientStream(self.jid, self, handlers, self.settings)<EOL>stream.initiate(transport)<EOL>self.main_loop.add_handler(transport)<EOL>self.main_loop.add_handler(stream)<EOL>self._ml_handlers += [transport, stream]<EOL>self.stream = stream<EOL>self.uplink = stream<EOL><DEDENT>


with self.lock:<EOL><INDENT>if self.stream:<EOL><INDENT>if self.settings[u"<STR_LIT>"]:<EOL><INDENT>self.send(Presence(stanza_type = "<STR_LIT>"))<EOL><DEDENT>self.stream.disconnect()<EOL><DEDENT><DEDENT>


with self.lock:<EOL><INDENT>self._close_stream()<EOL><DEDENT>


self.stream.close()<EOL>if self.stream.transport in self._ml_handlers:<EOL><INDENT>self._ml_handlers.remove(self.stream.transport)<EOL>self.main_loop.remove_handler(self.stream.transport)<EOL><DEDENT>self.stream = None<EOL>self.uplink = None<EOL>

Same as `close_stream` but with the `lock` acquired.


Call the main loop.

        Convenience wrapper for ``self.main_loop.loop``


with self.lock:<EOL><INDENT>if event.stream != self.stream:<EOL><INDENT>return<EOL><DEDENT>self.me = event.stream.me<EOL>self.peer = event.stream.peer<EOL>handlers = self._base_handlers[:]<EOL>handlers += self.handlers + [self]<EOL>self.setup_stanza_handlers(handlers, "<STR_LIT>")<EOL><DEDENT>


with self.lock:<EOL><INDENT>if event.stream != self.stream:<EOL><INDENT>return<EOL><DEDENT>self.me = event.stream.me<EOL>self.peer = event.stream.peer<EOL>presence = self.settings[u"<STR_LIT>"]<EOL>if presence:<EOL><INDENT>self.send(presence)<EOL><DEDENT><DEDENT>


with self.lock:<EOL><INDENT>if event.stream != self.stream:<EOL><INDENT>return<EOL><DEDENT>if self.stream is not None and event.stream == self.stream:<EOL><INDENT>if self.stream.transport in self._ml_handlers:<EOL><INDENT>self._ml_handlers.remove(self.stream.transport)<EOL>self.main_loop.remove_handler(self.stream.transport)<EOL><DEDENT>self.stream = None<EOL>self.uplink = None<EOL><DEDENT><DEDENT>


with self.lock:<EOL><INDENT>ret = self._iq_response_handlers.expire()<EOL>if ret is None:<EOL><INDENT>return <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>return min(<NUM_LIT:1>, ret)<EOL><DEDENT><DEDENT>

Do some housekeeping (cache expiration, timeout handling).

        This method should be called periodically from the application's
        main loop.

        :Return: suggested delay (in seconds) before the next call to this
                                                                    method.
        :Returntype: `int`


tls_handler = StreamTLSHandler(self.settings)<EOL>sasl_handler = StreamSASLHandler(self.settings)<EOL>session_handler = SessionHandler()<EOL>binding_handler = ResourceBindingHandler(self.settings)<EOL>return [tls_handler, sasl_handler, binding_handler, session_handler]<EOL>

Default base client handlers factory.

        Subclasses can provide different behaviour by overriding this.

        :Return: list of handlers


return RosterClient(self.settings)<EOL>

Creates the `RosterClient` instance for the `roster_client`
        attribute.

        Subclasses can provide different behaviour by overriding this. The
        overriding method can return `None` if no roster client is needed.

        :Return: `RosterClient`


def stanza_factory(element, return_path = None, language = None):

tag = element.tag<EOL>if tag.endswith("<STR_LIT>") or tag == "<STR_LIT>":<EOL><INDENT>return Iq(element, return_path = return_path, language = language)<EOL><DEDENT>if tag.endswith("<STR_LIT>") or tag == "<STR_LIT:message>":<EOL><INDENT>return Message(element, return_path = return_path, language = language)<EOL><DEDENT>if tag.endswith("<STR_LIT>") or tag == "<STR_LIT>":<EOL><INDENT>return Presence(element, return_path = return_path, language = language)<EOL><DEDENT>else:<EOL><INDENT>return Stanza(element, return_path = return_path, language = language)<EOL><DEDENT>

Creates Iq, Message or Presence object for XML stanza `element`

    :Parameters:
        - `element`: the stanza XML element
        - `return_path`: object through which responses to this stanza should
          be sent (will be weakly referenced by the stanza object).
        - `language`: default language for the stanza
    :Types:
        - `element`: :etree:`ElementTree.Element`
        - `return_path`: `StanzaRoute`
        - `language`: `unicode`


def __init__(self, default_timeout = <NUM_LIT>):

self.me = None<EOL>self.peer = None<EOL>self.uplink = None<EOL>self.process_all_stanzas = True<EOL>self._iq_response_handlers = ExpiringDictionary(default_timeout)<EOL>self._iq_handlers = defaultdict(dict)<EOL>self._message_handlers = []<EOL>self._presence_handlers = []<EOL>self.lock = threading.RLock()<EOL>

Initialize a `StanzaProcessor` object.

        :Parameters:
            - `default_timeout`: default timeout for IQ response handlers


if response is None or response is False:<EOL><INDENT>return False<EOL><DEDENT>if isinstance(response, Stanza):<EOL><INDENT>self.send(response)<EOL>return True<EOL><DEDENT>try:<EOL><INDENT>response = iter(response)<EOL><DEDENT>except TypeError:<EOL><INDENT>return bool(response)<EOL><DEDENT>for stanza in response:<EOL><INDENT>if isinstance(stanza, Stanza):<EOL><INDENT>self.send(stanza)<EOL><DEDENT>else:<EOL><INDENT>logger.warning("<STR_LIT>"<EOL>"<STR_LIT>".format(stanza))<EOL><DEDENT><DEDENT>return True<EOL>

Examines out the response returned by a stanza handler and sends all
        stanzas provided.

        :Parameters:
            - `response`: the response to process. `None` or `False` means 'not
              handled'. `True` means 'handled'. Stanza or stanza list means
              handled with the stanzas to send back
        :Types:
            - `response`: `bool` or `Stanza` or iterable of `Stanza`

        :Returns:
            - `True`: if `response` is `Stanza`, iterable or `True` (meaning
              the stanza was processed).
            - `False`: when `response` is `False` or `None`

        :returntype: `bool`


stanza_id = stanza.stanza_id<EOL>from_jid = stanza.from_jid<EOL>if from_jid:<EOL><INDENT>ufrom = from_jid.as_unicode()<EOL><DEDENT>else:<EOL><INDENT>ufrom = None<EOL><DEDENT>res_handler = err_handler = None<EOL>try:<EOL><INDENT>res_handler, err_handler = self._iq_response_handlers.pop(<EOL>(stanza_id, ufrom))<EOL><DEDENT>except KeyError:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(stanza_id, ufrom))<EOL>logger.debug("<STR_LIT>"<EOL>.format(from_jid, self.peer, self.me))<EOL>if ( (from_jid == self.peer or from_jid == self.me<EOL>or self.me and from_jid == self.me.bare()) ):<EOL><INDENT>try:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(stanza_id))<EOL>res_handler, err_handler =self._iq_response_handlers.pop(<EOL>(stanza_id, None))<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT><DEDENT>if stanza.stanza_type == "<STR_LIT:result>":<EOL><INDENT>if res_handler:<EOL><INDENT>response = res_handler(stanza)<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if err_handler:<EOL><INDENT>response = err_handler(stanza)<EOL><DEDENT>else:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>self._process_handler_result(response)<EOL>return True<EOL>

Process IQ stanza of type 'response' or 'error'.

        :Parameters:
            - `stanza`: the stanza received
        :Types:
            - `stanza`: `Iq`

        If a matching handler is available pass the stanza to it.  Otherwise
        ignore it if it is "error" or "result" stanza or return
        "feature-not-implemented" error if it is "get" or "set".


typ = stanza.stanza_type<EOL>if typ in ("<STR_LIT:result>", "<STR_LIT:error>"):<EOL><INDENT>return self._process_iq_response(stanza)<EOL><DEDENT>if typ not in ("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>raise BadRequestProtocolError("<STR_LIT>")<EOL><DEDENT>logger.debug("<STR_LIT>".format(<EOL>stanza, typ))<EOL>payload = stanza.get_payload(None)<EOL>logger.debug("<STR_LIT>".format(payload))<EOL>if not payload:<EOL><INDENT>raise BadRequestProtocolError("<STR_LIT>")<EOL><DEDENT>handler = self._get_iq_handler(typ, payload)<EOL>if not handler:<EOL><INDENT>payload = stanza.get_payload(None, specialize = True)<EOL>logger.debug("<STR_LIT>".format(payload))<EOL>if not isinstance(payload, XMLPayload):<EOL><INDENT>handler = self._get_iq_handler(typ, payload)<EOL><DEDENT><DEDENT>if handler:<EOL><INDENT>response = handler(stanza)<EOL>self._process_handler_result(response)<EOL>return True<EOL><DEDENT>else:<EOL><INDENT>raise ServiceUnavailableProtocolError("<STR_LIT>")<EOL><DEDENT>

Process IQ stanza received.

        :Parameters:
            - `stanza`: the stanza received
        :Types:
            - `stanza`: `Iq`

        If a matching handler is available pass the stanza to it.  Otherwise
        ignore it if it is "error" or "result" stanza or return
        "feature-not-implemented" error if it is "get" or "set".


def _get_iq_handler(self, iq_type, payload):

key = (payload.__class__, payload.handler_key)<EOL>logger.debug("<STR_LIT>"<EOL>.format(iq_type, payload, key))<EOL>logger.debug("<STR_LIT>".format(self._iq_handlers))<EOL>handler = self._iq_handlers[iq_type].get(key)<EOL>return handler<EOL>

Get an <iq/> handler for given iq  type and payload.


def __try_handlers(self, handler_list, stanza, stanza_type = None):

<EOL>if stanza_type is None:<EOL><INDENT>stanza_type = stanza.stanza_type<EOL><DEDENT>payload = stanza.get_all_payload()<EOL>classes = [p.__class__ for p in payload]<EOL>keys = [(p.__class__, p.handler_key) for p in payload]<EOL>for handler in handler_list:<EOL><INDENT>type_filter = handler._pyxmpp_stanza_handled[<NUM_LIT:1>]<EOL>class_filter = handler._pyxmpp_payload_class_handled<EOL>extra_filter = handler._pyxmpp_payload_key<EOL>if type_filter != stanza_type:<EOL><INDENT>continue<EOL><DEDENT>if class_filter:<EOL><INDENT>if extra_filter is None and class_filter not in classes:<EOL><INDENT>continue<EOL><DEDENT>if extra_filter and (class_filter, extra_filter) not in keys:<EOL><INDENT>continue<EOL><DEDENT><DEDENT>response = handler(stanza)<EOL>if self._process_handler_result(response):<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return False<EOL>

Search the handler list for handlers matching
        given stanza type and payload namespace. Run the
        handlers found ordering them by priority until
        the first one which returns `True`.

        :Parameters:
            - `handler_list`: list of available handlers
            - `stanza`: the stanza to handle
            - `stanza_type`: stanza type override (value of its "type"
              attribute)

        :return: result of the last handler or `False` if no
            handler was found.


stanza_type = stanza.stanza_type<EOL>if stanza_type is None:<EOL><INDENT>stanza_type = "<STR_LIT>"<EOL><DEDENT>if self.__try_handlers(self._message_handlers, stanza,<EOL>stanza_type = stanza_type):<EOL><INDENT>return True<EOL><DEDENT>if stanza_type not in ("<STR_LIT:error>", "<STR_LIT>"):<EOL><INDENT>return self.__try_handlers(self._message_handlers, stanza,<EOL>stanza_type = "<STR_LIT>")<EOL><DEDENT>return False<EOL>

Process message stanza.

        Pass it to a handler of the stanza's type and payload namespace.
        If no handler for the actual stanza type succeeds then hadlers
        for type "normal" are used.

        :Parameters:
            - `stanza`: message stanza to be handled


stanza_type = stanza.stanza_type<EOL>return self.__try_handlers(self._presence_handlers, stanza, stanza_type)<EOL>

Process presence stanza.

        Pass it to a handler of the stanza's type and payload namespace.

        :Parameters:
            - `stanza`: presence stanza to be handled


if stanza.stanza_type not in ("<STR_LIT:error>", "<STR_LIT:result>"):<EOL><INDENT>response = stanza.make_error_response("<STR_LIT>")<EOL>self.send(response)<EOL><DEDENT>return True<EOL>

Process stanza not addressed to us.

        Return "recipient-unavailable" return if it is not
        "error" nor "result" stanza.

        This method should be overriden in derived classes if they
        are supposed to handle stanzas not addressed directly to local
        stream endpoint.

        :Parameters:
            - `stanza`: presence stanza to be processed


self.fix_in_stanza(stanza)<EOL>to_jid = stanza.to_jid<EOL>if not self.process_all_stanzas and to_jid and (<EOL>to_jid != self.me and to_jid.bare() != self.me.bare()):<EOL><INDENT>return self.route_stanza(stanza)<EOL><DEDENT>try:<EOL><INDENT>if isinstance(stanza, Iq):<EOL><INDENT>if self.process_iq(stanza):<EOL><INDENT>return True<EOL><DEDENT><DEDENT>elif isinstance(stanza, Message):<EOL><INDENT>if self.process_message(stanza):<EOL><INDENT>return True<EOL><DEDENT><DEDENT>elif isinstance(stanza, Presence):<EOL><INDENT>if self.process_presence(stanza):<EOL><INDENT>return True<EOL><DEDENT><DEDENT><DEDENT>except ProtocolError as err:<EOL><INDENT>typ = stanza.stanza_type<EOL>if typ != '<STR_LIT:error>' and (typ != '<STR_LIT:result>'<EOL>or stanza.stanza_type != '<STR_LIT>'):<EOL><INDENT>response = stanza.make_error_response(err.xmpp_name)<EOL>self.send(response)<EOL>err.log_reported()<EOL><DEDENT>else:<EOL><INDENT>err.log_ignored()<EOL><DEDENT>return<EOL><DEDENT>logger.debug("<STR_LIT>" % (stanza.stanza_type,<EOL>stanza.serialize()))<EOL>return False<EOL>

Process stanza received from the stream.

        First "fix" the stanza with `self.fix_in_stanza()`,
        then pass it to `self.route_stanza()` if it is not directed
        to `self.me` and `self.process_all_stanzas` is not True. Otherwise
        stanza is passwd to `self.process_iq()`, `self.process_message()`
        or `self.process_presence()` appropriately.

        :Parameters:
            - `stanza`: the stanza received.

        :returns: `True` when stanza was handled


if to_jid != self.me:<EOL><INDENT>return None<EOL><DEDENT>return to_jid<EOL>

Check "to" attribute of received stream header.

        :return: `to_jid` if it is equal to `self.me`, None otherwise.

        Should be overriden in derived classes which require other logic
        for handling that attribute.


def set_response_handlers(self, stanza, res_handler, err_handler,<EOL>timeout_handler = None, timeout = None):

Set response handler for an IQ "get" or "set" stanza.

        This should be called before the stanza is sent.

        :Parameters:
            - `stanza`: an IQ stanza
            - `res_handler`: result handler for the stanza. Will be called
              when matching <iq type="result"/> is received. Its only
              argument will be the stanza received. The handler may return
              a stanza or list of stanzas which should be sent in response.
            - `err_handler`: error handler for the stanza. Will be called
              when matching <iq type="error"/> is received. Its only
              argument will be the stanza received. The handler may return
              a stanza or list of stanzas which should be sent in response
              but this feature should rather not be used (it is better not to
              respond to 'error' stanzas).
            - `timeout_handler`: timeout handler for the stanza. Will be called
              (with no arguments) when no matching <iq type="result"/> or <iq
              type="error"/> is received in next `timeout` seconds.
            - `timeout`: timeout value for the stanza. After that time if no
              matching <iq type="result"/> nor <iq type="error"/> stanza is
              received, then timeout_handler (if given) will be called.


def _set_response_handlers(self, stanza, res_handler, err_handler,<EOL>timeout_handler = None, timeout = None):

<EOL>self.fix_out_stanza(stanza)<EOL>to_jid = stanza.to_jid<EOL>if to_jid:<EOL><INDENT>to_jid = str(to_jid)<EOL><DEDENT>if timeout_handler:<EOL><INDENT>def callback(dummy1, dummy2):<EOL><INDENT>"""<STR_LIT>"""<EOL>timeout_handler()<EOL><DEDENT>self._iq_response_handlers.set_item(<EOL>(stanza.stanza_id, to_jid),<EOL>(res_handler,err_handler),<EOL>timeout, callback)<EOL><DEDENT>else:<EOL><INDENT>self._iq_response_handlers.set_item(<EOL>(stanza.stanza_id, to_jid),<EOL>(res_handler, err_handler),<EOL>timeout)<EOL><DEDENT>

Same as `set_response_handlers` but assume `self.lock` is
        acquired.


Remove all registered response handlers.


def setup_stanza_handlers(self, handler_objects, usage_restriction):

<EOL>iq_handlers = {"<STR_LIT>": {}, "<STR_LIT>": {}}<EOL>message_handlers = []<EOL>presence_handlers = []<EOL>for obj in handler_objects:<EOL><INDENT>if not isinstance(obj, XMPPFeatureHandler):<EOL><INDENT>continue<EOL><DEDENT>obj.stanza_processor = self<EOL>for dummy, handler in inspect.getmembers(obj, callable):<EOL><INDENT>if not hasattr(handler, "<STR_LIT>"):<EOL><INDENT>continue<EOL><DEDENT>element_name, stanza_type = handler._pyxmpp_stanza_handled<EOL>restr = handler._pyxmpp_usage_restriction<EOL>if restr and restr != usage_restriction:<EOL><INDENT>continue<EOL><DEDENT>if element_name == "<STR_LIT>":<EOL><INDENT>payload_class = handler._pyxmpp_payload_class_handled<EOL>payload_key = handler._pyxmpp_payload_key<EOL>if (payload_class, payload_key) in iq_handlers[stanza_type]:<EOL><INDENT>continue<EOL><DEDENT>iq_handlers[stanza_type][(payload_class, payload_key)] =handler<EOL>continue<EOL><DEDENT>elif element_name == "<STR_LIT:message>":<EOL><INDENT>handler_list = message_handlers<EOL><DEDENT>elif element_name == "<STR_LIT>":<EOL><INDENT>handler_list = presence_handlers<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>handler_list.append(handler)<EOL><DEDENT><DEDENT>with self.lock:<EOL><INDENT>self._iq_handlers = iq_handlers<EOL>self._presence_handlers = presence_handlers<EOL>self._message_handlers = message_handlers<EOL><DEDENT>

Install stanza handlers provided by `handler_objects`


pass<EOL>

Modify incoming stanza before processing it.

        This implementation does nothig. It should be overriden in derived
        classes if needed.


pass<EOL>

Modify outgoing stanza before sending into the stream.

        This implementation does nothig. It should be overriden in derived
        classes if needed.


if self.uplink:<EOL><INDENT>self.uplink.send(stanza)<EOL><DEDENT>else:<EOL><INDENT>raise NoRouteError("<STR_LIT>")<EOL><DEDENT>

Send a stanza somwhere.

        The default implementation sends it via the `uplink` if it is defined
        or raises the `NoRouteError`.

        :Parameters:
            - `stanza`: the stanza to send.
        :Types:
            - `stanza`: `pyxmpp.stanza.Stanza`


def __init__(self, element = None, from_jid = None, to_jid = None,<EOL>stanza_type = None, stanza_id = None,<EOL>error = None, error_cond=None, return_path = None,<EOL>language = None):

<EOL>if stanza_type is None:<EOL><INDENT>if element is None:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT><DEDENT>elif stanza_type not in IQ_TYPES:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if element is None and stanza_id is None and stanza_type in (<EOL>"<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>stanza_id = self.gen_id()<EOL><DEDENT>if element is None:<EOL><INDENT>element = "<STR_LIT>"<EOL><DEDENT>elif not isinstance(element, ElementClass):<EOL><INDENT>raise TypeError("<STR_LIT>" + repr(element))<EOL><DEDENT>Stanza.__init__(self, element, from_jid = from_jid, to_jid = to_jid,<EOL>stanza_type = stanza_type, stanza_id = stanza_id,<EOL>error = error, error_cond = error_cond,<EOL>return_path = return_path, language = language)<EOL>if self.element_name != "<STR_LIT>":<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>

Initialize an `Iq` object.

        :Parameters:
            - `element`: XML element of this stanza.
            - `from_jid`: sender JID.
            - `to_jid`: recipient JID.
            - `stanza_type`: staza type: one of: "get", "set", "response"
              or "error".
            - `stanza_id`: stanza id -- value of stanza's "id" attribute. If
              not given, then unique for the session value is generated.
            - `error_cond`: error condition name. Ignored if `stanza_type`
              is not "error".
            - `language`: default language for the stanza content
        :Types:
            - `element`: :etree:`ElementTree.Element`
            - `from_jid`: `JID`
            - `to_jid`: `JID`
            - `stanza_type`: `unicode`
            - `stanza_id`: `unicode`
            - `error`: `pyxmpp.error.StanzaErrorElement`
            - `error_cond`: `unicode`
            - `language`: `unicode`


result = Iq(None, self.from_jid, self.to_jid,<EOL>self.stanza_type, self.stanza_id, self.error,<EOL>self._return_path())<EOL>if self._payload is None:<EOL><INDENT>self.decode_payload()<EOL><DEDENT>for payload in self._payload:<EOL><INDENT>Stanza.add_payload(result, payload)<EOL><DEDENT>return result<EOL>

Create a deep copy of the stanza.

        :returntype: `Iq`


if self.stanza_type in ("<STR_LIT:result>", "<STR_LIT:error>"):<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>stanza = Iq(stanza_type="<STR_LIT:error>", from_jid = self.to_jid,<EOL>to_jid = self.from_jid, stanza_id = self.stanza_id,<EOL>error_cond = cond)<EOL>if self._payload is None:<EOL><INDENT>self.decode_payload()<EOL><DEDENT>for payload in self._payload:<EOL><INDENT>Stanza.add_payload(stanza, payload)<EOL><DEDENT>return stanza<EOL>

Create error response for the a "get" or "set" iq stanza.

        :Parameters:
            - `cond`: error condition name, as defined in XMPP specification.

        :return: new `Iq` object with the same "id" as self, "from" and "to"
            attributes swapped, type="error" and containing <error /> element
            plus payload of `self`.
        :returntype: `Iq`


if self.stanza_type not in ("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>stanza = Iq(stanza_type = "<STR_LIT:result>", from_jid = self.to_jid,<EOL>to_jid = self.from_jid, stanza_id = self.stanza_id)<EOL>return stanza<EOL>

Create result response for the a "get" or "set" iq stanza.

        :return: new `Iq` object with the same "id" as self, "from" and "to"
            attributes replaced and type="result".
        :returntype: `Iq`


if self._payload is None:<EOL><INDENT>self.decode_payload()<EOL><DEDENT>if len(self._payload) >= <NUM_LIT:1>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return Stanza.add_payload(self, payload)<EOL>

Add new the stanza payload. Fails if there is already some
        payload element attached (<iq/> stanza can contain only one payload
        element)

        Marks the stanza dirty.

        :Parameters:
            - `payload`: XML element or stanza payload object to add
        :Types:
            - `payload`: :etree:`ElementTree.Element` or
              `interfaces.StanzaPayload`


reader_thread = threading.Thread(target = self.reader_run,<EOL>name = "<STR_LIT>")<EOL>reader_thread.daemon = True<EOL>writter_thread = threading.Thread(target = self.writter_run,<EOL>name = "<STR_LIT>")<EOL>writter_thread.daemon = True<EOL>reader_thread.start()<EOL>writter_thread.start()<EOL>


logger.debug("<STR_LIT>")<EOL>while True:<EOL><INDENT>try:<EOL><INDENT>self.sock.do_handshake()<EOL>break<EOL><DEDENT>except ssl.SSLError as err:<EOL><INDENT>if err.args[<NUM_LIT:0>] == ssl.SSL_ERROR_WANT_READ:<EOL><INDENT>select.select([self.sock], [], [])<EOL><DEDENT>elif err.args[<NUM_LIT:0>] == ssl.SSL_ERROR_WANT_WRITE:<EOL><INDENT>select.select([], [self.sock], [])<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT><DEDENT>logger.debug("<STR_LIT>")<EOL>self.extra_on_read = None<EOL>self.write_enabled = True<EOL>self.write_cond.notify()<EOL>

Do the TLS handshake. Called from the reader thread
        after `starttls` is called.


kwargs['<STR_LIT>'] = False<EOL>with self.lock:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>while self.wdata:<EOL><INDENT>self.write_cond.wait()<EOL><DEDENT>self.write_enabled = False<EOL>self.write_cond.notify()<EOL>logger.debug("<STR_LIT>")<EOL>self.sock = ssl.wrap_socket(*args, **kwargs)<EOL>self.extra_on_read = self._do_tls_handshake<EOL>self.rdata = b"<STR_LIT>"<EOL><DEDENT>

Request switching to TLS.

        First waits untill all currently buffered data is sent.

        :Parameters:
            - `args`: positional arguments to :std:`ssl.wrap_socket`
            - `kwargs`: keyword arguments to :std:`ssl.wrap_socket`


with self.write_cond:<EOL><INDENT>while self.sock is not None:<EOL><INDENT>while self.ready and self.wdata and self.write_enabled:<EOL><INDENT>sent = self.sock.send(self.wdata)<EOL>logger.debug("<STR_LIT>" + repr(self.wdata[:sent]))<EOL>self.wdata = self.wdata[sent:]<EOL>self.write_cond.notify()<EOL><DEDENT>if self._disconnect and not self.wdata:<EOL><INDENT>self.sock.shutdown(socket.SHUT_WR)<EOL>logger.debug("<STR_LIT>")<EOL>break<EOL><DEDENT>self.write_cond.wait()<EOL><DEDENT><DEDENT>


WSAEBADF = getattr(errno, "<STR_LIT>", None)<EOL>with self.lock:<EOL><INDENT>if not self.sock or self.eof:<EOL><INDENT>return<EOL><DEDENT>while not self.eof and self.sock is not None:<EOL><INDENT>self.lock.release()<EOL>try:<EOL><INDENT>ret = infd, _outfd, _errfd = select.select([self.sock], [],<EOL>[], <NUM_LIT:5>)<EOL><DEDENT>except select.error as err:<EOL><INDENT>if WSAEBADF and err == WSAEBADF:<EOL><INDENT>self.sock = None<EOL>break<EOL><DEDENT>raise<EOL><DEDENT>finally:<EOL><INDENT>self.lock.acquire()<EOL><DEDENT>if not self.sock:<EOL><INDENT>break<EOL><DEDENT>if infd:<EOL><INDENT>if self.extra_on_read:<EOL><INDENT>self.extra_on_read()<EOL><DEDENT>elif self.ready:<EOL><INDENT>data = self.sock.recv(<NUM_LIT>)<EOL>if not data:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>self.eof = True<EOL>self.eof_cond.notifyAll()<EOL><DEDENT>else:<EOL><INDENT>logger.debug("<STR_LIT>" + repr(data))<EOL>self.rdata += data<EOL><DEDENT><DEDENT>else:<EOL><INDENT>sock1, self.peer = self.sock.accept()<EOL>logger.debug("<STR_LIT>" + repr(self.peer))<EOL>self.sock.close()<EOL>self.sock = sock1<EOL>self.ready = True<EOL>self.write_cond.notify()<EOL><DEDENT><DEDENT><DEDENT><DEDENT>


with self.write_cond:<EOL><INDENT>self.wdata += data<EOL>if self.ready:<EOL><INDENT>self.write_cond.notify()<EOL><DEDENT><DEDENT>


with self.write_cond:<EOL><INDENT>self._disconnect = True<EOL>self.write_cond.notify()<EOL><DEDENT>


with self.lock:<EOL><INDENT>data, self.rdata = self.rdata, "<STR_LIT>"<EOL><DEDENT>return data<EOL>

Read data from input buffer (received by the reader thread).


with self.lock:<EOL><INDENT>if self.sock is not None:<EOL><INDENT>self.sock.close()<EOL><DEDENT>self.sock = None<EOL>self.wdata = None<EOL>self.write_cond.notify()<EOL>self.eof_cond.wait(<NUM_LIT:0.1>)<EOL><DEDENT>

Close the socket and request the threads to stop.


with self.eof_cond:<EOL><INDENT>if not self.eof:<EOL><INDENT>self.eof_cond.wait(timeout)<EOL><DEDENT><DEDENT>

Wait for socket closing, an error or `timeout` seconds.


if "<STR_LIT>" not in _support.RESOURCES:<EOL><INDENT>raise unittest.SkipTest("<STR_LIT>")<EOL><DEDENT>try:<EOL><INDENT>sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<EOL>sock.close()<EOL>cls.can_do_ipv4 = True<EOL><DEDENT>except socket.error as err:<EOL><INDENT>logger.debug("<STR_LIT>".format(err))<EOL>pass<EOL><DEDENT>if socket.has_ipv6:<EOL><INDENT>try:<EOL><INDENT>sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)<EOL>sock.close()<EOL>cls.can_do_ipv6 = True<EOL><DEDENT>except socket.error as err:<EOL><INDENT>logger.debug("<STR_LIT>".format(err))<EOL>pass<EOL><DEDENT><DEDENT>

Check if loopback networking is enabled and IPv4 and IPv6 sockets
        available.


self.server = None<EOL>self.client = None<EOL>XMPPSettings._defs['<STR_LIT>'].default = None<EOL>

Initialize class instance for a new test.


if self.server:<EOL><INDENT>self.server.close()<EOL><DEDENT>if self.client:<EOL><INDENT>self.client.close()<EOL><DEDENT>XMPPSettings._defs['<STR_LIT>'].default = None<EOL>

Stop the server and client connections started.


def start_server(self, ip_version = <NUM_LIT:4>):

sock = self.make_listening_socket(ip_version)<EOL>self.server = NetReaderWritter(sock, need_accept = True)<EOL>self.server.start()<EOL>return sock.getsockname()<EOL>

Create the `server` object, start its thread and return
        assigned socket address (IP address, port).


def make_listening_socket(self, ip_version = <NUM_LIT:4>):

if ip_version == <NUM_LIT:4>:<EOL><INDENT>if not self.can_do_ipv4:<EOL><INDENT>self.skipTest("<STR_LIT>")<EOL>return None<EOL><DEDENT>family = socket.AF_INET<EOL>addr = "<STR_LIT:127.0.0.1>"<EOL><DEDENT>elif ip_version == <NUM_LIT:6>:<EOL><INDENT>if not self.can_do_ipv6:<EOL><INDENT>self.skipTest("<STR_LIT>")<EOL>return None<EOL><DEDENT>family = socket.AF_INET6<EOL>addr = "<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>sock = socket.socket(family, socket.SOCK_STREAM)<EOL>sock.bind((addr, <NUM_LIT:0>))<EOL>sock.listen(<NUM_LIT:1>)<EOL>return sock<EOL>

Create a listening socket on a random (OS-assigned) port
        on the loopback interface.


def start_client(self, sockaddr, ip_version = <NUM_LIT:4>):

if ip_version == <NUM_LIT:4>:<EOL><INDENT>if not self.can_do_ipv4:<EOL><INDENT>self.skipTest("<STR_LIT>")<EOL>return None<EOL><DEDENT>family = socket.AF_INET<EOL><DEDENT>elif ip_version == <NUM_LIT:6>:<EOL><INDENT>if not self.can_do_ipv6:<EOL><INDENT>self.skipTest("<STR_LIT>")<EOL>return None<EOL><DEDENT>family = socket.AF_INET6<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>sock = socket.socket(family, socket.SOCK_STREAM)<EOL>sock.connect(sockaddr)<EOL>self.client = NetReaderWritter(sock)<EOL>self.client.start()<EOL>return sock.getsockname()<EOL>

Create the `client` object, starts its threads anc
        connect it to the provided `sockaddr`.

        :Return: its socket address


self.transport = TCPTransport()<EOL>self.make_loop(handlers + [self.transport])<EOL>

Initialize a transport and a main loop with the provided handlers


addr, port = self.start_server()<EOL>self.transport.connect(addr, port)<EOL>

Start a test server and connect the transport to it.


self.loop = SelectMainLoop(None, handlers)<EOL>

Return a main loop object for use with this test suite.


def wait(self, timeout = TIMEOUT, expect = None):

timeout = time.time() + timeout<EOL>while not self.loop.finished:<EOL><INDENT>self.loop.loop_iteration(<NUM_LIT:0.1>)<EOL>if expect:<EOL><INDENT>match = expect.match(self.server.rdata)<EOL>if match:<EOL><INDENT>return match.group(<NUM_LIT:1>)<EOL><DEDENT><DEDENT>if time.time() > timeout:<EOL><INDENT>break<EOL><DEDENT><DEDENT>

Wait until the main loop finishes, `timeout` seconds passes
        or current server input matches `expect`.


def wait_short(self, timeout = <NUM_LIT:0.1>):


<EOL>self.loop = PollMainLoop(None, handlers)<EOL>


<EOL>from pyxmpp2.mainloop.glib import GLibMainLoop<EOL>self.loop = GLibMainLoop(None, handlers)<EOL>


<EOL>self.loop = ThreadPool(XMPPSettings({"<STR_LIT>": <NUM_LIT:0.1>}), handlers)<EOL>


InitiatorSelectTestCase.connect_transport(self)<EOL>self.loop.start()<EOL>


sock = self.make_listening_socket()<EOL>self.addr = sock.getsockname()<EOL>self.start_client(self.addr)<EOL>self.transport = TCPTransport(sock = sock.accept()[<NUM_LIT:0>])<EOL>sock.close()<EOL>self.make_loop(handlers + [self.transport])<EOL>

Create a listening socket for the tested stream,
        a transport a main loop and create a client connectiong to the
        socket.


timeout = time.time() + timeout<EOL>while not self.loop.finished:<EOL><INDENT>self.loop.loop_iteration(<NUM_LIT:0.1>)<EOL>if expect:<EOL><INDENT>match = expect.match(self.client.rdata)<EOL>if match:<EOL><INDENT>return match.group(<NUM_LIT:1>)<EOL><DEDENT><DEDENT>if time.time() > timeout:<EOL><INDENT>break<EOL><DEDENT><DEDENT>


super(ReceiverThreadedTestMixIn, self).start_transport(handlers)<EOL>self.loop.start()<EOL>


self.events_received.append(event)<EOL>return False<EOL>

Handle any event: store it in `events_received`.


<EOL>event.stream.event(QUIT)<EOL>

Handle the `DisconnectedEvent`: abort the main loop.


<EOL>global logging_ready<EOL>if logging_ready:<EOL><INDENT>return<EOL><DEDENT>if sys.argv.count("<STR_LIT>") > <NUM_LIT:2>:<EOL><INDENT>logging.basicConfig(level=logging.DEBUG)<EOL><DEDENT>elif sys.argv.count("<STR_LIT>") == <NUM_LIT:2>:<EOL><INDENT>logging.basicConfig(level=logging.INFO)<EOL><DEDENT>else:<EOL><INDENT>logging.basicConfig(level=logging.ERROR)<EOL><DEDENT>logging_ready = True<EOL>

Set up logging for the tests.

    Log level used depends on number of '-v' in sys.argv


suite = unittest.TestSuite()<EOL>for mod in unittest.defaultTestLoader.discover("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>suite.addTest(mod)<EOL><DEDENT>return suite<EOL>

Discover all the test suites in pyxmpp2.test.


return SelectMainLoop(None, handlers)<EOL>


def start_connections(self, target_address, number):

def thread_func():<EOL><INDENT>for dummy in range(number):<EOL><INDENT>sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<EOL>try:<EOL><INDENT>sock.connect(target_address)<EOL>with self.lock:<EOL><INDENT>if self.connected is None:<EOL><INDENT>return<EOL><DEDENT>self.connected.append(sock)<EOL><DEDENT><DEDENT>except:<EOL><INDENT>sock.close()<EOL>raise<EOL><DEDENT><DEDENT><DEDENT>thread = threading.Thread(name = "<STR_LIT>",<EOL>target = thread_func)<EOL>thread.daemon = True<EOL>thread.start()<EOL>

Start a thread which will make `number` connections to
`target_address`.


return PollMainLoop(None, handlers)<EOL>


from pyxmpp2.mainloop.glib import GLibMainLoop<EOL>return GLibMainLoop(None, handlers)<EOL>


self._loop = ThreadPool(None, handlers)<EOL>self._loop.start()<EOL>return self._loop<EOL>


def __init__(self, family, address, target):

self._socket = None<EOL>self._lock = threading.RLock()<EOL>self._target = target<EOL>sock = socket.socket(family, socket.SOCK_STREAM)<EOL>try:<EOL><INDENT>sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, <NUM_LIT:1>)<EOL>sock.bind(address)<EOL><DEDENT>except:<EOL><INDENT>sock.close()<EOL>raise<EOL><DEDENT>self._socket = sock<EOL>

Initialize the `TCPListener` object and create the socket.

        :Parameters:
            - `family`: address family (:std:`socket.AF_INET` or
              :std:`socket.AF_INET6`)
            - `address`: address to listen on (address, port)
            - `target`: function to call on an accepted connection


with self._lock:<EOL><INDENT>if self._socket:<EOL><INDENT>self._socket.listen(SOMAXCONN)<EOL>self._socket.setblocking(False)<EOL><DEDENT>return HandlerReady()<EOL><DEDENT>

When connecting start the next connection step and schedule
        next `prepare` call, when connected return `HandlerReady()`


with self._lock:<EOL><INDENT>if self._socket:<EOL><INDENT>return self._socket.fileno()<EOL><DEDENT><DEDENT>

Return file descriptor to poll or select.


with self._lock:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>if self._socket is None:<EOL><INDENT>return<EOL><DEDENT>while True:<EOL><INDENT>try:<EOL><INDENT>sock, address = self._socket.accept()<EOL><DEDENT>except socket.error as err:<EOL><INDENT>if err.args[<NUM_LIT:0>] in BLOCKING_ERRORS:<EOL><INDENT>break<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>logger.debug("<STR_LIT>".format(address))<EOL>self._target(sock, address)<EOL><DEDENT><DEDENT>


logger.debug("<STR_LIT>".format(<EOL>element_name))<EOL>logger.debug("<STR_LIT>".format(STANZA_PAYLOAD_CLASSES))<EOL>if element_name in STANZA_PAYLOAD_CLASSES:<EOL><INDENT>return STANZA_PAYLOAD_CLASSES[element_name]<EOL><DEDENT>else:<EOL><INDENT>return XMLPayload<EOL><DEDENT>

Return a payload class for given element name.


return STANZA_PAYLOAD_ELEMENTS[klass]<EOL>

Return a payload element name for given class.


return payload_class_for_element_name(element.tag).from_xml(element)<EOL>

Return a specialized `StanzaPayload` object for given element.


return self.xml_element_name<EOL>

Return `xml_element_name` as the extra key for stanza
        handlers.


logger.error("<STR_LIT>".format(element))<EOL>

Called when the start tag of root element is encountered
        in the stream.

        :Parameters:
            - `element`: the root element
        :Types:
            - `element`: :etree:`ElementTree.Element`


Called when the end tag of root element is encountered
        in the stream.


Called when the end tag of a direct child of the root
        element is encountered in the stream.

        :Parameters:
            - `element`: the (complete) element being processed
        :Types:
            - `element`: :etree:`ElementTree.Element`


raise StreamParseError(descr)<EOL>

Called when an error is encountered in the stream.

        :Parameters:
            - `descr`: description of the error
        :Types:
            - `descr`: `unicode`


pass<EOL>

Called when stream input ends (EOF, socket closed by peer)
        which could happen before actual stream end tag was received,
        but usually will happen just after that.

        This event is not generated by the XMPP parser, but may be generated
        by transports.


self._handler = handler<EOL>self._head = "<STR_LIT>"<EOL>self._tail = "<STR_LIT>"<EOL>self._builder = None<EOL>self._level = <NUM_LIT:0><EOL>self._root = None<EOL>

Initialize the SAX handler.

        :Parameters:
            - `handler`: Object to handle stream start, end and stanzas.
        :Types:
            - `handler`: `XMLStreamHandler`


if self._level > <NUM_LIT:1>:<EOL><INDENT>return self._builder.data(data)<EOL><DEDENT>

Handle XML text data.

        Ignore the data outside the root element and directly under the root,
        pass all other text to the tree builder, so it will be included in the
        stanzas.


if self._level == <NUM_LIT:0>:<EOL><INDENT>self._root = ElementTree.Element(tag, attrs)<EOL>self._handler.stream_start(self._root)<EOL><DEDENT>if self._level < <NUM_LIT:2>:<EOL><INDENT>self._builder = ElementTree.TreeBuilder()<EOL><DEDENT>self._level += <NUM_LIT:1><EOL>return self._builder.start(tag, attrs)<EOL>

Handle the start tag.

        Call the handler's 'stream_start' methods with
        an empty root element if it is top level.

        For lower level tags use :etree:`ElementTree.TreeBuilder` to collect
        them.


pass<EOL>


self._level -= <NUM_LIT:1><EOL>if self._level < <NUM_LIT:0>:<EOL><INDENT>self._handler.stream_parse_error("<STR_LIT>"<EOL>.format(tag))<EOL>return<EOL><DEDENT>if self._level == <NUM_LIT:0>:<EOL><INDENT>if tag != self._root.tag:<EOL><INDENT>self._handler.stream_parse_error("<STR_LIT>"<EOL>"<STR_LIT>".format(tag))<EOL>return<EOL><DEDENT>self._handler.stream_end()<EOL>return<EOL><DEDENT>element = self._builder.end(tag)<EOL>if self._level == <NUM_LIT:1>:<EOL><INDENT>self._handler.stream_element(element)<EOL><DEDENT>

Handle an end tag.

        Call the handler's 'stream_end' method with
        an the root element (built by the `start` method).

        On the first level below root, sent the built element tree
        to the handler via the 'stanza methods'.

        Any tag below will be just added to the tree builder.


self.handler = handler<EOL>self.parser = ElementTree.XMLParser(target = ParserTarget(handler))<EOL>self.lock = threading.RLock()<EOL>self.in_use = False<EOL>self._started = False<EOL>

Initialize the reader.

        :Parameters:
            - `handler`: Object to handle stream start, end and stanzas.
        :Types:
            - `handler`: `XMLStreamHandler`


with self.lock:<EOL><INDENT>if self.in_use:<EOL><INDENT>raise StreamParseError("<STR_LIT>")<EOL><DEDENT>self.in_use = True<EOL>try:<EOL><INDENT>if not self._started:<EOL><INDENT>if len(data) > <NUM_LIT:1>:<EOL><INDENT>self.parser.feed(data[:<NUM_LIT:1>])<EOL>data = data[<NUM_LIT:1>:]<EOL><DEDENT>self._started = True<EOL><DEDENT>if data:<EOL><INDENT>self.parser.feed(data)<EOL><DEDENT>else:<EOL><INDENT>self.parser.close()<EOL><DEDENT><DEDENT>except ElementTree.ParseError as err:<EOL><INDENT>self.handler.stream_parse_error(str(err))<EOL><DEDENT>finally:<EOL><INDENT>self.in_use = False<EOL><DEDENT><DEDENT>

Feed the parser with a chunk of data. Apropriate methods
        of `handler` will be called whenever something interesting is
        found.

        :Parameters:
            - `data`: the chunk of data to parse.
        :Types:
            - `data`: `str`


if stringprep.in_table_b1(char):<EOL><INDENT>return u"<STR_LIT>"<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Do RFC 3454 B.1 table mapping.

    :Parameters:
        - `char`: Unicode character to map.

    :returns: u"" if there is `char` code in the table, `None` otherwise.


if stringprep.in_table_c12(char):<EOL><INDENT>return u"<STR_LIT:U+0020>"<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Do mapping of RFC 3454 C.1.2 space characters to ' '.

    :Parameters:
        - `char`: Unicode character to map.

    :returns: u" " if there is `char` code in the table, `None` otherwise.


if isinstance(data, list):<EOL><INDENT>data = u"<STR_LIT>".join(data)<EOL><DEDENT>return unicodedata.normalize("<STR_LIT>", data)<EOL>

Do NFKC normalization of Unicode data.

    :Parameters:
        - `data`: list of Unicode characters or Unicode string.

    :return: normalized Unicode string.


<EOL>global _stringprep_cache_size<EOL>_stringprep_cache_size = size<EOL>if len(Profile.cache_items) > size:<EOL><INDENT>remove = Profile.cache_items[:-size]<EOL>for profile, key in remove:<EOL><INDENT>try:<EOL><INDENT>del profile.cache[key]<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>Profile.cache_items = Profile.cache_items[-size:]<EOL><DEDENT>

Modify stringprep cache size.

    :Parameters:
        - `size`: new cache size


def __init__(self, unassigned, mapping, normalization, prohibited,<EOL>bidi = True):

<EOL>self.unassigned = unassigned<EOL>self.mapping = mapping<EOL>self.normalization = normalization<EOL>self.prohibited = prohibited<EOL>self.bidi = bidi<EOL>self.cache = {}<EOL>

Initialize Profile object.

        :Parameters:
            - `unassigned`: the lookup table with unassigned codes
            - `mapping`: the lookup table with character mappings
            - `normalization`: the normalization function
            - `prohibited`: the lookup table with prohibited characters
            - `bidi`: if True then bidirectional checks should be done
        :Types:
            - `unassigned`: tuple of functions
            - `mapping`: tuple of functions
            - `normalization`: tuple of functions
            - `prohibited`: tuple of functions
            - `bidi`: `bool`


ret = self.cache.get(data)<EOL>if ret is not None:<EOL><INDENT>return ret<EOL><DEDENT>result = self.map(data)<EOL>if self.normalization:<EOL><INDENT>result = self.normalization(result)<EOL><DEDENT>result = self.prohibit(result)<EOL>result = self.check_unassigned(result)<EOL>if self.bidi:<EOL><INDENT>result = self.check_bidi(result)<EOL><DEDENT>if isinstance(result, list):<EOL><INDENT>result = u"<STR_LIT>".join()<EOL><DEDENT>if len(self.cache_items) >= _stringprep_cache_size:<EOL><INDENT>remove = self.cache_items[: -_stringprep_cache_size // <NUM_LIT:2>]<EOL>for profile, key in remove:<EOL><INDENT>try:<EOL><INDENT>del profile.cache[key]<EOL><DEDENT>except KeyError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>self.cache_items[:] = self.cache_items[<EOL>-_stringprep_cache_size // <NUM_LIT:2> :]<EOL><DEDENT>self.cache_items.append((self, data))<EOL>self.cache[data] = result<EOL>return result<EOL>

Complete string preparation procedure for 'stored' strings.
        (includes checks for unassigned codes)

        :Parameters:
            - `data`: Unicode string to prepare.

        :return: prepared string

        :raise StringprepError: if the preparation fails


data = self.map(data)<EOL>if self.normalization:<EOL><INDENT>data = self.normalization(data)<EOL><DEDENT>data = self.prohibit(data)<EOL>if self.bidi:<EOL><INDENT>data = self.check_bidi(data)<EOL><DEDENT>if isinstance(data, list):<EOL><INDENT>data = u"<STR_LIT>".join(data)<EOL><DEDENT>return data<EOL>

Complete string preparation procedure for 'query' strings.
        (without checks for unassigned codes)

        :Parameters:
            - `data`: Unicode string to prepare.

        :return: prepared string

        :raise StringprepError: if the preparation fails


result = []<EOL>for char in data:<EOL><INDENT>ret = None<EOL>for lookup in self.mapping:<EOL><INDENT>ret = lookup(char)<EOL>if ret is not None:<EOL><INDENT>break<EOL><DEDENT><DEDENT>if ret is not None:<EOL><INDENT>result.append(ret)<EOL><DEDENT>else:<EOL><INDENT>result.append(char)<EOL><DEDENT><DEDENT>return result<EOL>


for char in data:<EOL><INDENT>for lookup in self.prohibited:<EOL><INDENT>if lookup(char):<EOL><INDENT>raise StringprepError("<STR_LIT>"<EOL>.format(char))<EOL><DEDENT><DEDENT><DEDENT>return data<EOL>


for char in data:<EOL><INDENT>for lookup in self.unassigned:<EOL><INDENT>if lookup(char):<EOL><INDENT>raise StringprepError("<STR_LIT>"<EOL>.format(char))<EOL><DEDENT><DEDENT><DEDENT>return data<EOL>


has_l = False<EOL>has_ral = False<EOL>for char in data:<EOL><INDENT>if stringprep.in_table_d1(char):<EOL><INDENT>has_ral = True<EOL><DEDENT>elif stringprep.in_table_d2(char):<EOL><INDENT>has_l = True<EOL><DEDENT><DEDENT>if has_l and has_ral:<EOL><INDENT>raise StringprepError("<STR_LIT>")<EOL><DEDENT>if has_ral and (not stringprep.in_table_d1(data[<NUM_LIT:0>])<EOL>or not stringprep.in_table_d1(data[-<NUM_LIT:1>])):<EOL><INDENT>raise StringprepError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>return data<EOL>

Checks if sting is valid for bidirectional printing.


def __init__(self, settings = None, sock = None):

if settings:<EOL><INDENT>self.settings = settings<EOL><DEDENT>else:<EOL><INDENT>self.settings = XMPPSettings()<EOL><DEDENT>self.lock = threading.RLock()<EOL>self._write_queue = deque()<EOL>self._write_queue_cond = threading.Condition(self.lock)<EOL>self._eof = False<EOL>self._hup = False<EOL>self._stream = None<EOL>self._serializer = None<EOL>self._reader = None<EOL>self._dst_name = None<EOL>self._dst_port = None<EOL>self._dst_service = None<EOL>self._dst_nameports = None<EOL>self._dst_hostname = None<EOL>self._dst_addrs = None<EOL>self._tls_state = None<EOL>self._state_cond = threading.Condition(self.lock)<EOL>if sock is None:<EOL><INDENT>self._socket = None<EOL>self._dst_addr = None<EOL>self._family = None<EOL>self._state = None<EOL><DEDENT>else:<EOL><INDENT>self._socket = sock<EOL>self._family = sock.family<EOL>self._dst_addr = sock.getpeername()<EOL>self._state = "<STR_LIT>"<EOL>self._socket.setblocking(False)<EOL><DEDENT>self._event_queue = self.settings["<STR_LIT>"]<EOL>self._auth_properties = {}<EOL>

Initialize the `TCPTransport` object.

        :Parameters:
            - `settings`: XMPP settings to use
            - `sock`: existing socket, e.g. for accepted incoming connection.


logger.debug("<STR_LIT>".format(state))<EOL>self._state = state<EOL>self._state_cond.notify()<EOL>

Set `_state` and notify any threads waiting for the change.


def connect(self, addr, port = None, service = None):

with self.lock:<EOL><INDENT>self._connect(addr, port, service)<EOL><DEDENT>

Start establishing TCP connection with given address.

        One of: `port` or `service` must be provided and `addr` must be
        a domain name and not an IP address if `port` is not given.

        When `service` is given try an SRV lookup for that service
        at domain `addr`. If `service` is not given or `addr` is an IP address,
        or the SRV lookup fails, connect to `port` at host `addr` directly.

        [initiating entity only]

        :Parameters:
            - `addr`: peer name or IP address
            - `port`: port number to connect to
            - `service`: service name (to be resolved using SRV DNS records)


def _connect(self, addr, port, service):

self._dst_name = addr<EOL>self._dst_port = port<EOL>family = None<EOL>try:<EOL><INDENT>res = socket.getaddrinfo(addr, port, socket.AF_UNSPEC,<EOL>socket.SOCK_STREAM, <NUM_LIT:0>, socket.AI_NUMERICHOST)<EOL>family = res[<NUM_LIT:0>][<NUM_LIT:0>]<EOL>sockaddr = res[<NUM_LIT:0>][<NUM_LIT:4>]<EOL><DEDENT>except socket.gaierror:<EOL><INDENT>family = None<EOL>sockaddr = None<EOL><DEDENT>if family is not None:<EOL><INDENT>if not port:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>self._dst_service = None<EOL>self._family = family<EOL>self._dst_addrs = [(family, sockaddr)]<EOL>self._set_state("<STR_LIT>")<EOL><DEDENT>elif service is not None:<EOL><INDENT>self._dst_service = service<EOL>self._set_state("<STR_LIT>")<EOL>self._dst_name = addr<EOL><DEDENT>elif port:<EOL><INDENT>self._dst_nameports = [(self._dst_name, self._dst_port)]<EOL>self._dst_service = None<EOL>self._set_state("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>

Same as `connect`, but assumes `lock` acquired.


resolver = self.settings["<STR_LIT>"] <EOL>self._set_state("<STR_LIT>")<EOL>self.event(ResolvingSRVEvent(self._dst_name, self._dst_service))<EOL>resolver.resolve_srv(self._dst_name, self._dst_service, "<STR_LIT>",<EOL>callback = self._got_srv)<EOL>


with self.lock:<EOL><INDENT>if not addrs:<EOL><INDENT>self._dst_service = None<EOL>if self._dst_port:<EOL><INDENT>self._dst_nameports = [(self._dst_name, self._dst_port)]<EOL><DEDENT>else:<EOL><INDENT>self._dst_nameports = []<EOL>self._set_state("<STR_LIT>")<EOL>raise DNSError("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>.format(self._dst_service, self._dst_name))<EOL><DEDENT><DEDENT>elif addrs == [("<STR_LIT:.>", <NUM_LIT:0>)]:<EOL><INDENT>self._dst_nameports = []<EOL>self._set_state("<STR_LIT>")<EOL>raise DNSError("<STR_LIT>"<EOL>.format(self._dst_service, self._dst_name))<EOL><DEDENT>else:<EOL><INDENT>self._dst_nameports = addrs<EOL><DEDENT>self._set_state("<STR_LIT>")<EOL><DEDENT>

Handle SRV lookup result.

        :Parameters:
            - `addrs`: properly sorted list of (hostname, port) tuples


self._set_state("<STR_LIT>")<EOL>resolver = self.settings["<STR_LIT>"] <EOL>logger.debug("<STR_LIT>".format(self._dst_nameports))<EOL>name, port = self._dst_nameports.pop(<NUM_LIT:0>)<EOL>self._dst_hostname = name<EOL>resolver.resolve_address(name, callback = partial(<EOL>self._got_addresses, name, port),<EOL>allow_cname = self._dst_service is None)<EOL>self.event(ResolvingAddressEvent(name))<EOL>

Start hostname resolution for the next name to try.

        [called with `lock` acquired]


def _got_addresses(self, name, port, addrs):

with self.lock:<EOL><INDENT>if not addrs:<EOL><INDENT>if self._dst_nameports:<EOL><INDENT>self._set_state("<STR_LIT>")<EOL>return<EOL><DEDENT>else:<EOL><INDENT>self._dst_addrs = []<EOL>self._set_state("<STR_LIT>")<EOL>raise DNSError("<STR_LIT>"<EOL>.format(name))<EOL><DEDENT><DEDENT>self._dst_addrs = [ (family, (addr, port)) for (family, addr)<EOL>in addrs ]<EOL>self._set_state("<STR_LIT>")<EOL><DEDENT>

Handler DNS address record lookup result.

        :Parameters:
            - `name`: the name requested
            - `port`: port number to connect to
            - `addrs`: list of (family, address) tuples


family, addr = self._dst_addrs.pop(<NUM_LIT:0>)<EOL>self._socket = socket.socket(family, socket.SOCK_STREAM)<EOL>self._socket.setblocking(False)<EOL>self._dst_addr = addr<EOL>self._family  = family<EOL>try:<EOL><INDENT>self._socket.connect(addr)<EOL><DEDENT>except socket.error as err:<EOL><INDENT>logger.debug("<STR_LIT>".format(err))<EOL>if err.args[<NUM_LIT:0>] in BLOCKING_ERRORS:<EOL><INDENT>self._set_state("<STR_LIT>")<EOL>self._write_queue.append(ContinueConnect())<EOL>self._write_queue_cond.notify()<EOL>self.event(ConnectingEvent(addr))<EOL>return<EOL><DEDENT>elif self._dst_addrs:<EOL><INDENT>self._set_state("<STR_LIT>")<EOL>return<EOL><DEDENT>elif self._dst_nameports:<EOL><INDENT>self._set_state("<STR_LIT>")<EOL>return<EOL><DEDENT>else:<EOL><INDENT>self._socket.close()<EOL>self._socket = None<EOL>self._set_state("<STR_LIT>")<EOL>self._write_queue.clear()<EOL>self._write_queue_cond.notify()<EOL>raise<EOL><DEDENT><DEDENT>self._connected()<EOL>

Start connecting to the next address on the `_dst_addrs` list.

        [ called with `lock` acquired ]


self._auth_properties['<STR_LIT>'] = self._dst_addr[<NUM_LIT:0>]<EOL>if self._dst_service:<EOL><INDENT>self._auth_properties['<STR_LIT>'] = self._dst_name<EOL><DEDENT>if self._dst_hostname is not None:<EOL><INDENT>self._auth_properties['<STR_LIT>'] = self._dst_hostname<EOL><DEDENT>else:<EOL><INDENT>self._auth_properties['<STR_LIT>'] = self._dst_addr[<NUM_LIT:0>]<EOL><DEDENT>self._auth_properties['<STR_LIT>'] = None<EOL>self.event(ConnectedEvent(self._dst_addr))<EOL>self._set_state("<STR_LIT>")<EOL>self._stream.transport_connected()<EOL>


try:<EOL><INDENT>self._socket.connect(self._dst_addr)<EOL><DEDENT>except socket.error as err:<EOL><INDENT>logger.debug("<STR_LIT>".format(err))<EOL>if err.args[<NUM_LIT:0>] == errno.EISCONN:<EOL><INDENT>pass<EOL><DEDENT>elif err.args[<NUM_LIT:0>] in BLOCKING_ERRORS:<EOL><INDENT>return None<EOL><DEDENT>elif self._dst_addrs:<EOL><INDENT>self._set_state("<STR_LIT>")<EOL>return None<EOL><DEDENT>elif self._dst_nameports:<EOL><INDENT>self._set_state("<STR_LIT>")<EOL>return None<EOL><DEDENT>else:<EOL><INDENT>self._socket.close()<EOL>self._socket = None<EOL>self._set_state("<STR_LIT>")<EOL>raise<EOL><DEDENT><DEDENT>self._connected()<EOL>

Continue connecting.

        [called with `lock` acquired]

        :Return: `True` when just connected


OUT_LOGGER.debug("<STR_LIT>", data)<EOL>if self._hup or not self._socket:<EOL><INDENT>raise PyXMPPIOError("<STR_LIT>")<EOL><DEDENT>try:<EOL><INDENT>while data:<EOL><INDENT>try:<EOL><INDENT>sent = self._socket.send(data)<EOL><DEDENT>except ssl.SSLError as err:<EOL><INDENT>if err.args[<NUM_LIT:0>] == ssl.SSL_ERROR_WANT_WRITE:<EOL><INDENT>continue<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>except socket.error as err:<EOL><INDENT>if err.args[<NUM_LIT:0>] == errno.EINTR:<EOL><INDENT>continue<EOL><DEDENT>if err.args[<NUM_LIT:0>] in BLOCKING_ERRORS:<EOL><INDENT>wait_for_write(self._socket)<EOL>continue<EOL><DEDENT>raise<EOL><DEDENT>data = data[sent:]<EOL><DEDENT><DEDENT>except (IOError, OSError, socket.error) as err:<EOL><INDENT>raise PyXMPPIOError("<STR_LIT>".format(err))<EOL><DEDENT>

Write raw data to the socket.

        :Parameters:
            - `data`: data to send
        :Types:
            - `data`: `bytes`


with self.lock:<EOL><INDENT>if self._stream:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>self._stream = stream<EOL>self._reader = StreamReader(stream)<EOL><DEDENT>

Make the `stream` the target for this transport instance.

        The 'stream_start', 'stream_end' and 'stream_element' methods
        of the target will be called when appropriate content is received.

        :Parameters:
            - `stream`: the stream handler to receive stream content
              from the transport
        :Types:
            - `stream`: `StreamBase`


def send_stream_head(self, stanza_namespace, stream_from, stream_to,<EOL>stream_id = None, version = '<STR_LIT:1.0>', language = None):

<EOL>with self.lock:<EOL><INDENT>self._serializer = XMPPSerializer(stanza_namespace,<EOL>self.settings["<STR_LIT>"])<EOL>head = self._serializer.emit_head(stream_from, stream_to,<EOL>stream_id, version, language)<EOL>self._write(head.encode("<STR_LIT:utf-8>"))<EOL><DEDENT>

Send stream head via the transport.

:Parameters:
    - `stanza_namespace`: namespace of stream stanzas (e.g.
      'jabber:client')
    - `stream_from`: the 'from' attribute of the stream. May be `None`.
    - `stream_to`: the 'to' attribute of the stream. May be `None`.
    - `version`: the 'version' of the stream.
    - `language`: the 'xml:lang' of the stream
:Types:
    - `stanza_namespace`: `unicode`
    - `stream_from`: `unicode`
    - `stream_to`: `unicode`
    - `version`: `unicode`
    - `language`: `unicode`


self._reader = StreamReader(self._stream)<EOL>self._serializer = None<EOL>

Restart the stream after SASL or StartTLS handshake.


with self.lock:<EOL><INDENT>if not self._socket or self._hup:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return<EOL><DEDENT>data = self._serializer.emit_tail()<EOL>try:<EOL><INDENT>self._write(data.encode("<STR_LIT:utf-8>"))<EOL><DEDENT>except (IOError, SystemError, socket.error) as err:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(err))<EOL><DEDENT>self._serializer = None<EOL>self._hup = True<EOL>if self._tls_state is None:<EOL><INDENT>try:<EOL><INDENT>self._socket.shutdown(socket.SHUT_WR)<EOL><DEDENT>except socket.error:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>self._set_state("<STR_LIT>")<EOL>self._write_queue.clear()<EOL>self._write_queue_cond.notify()<EOL><DEDENT>


with self.lock:<EOL><INDENT>if self._eof or self._socket is None or not self._serializer:<EOL><INDENT>logger.debug("<STR_LIT>".format(<EOL>element_to_unicode(element)))<EOL>return<EOL><DEDENT>data = self._serializer.emit_stanza(element)<EOL>self._write(data.encode("<STR_LIT:utf-8>"))<EOL><DEDENT>


result = HandlerReady()<EOL>logger.debug("<STR_LIT>".format(self._state))<EOL>with self.lock:<EOL><INDENT>if self._state in ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>pass<EOL><DEDENT>elif self._state == "<STR_LIT>":<EOL><INDENT>self._start_connect()<EOL>result = PrepareAgain(None)<EOL><DEDENT>elif self._state == "<STR_LIT>":<EOL><INDENT>self._resolve_hostname()<EOL>result = PrepareAgain(<NUM_LIT:0>)<EOL><DEDENT>elif self._state == "<STR_LIT>":<EOL><INDENT>self._resolve_srv()<EOL>result = PrepareAgain(<NUM_LIT:0>)<EOL><DEDENT>else:<EOL><INDENT>result = PrepareAgain(None)<EOL><DEDENT><DEDENT>logger.debug("<STR_LIT>"<EOL>.format(self._state))<EOL>return result<EOL>

When connecting start the next connection step and schedule
        next `prepare` call, when connected return `HandlerReady()`


with self.lock:<EOL><INDENT>if self._socket is not None:<EOL><INDENT>return self._socket.fileno()<EOL><DEDENT><DEDENT>return None<EOL>

Return file descriptor to poll or select.


return self._socket is not None and not self._eof and (<EOL>self._state in ("<STR_LIT>", "<STR_LIT>")<EOL>or self._state == "<STR_LIT>"<EOL>and self._tls_state == "<STR_LIT>")<EOL>

:Return: `True` when the I/O channel can be read


with self.lock:<EOL><INDENT>while True:<EOL><INDENT>if self._socket is None or self._eof:<EOL><INDENT>return False<EOL><DEDENT>if self._state in ("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>return True<EOL><DEDENT>if self._state == "<STR_LIT>" andself._tls_state == "<STR_LIT>":<EOL><INDENT>return True<EOL><DEDENT>self._state_cond.wait()<EOL><DEDENT><DEDENT>

Stop current thread until the channel is readable.

:Return: `False` if it won't be readable (e.g. is closed)


with self.lock:<EOL><INDENT>return self._socket and bool(self._write_queue)<EOL><DEDENT>

:Return: `False` as currently the data is always written synchronously


with self.lock:<EOL><INDENT>while True:<EOL><INDENT>if self._state in ("<STR_LIT>", "<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>return False<EOL><DEDENT>if self._socket and bool(self._write_queue):<EOL><INDENT>return True<EOL><DEDENT>self._write_queue_cond.wait()<EOL><DEDENT><DEDENT>return False<EOL>

Stop current thread until the channel is writable.

:Return: `False` if it won't be readable (e.g. is closed)


with self.lock:<EOL><INDENT>logger.debug("<STR_LIT>".format(self._write_queue))<EOL>try:<EOL><INDENT>job = self._write_queue.popleft()<EOL><DEDENT>except IndexError:<EOL><INDENT>return<EOL><DEDENT>if isinstance(job, WriteData):<EOL><INDENT>self._do_write(job.data) <EOL><DEDENT>elif isinstance(job, ContinueConnect):<EOL><INDENT>self._continue_connect()<EOL><DEDENT>elif isinstance(job, StartTLS):<EOL><INDENT>self._initiate_starttls(**job.kwargs)<EOL><DEDENT>elif isinstance(job, TLSHandshake):<EOL><INDENT>self._continue_tls_handshake()<EOL><DEDENT>else:<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>".format(job))<EOL><DEDENT><DEDENT>

Handle the 'channel writable' state. E.g. send buffered data via a
socket.


with self.lock:<EOL><INDENT>self.event(TLSConnectingEvent())<EOL>self._write_queue.append(StartTLS(**kwargs))<EOL>self._write_queue_cond.notify()<EOL><DEDENT>

Request a TLS handshake on the socket ans switch
        to encrypted output.
        The handshake will start after any currently buffered data is sent.

        :Parameters:
            - `kwargs`: arguments for :std:`ssl.wrap_socket`


with self.lock:<EOL><INDENT>if not self._socket or self._tls_state != "<STR_LIT>":<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return get_certificate_from_ssl_socket(self._socket)<EOL><DEDENT>

Return the peer certificate.

        :ReturnType: `pyxmpp2.cert.Certificate`


if self._tls_state == "<STR_LIT>":<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>kwargs["<STR_LIT>"] = False<EOL>logger.debug("<STR_LIT>")<EOL>self._socket = ssl.wrap_socket(self._socket, **kwargs)<EOL>self._set_state("<STR_LIT>")<EOL>self._continue_tls_handshake()<EOL>

Initiate starttls handshake over the socket.


try:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>self._socket.do_handshake()<EOL><DEDENT>except ssl.SSLError as err:<EOL><INDENT>if err.args[<NUM_LIT:0>] == ssl.SSL_ERROR_WANT_READ:<EOL><INDENT>self._tls_state = "<STR_LIT>"<EOL>logger.debug("<STR_LIT>")<EOL>self._state_cond.notify()<EOL>return<EOL><DEDENT>elif err.args[<NUM_LIT:0>] == ssl.SSL_ERROR_WANT_WRITE:<EOL><INDENT>self._tls_state = "<STR_LIT>"<EOL>logger.debug("<STR_LIT>")<EOL>self._write_queue.appendleft(TLSHandshake)<EOL>return<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>self._tls_state = "<STR_LIT>"<EOL>self._set_state("<STR_LIT>")<EOL>self._auth_properties['<STR_LIT>'] = "<STR_LIT>"<EOL>if "<STR_LIT>" in CHANNEL_BINDING_TYPES:<EOL><INDENT>try:<EOL><INDENT>tls_unique = self._socket.get_channel_binding("<STR_LIT>")<EOL><DEDENT>except ValueError:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>self._auth_properties['<STR_LIT>'] = {<EOL>"<STR_LIT>": tls_unique}<EOL><DEDENT><DEDENT>try:<EOL><INDENT>cipher = self._socket.cipher()<EOL><DEDENT>except AttributeError:<EOL><INDENT>cipher = "<STR_LIT>"<EOL><DEDENT>cert = get_certificate_from_ssl_socket(self._socket)<EOL>self.event(TLSConnectedEvent(cipher, cert))<EOL>


with self.lock:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>if self._eof or self._socket is None:<EOL><INDENT>return<EOL><DEDENT>if self._state == "<STR_LIT>":<EOL><INDENT>while True:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>self._continue_tls_handshake()<EOL>logger.debug("<STR_LIT>".format(self._tls_state))<EOL>if self._tls_state != "<STR_LIT>":<EOL><INDENT>break<EOL><DEDENT><DEDENT><DEDENT>elif self._tls_state == "<STR_LIT>":<EOL><INDENT>while self._socket and not self._eof:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>try:<EOL><INDENT>data = self._socket.read(<NUM_LIT>)<EOL><DEDENT>except ssl.SSLError as err:<EOL><INDENT>if err.args[<NUM_LIT:0>] == ssl.SSL_ERROR_WANT_READ:<EOL><INDENT>break<EOL><DEDENT>elif err.args[<NUM_LIT:0>] == ssl.SSL_ERROR_WANT_WRITE:<EOL><INDENT>break<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>except socket.error as err:<EOL><INDENT>if err.args[<NUM_LIT:0>] == errno.EINTR:<EOL><INDENT>continue<EOL><DEDENT>elif err.args[<NUM_LIT:0>] in BLOCKING_ERRORS:<EOL><INDENT>break<EOL><DEDENT>elif err.args[<NUM_LIT:0>] == errno.ECONNRESET:<EOL><INDENT>logger.warning("<STR_LIT>")<EOL>data = None<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>self._feed_reader(data)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>while self._socket and not self._eof:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>try:<EOL><INDENT>data = self._socket.recv(<NUM_LIT>)<EOL><DEDENT>except socket.error as err:<EOL><INDENT>if err.args[<NUM_LIT:0>] == errno.EINTR:<EOL><INDENT>continue<EOL><DEDENT>elif err.args[<NUM_LIT:0>] in BLOCKING_ERRORS:<EOL><INDENT>break<EOL><DEDENT>elif err.args[<NUM_LIT:0>] == errno.ECONNRESET:<EOL><INDENT>logger.warning("<STR_LIT>")<EOL>data = None<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>self._feed_reader(data)<EOL><DEDENT><DEDENT><DEDENT>

Handle the 'channel readable' state. E.g. read from a socket.


with self.lock:<EOL><INDENT>if self._state == '<STR_LIT>' and self._dst_addrs:<EOL><INDENT>self._hup = False<EOL>self._set_state("<STR_LIT>")<EOL>return<EOL><DEDENT><DEDENT>self._hup = True<EOL>

Handle the 'channel hungup' state. The handler should not be writable
after this.


with self.lock:<EOL><INDENT>if self._state == '<STR_LIT>' and self._dst_addrs:<EOL><INDENT>self._hup = False<EOL>self._set_state("<STR_LIT>")<EOL>return<EOL><DEDENT>self._socket.close()<EOL>self._socket = None<EOL>self._set_state("<STR_LIT>")<EOL>self._write_queue.clear()<EOL>self._write_queue_cond.notify()<EOL><DEDENT>raise PyXMPPIOError("<STR_LIT>")<EOL>


if self._socket is None:<EOL><INDENT>return<EOL><DEDENT>self._set_state("<STR_LIT>")<EOL>raise PyXMPPIOError("<STR_LIT>")<EOL>


return self._state in ("<STR_LIT>", "<STR_LIT>")and not self._eof and not self._hup<EOL>

Check if the transport is connected.

:Return: `True` if is connected.


logger.debug("<STR_LIT>")<EOL>with self.lock:<EOL><INDENT>if self._socket is None:<EOL><INDENT>if self._state != "<STR_LIT>":<EOL><INDENT>self.event(DisconnectedEvent(self._dst_addr))<EOL>self._set_state("<STR_LIT>")<EOL><DEDENT>return<EOL><DEDENT>if self._hup or not self._serializer:<EOL><INDENT>self._close()<EOL><DEDENT>else:<EOL><INDENT>self.send_stream_tail()<EOL><DEDENT><DEDENT>


with self.lock:<EOL><INDENT>self._close()<EOL><DEDENT>

Close the stream immediately, so it won't expect more events.


if self._state != "<STR_LIT>":<EOL><INDENT>self.event(DisconnectedEvent(self._dst_addr))<EOL>self._set_state("<STR_LIT>")<EOL><DEDENT>if self._socket is None:<EOL><INDENT>return<EOL><DEDENT>try:<EOL><INDENT>self._socket.shutdown(socket.SHUT_RDWR)<EOL><DEDENT>except socket.error:<EOL><INDENT>pass<EOL><DEDENT>self._socket.close()<EOL>self._socket = None<EOL>self._write_queue.clear()<EOL>self._write_queue_cond.notify()<EOL>

Same as `_close` but expects `lock` acquired.


IN_LOGGER.debug("<STR_LIT>", data)<EOL>if data:<EOL><INDENT>self.lock.release() <EOL>try:<EOL><INDENT>self._reader.feed(data)<EOL><DEDENT>finally:<EOL><INDENT>self.lock.acquire()<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self._eof = True<EOL>self.lock.release() <EOL>try:<EOL><INDENT>self._stream.stream_eof()<EOL><DEDENT>finally:<EOL><INDENT>self.lock.acquire()<EOL><DEDENT>if not self._serializer:<EOL><INDENT>if self._state != "<STR_LIT>":<EOL><INDENT>self.event(DisconnectedEvent(self._dst_addr))<EOL>self._set_state("<STR_LIT>")<EOL><DEDENT><DEDENT><DEDENT>

Feed the stream reader with data received.

        [ called with `lock` acquired ]

        If `data` is None or empty, then stream end (peer disconnected) is
        assumed and the stream is closed.

        `lock` is acquired during the operation.

        :Parameters:
            - `data`: data received from the stream socket.
        :Types:
            - `data`: `unicode`


logger.debug("<STR_LIT>".format(event))<EOL>if self._stream:<EOL><INDENT>event.stream = self._stream<EOL><DEDENT>self._event_queue.put(event)<EOL>

Pass an event to the target stream or just log it.


def __init__(self, jid, stanza_route, handlers, settings = None):

if handlers is None:<EOL><INDENT>handlers = []<EOL><DEDENT>if settings is None:<EOL><INDENT>settings = XMPPSettings()<EOL><DEDENT>if "<STR_LIT>" not in settings:<EOL><INDENT>settings["<STR_LIT>"] = jid.resource<EOL><DEDENT>StreamBase.__init__(self, STANZA_CLIENT_NS, stanza_route,<EOL>handlers, settings)<EOL>self.me = JID(jid.local, jid.domain)<EOL>

Initialize the ClientStream object.

        :Parameters:
            - `jid`: local JID.
            - `handlers`: XMPP feature and event handlers
            - `settings`: PyXMPP settings for the stream
        :Types:
            - `jid`: `JID`
            - `settings`: `XMPPSettings`


def initiate(self, transport, to = None):

if to is None:<EOL><INDENT>to = JID(self.me.domain)<EOL><DEDENT>return StreamBase.initiate(self, transport, to)<EOL>

Initiate an XMPP connection over the `transport`.

        :Parameters:
            - `transport`: an XMPP transport instance
            - `to`: peer name (defaults to own jid domain part)


def receive(self, transport, myname = None):

if myname is None:<EOL><INDENT>myname = JID(self.me.domain)<EOL><DEDENT>return StreamBase.receive(self, transport, myname)<EOL>

Receive an XMPP connection over the `transport`.

        :Parameters:
            - `transport`: an XMPP transport instance
            - `myname`: local stream endpoint name (defaults to own jid domain
              part).


StreamBase.fix_out_stanza(self, stanza)<EOL>if self.initiator:<EOL><INDENT>if stanza.from_jid:<EOL><INDENT>stanza.from_jid = None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>if not stanza.from_jid:<EOL><INDENT>stanza.from_jid = self.me<EOL><DEDENT><DEDENT>

Fix outgoing stanza.

        On a client clear the sender JID. On a server set the sender
        address to the own JID if the address is not set yet.


StreamBase.fix_in_stanza(self, stanza)<EOL>if not self.initiator:<EOL><INDENT>if stanza.from_jid != self.peer:<EOL><INDENT>stanza.set_from(self.peer)<EOL><DEDENT><DEDENT>

Fix an incoming stanza.

        Ona server replace the sender address with authorized client JID.


def __init__(self, element = None, from_jid = None, to_jid = None,<EOL>stanza_type = None, stanza_id = None,<EOL>error = None, error_cond = None, return_path = None,<EOL>language = None,<EOL>subject = None, body = None, thread = None):

<EOL>self._subject = None<EOL>self._body = None<EOL>self._thread = None<EOL>if element is None:<EOL><INDENT>element = "<STR_LIT:message>"<EOL><DEDENT>elif not isinstance(element, ElementClass):<EOL><INDENT>raise TypeError("<STR_LIT>" + repr(element))<EOL><DEDENT>Stanza.__init__(self, element, from_jid = from_jid, to_jid = to_jid,<EOL>stanza_type = stanza_type, stanza_id = stanza_id,<EOL>error = error, error_cond = error_cond,<EOL>return_path = return_path, language = language)<EOL>if self.element_name != "<STR_LIT:message>":<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>self._subject_tag = self._ns_prefix + "<STR_LIT>"<EOL>self._body_tag = self._ns_prefix + "<STR_LIT:body>"<EOL>self._thread_tag = self._ns_prefix + "<STR_LIT>"<EOL>if self._element is not None:<EOL><INDENT>self._decode_subelements()<EOL><DEDENT>if subject is not None:<EOL><INDENT>self.subject = subject<EOL><DEDENT>if body is not None:<EOL><INDENT>self.body = body<EOL><DEDENT>if thread is not None:<EOL><INDENT>self.thread = thread<EOL><DEDENT>

Initialize a `Message` object.

        :Parameters:
            - `element`: XML element of this stanza.
            - `from_jid`: sender JID.
            - `to_jid`: recipient JID.
            - `stanza_type`: staza type: one of: "normal", "chat", "headline",
              "error", "groupchat"
            - `stanza_id`: stanza id -- value of stanza's "id" attribute. If
              not given, then unique for the session value is generated.
            - `error_cond`: error condition name. Ignored if `stanza_type`
              is not "error".
            - `language`: default language for the stanza content
            - `subject`: message subject,
            - `body`: message body.
            - `thread`: message thread id.
        :Types:
            - `element`: :etree:`ElementTree.Element`
            - `from_jid`: `JID`
            - `to_jid`: `JID`
            - `stanza_type`: `unicode`
            - `stanza_id`: `unicode`
            - `error`: `pyxmpp.error.StanzaErrorElement`
            - `error_cond`: `unicode`
            - `subject`: `unicode`
            - `body`: `unicode`
            - `thread`: `unicode`
            - `language`: `unicode`


for child in self._element:<EOL><INDENT>if child.tag == self._subject_tag:<EOL><INDENT>self._subject = child.text<EOL><DEDENT>elif child.tag == self._body_tag:<EOL><INDENT>self._body = child.text<EOL><DEDENT>elif child.tag == self._thread_tag:<EOL><INDENT>self._thread = child.text<EOL><DEDENT><DEDENT>


result = Stanza.as_xml(self)<EOL>if self._subject:<EOL><INDENT>child = ElementTree.SubElement(result, self._subject_tag)<EOL>child.text = self._subject<EOL><DEDENT>if self._body:<EOL><INDENT>child = ElementTree.SubElement(result, self._body_tag)<EOL>child.text = self._body<EOL><DEDENT>if self._thread:<EOL><INDENT>child = ElementTree.SubElement(result, self._thread_tag)<EOL>child.text = self._thread<EOL><DEDENT>return result<EOL>

Return the XML stanza representation.

        Always return an independent copy of the stanza XML representation,
        which can be freely modified without affecting the stanza.

        :returntype: :etree:`ElementTree.Element`


result = Message(None, self.from_jid, self.to_jid,<EOL>self.stanza_type, self.stanza_id, self.error,<EOL>self._return_path(), self._subject, self._body,<EOL>self._thread)<EOL>for payload in self._payload:<EOL><INDENT>result.add_payload(payload.copy())<EOL><DEDENT>return result<EOL>

Create a deep copy of the stanza.

        :returntype: `Message`


return self._subject<EOL>

Message subject.

        :Returntype: `unicode`


return self._body<EOL>

Message body.

        :Returntype: `unicode`


return self._thread<EOL>

Thread id.

        :Returntype: `unicode`


if self.stanza_type == "<STR_LIT:error>":<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>msg = Message(stanza_type = "<STR_LIT:error>", from_jid = self.to_jid,<EOL>to_jid = self.from_jid, stanza_id = self.stanza_id,<EOL>error_cond = cond,<EOL>subject = self._subject, body = self._body,<EOL>thread = self._thread)<EOL>if self._payload is None:<EOL><INDENT>self.decode_payload()<EOL><DEDENT>for payload in self._payload:<EOL><INDENT>msg.add_payload(payload.copy())<EOL><DEDENT>return msg<EOL>

Create error response for any non-error message stanza.

        :Parameters:
            - `cond`: error condition name, as defined in XMPP specification.

        :return: new message stanza with the same "id" as self, "from" and
            "to" attributes swapped, type="error" and containing <error />
            element plus payload of `self`.
        :returntype: `Message`


if data is None:<EOL><INDENT>self._settings = {}<EOL><DEDENT>else:<EOL><INDENT>self._settings = dict(data)<EOL><DEDENT>

Create settings, optionally initialized with `data`.

        :Parameters:
            - `data`: initial data
        :Types:
            - `data`: any mapping, including `XMPPSettings`


return len(self._settings)<EOL>


for key in self._settings.iterkeys():<EOL><INDENT>return self[key]<EOL><DEDENT>


return key in self._settings<EOL>

Check if a parameter is set.

        :Parameters:
            - `key`: the parameter name
        :Types:
            - `key`: `unicode`


return self.get(key, required = True)<EOL>

Get a parameter value. Return the default if no value is set
        and the default is provided by PyXMPP.

        :Parameters:
            - `key`: the parameter name
        :Types:
            - `key`: `unicode`


self._settings[unicode(key)] = value<EOL>

Set a parameter value.

        :Parameters:
            - `key`: the parameter name
            - `value`: the new value
        :Types:
            - `key`: `unicode`


del self._settings[key]<EOL>

Unset a parameter value.

        :Parameters:
            - `key`: the parameter name
        :Types:
            - `key`: `unicode`


def get(self, key, local_default = None, required = False):

<EOL>if key in self._settings:<EOL><INDENT>return self._settings[key]<EOL><DEDENT>if local_default is not None:<EOL><INDENT>return local_default<EOL><DEDENT>if key in self._defs:<EOL><INDENT>setting_def = self._defs[key]<EOL>if setting_def.default is not None:<EOL><INDENT>return setting_def.default<EOL><DEDENT>factory = setting_def.factory<EOL>if factory is None:<EOL><INDENT>return None<EOL><DEDENT>value = factory(self)<EOL>if setting_def.cache is True:<EOL><INDENT>setting_def.default = value<EOL><DEDENT>return value<EOL><DEDENT>if required:<EOL><INDENT>raise KeyError(key)<EOL><DEDENT>return local_default<EOL>

Get a parameter value.

        If parameter is not set, return `local_default` if it is not `None`
        or the PyXMPP global default otherwise.

        :Raise `KeyError`: if parameter has no value and no global default

        :Return: parameter value


return self._settings.keys()<EOL>

Return names of parameters set.

        :Returntype: - `list` of `unicode`


return self._settings.items()<EOL>

Return names and values of parameters set.

        :Returntype: - `list` of tuples


for name, setting in self._defs.items():<EOL><INDENT>if sys.version_info.major < <NUM_LIT:3>:<EOL><INDENT>from locale import getpreferredencoding<EOL>encoding = getpreferredencoding()<EOL>name = name.encode(encoding, "<STR_LIT:replace>")<EOL><DEDENT>attr = "<STR_LIT>" + name<EOL>try:<EOL><INDENT>self[setting.name] = getattr(args, attr)<EOL><DEDENT>except AttributeError:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>

Load settings from :std:`ArgumentParser` output.

        :Parameters:
            - `args`: output of argument parsed based on the one
              returned by `get_arg_parser()`


@classmethod<EOL><INDENT>def add_setting(cls, name, type = unicode, default = None, factory = None,<EOL>cache = False, default_d = None, doc = None,<EOL>cmdline_help = None, validator = None, basic = False):<DEDENT>

<EOL>setting_def = _SettingDefinition(name, type, default, factory,<EOL>cache, default_d, doc,<EOL>cmdline_help, validator, basic)<EOL>if name not in cls._defs:<EOL><INDENT>cls._defs[name] = setting_def<EOL>return<EOL><DEDENT>duplicate = cls._defs[name]<EOL>if duplicate.type != setting_def.type:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if duplicate.default != setting_def.default:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if duplicate.factory != setting_def.factory:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>

Add a new setting definition.

        :Parameters:
            - `name`: setting name
            - `type`: setting type object or type description
            - `default`: default value
            - `factory`: default value factory
            - `cache`: if `True` the `factory` will be called only once
              and its value stored as a constant default.
            - `default_d`: description of the default value
            - `doc`: setting documentation
            - `cmdline_help`: command line argument description. When not
              provided then the setting won't be available as a command-line
              option
            - `basic`: when `True` the option is considered a basic option -
              one of those which should usually stay configurable in
              an application.
            - `validator`: function validating command-line option value string
              and returning proper value for the settings objects. Defaults
              to `type`.
        :Types:
            - `name`: `unicode`
            - `type`: type or `unicode`
            - `factory`: a callable
            - `cache`: `bool`
            - `default_d`: `unicode`
            - `doc`: `unicode`
            - `cmdline_help`: `unicode`
            - `basic`: `bool`
            - `validator`: a callable


try:<EOL><INDENT>if sys.version_info.major < <NUM_LIT:3>:<EOL><INDENT>from locale import getpreferredencoding<EOL>encoding = getpreferredencoding()<EOL>value = value.decode(encoding)<EOL><DEDENT>return [x.strip() for x in value.split(u"<STR_LIT:U+002C>")]<EOL><DEDENT>except (AttributeError, TypeError, UnicodeError):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>

Validator for string lists to be used with `add_setting`.


value = int(value)<EOL>if value <= <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return value<EOL>

Positive integer validator to be used with `add_setting`.


value = float(value)<EOL>if value <= <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return value<EOL>

Positive float validator to be used with `add_setting`.


def validate_int_range(value):<EOL><INDENT>"""<STR_LIT>"""<EOL>value = int(value)<EOL>if value >= start and value < stop:<EOL><INDENT>return value<EOL><DEDENT>raise ValueError("<STR_LIT>".format(start, stop))<EOL><DEDENT>return validate_int_range<EOL>

Return an integer range validator to be used with `add_setting`.

        :Parameters:
            - `start`: minimum value for the integer
            - `stop`: the upper bound (maximum value + 1)
        :Types:
            - `start`: `int`
            - `stop`: `int`

        :return: a validator function


@classmethod<EOL><INDENT>def list_all(cls, basic = None):<DEDENT>

if basic is None:<EOL><INDENT>return [s for s in cls._defs]<EOL><DEDENT>else:<EOL><INDENT>return [s.name for s in cls._defs.values() if s.basic == basic]<EOL><DEDENT>

List known settings.

        :Parameters:
            - `basic`: When `True` then limit output to the basic settings,
              when `False` list only the extra settings.


@classmethod<EOL><INDENT>def get_arg_parser(cls, settings = None, option_prefix = u'<STR_LIT>',<EOL>add_help = False):<DEDENT>

<EOL>parser = argparse.ArgumentParser(add_help = add_help,<EOL>prefix_chars = option_prefix[<NUM_LIT:0>])<EOL>if settings is None:<EOL><INDENT>settings = cls.list_all(basic = True)<EOL><DEDENT>if sys.version_info.major < <NUM_LIT:3>:<EOL><INDENT>from locale import getpreferredencoding<EOL>encoding = getpreferredencoding()<EOL>def decode_string_option(value):<EOL><INDENT>"""<STR_LIT>"""<EOL>return value.decode(encoding)<EOL><DEDENT><DEDENT>for name in settings:<EOL><INDENT>if name not in cls._defs:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(name))<EOL>return<EOL><DEDENT>setting = cls._defs[name]<EOL>if not setting.cmdline_help:<EOL><INDENT>logger.debug("<STR_LIT>"<EOL>.format(name))<EOL>return<EOL><DEDENT>if sys.version_info.major < <NUM_LIT:3>:<EOL><INDENT>name = name.encode(encoding, "<STR_LIT:replace>")<EOL><DEDENT>option = option_prefix + name.replace("<STR_LIT:_>", "<STR_LIT:->")<EOL>dest = "<STR_LIT>" + name<EOL>if setting.validator:<EOL><INDENT>opt_type = setting.validator<EOL><DEDENT>elif setting.type is unicode and sys.version_info.major < <NUM_LIT:3>:<EOL><INDENT>opt_type = decode_string_option<EOL><DEDENT>else:<EOL><INDENT>opt_type = setting.type<EOL><DEDENT>if setting.default_d:<EOL><INDENT>default_s = setting.default_d<EOL>if sys.version_info.major < <NUM_LIT:3>:<EOL><INDENT>default_s = default_s.encode(encoding, "<STR_LIT:replace>")<EOL><DEDENT><DEDENT>elif setting.default is not None:<EOL><INDENT>default_s = repr(setting.default)<EOL><DEDENT>else:<EOL><INDENT>default_s = None<EOL><DEDENT>opt_help = setting.cmdline_help<EOL>if sys.version_info.major < <NUM_LIT:3>:<EOL><INDENT>opt_help = opt_help.encode(encoding, "<STR_LIT:replace>")<EOL><DEDENT>if default_s:<EOL><INDENT>opt_help += "<STR_LIT>".format(default_s)<EOL><DEDENT>if opt_type is bool:<EOL><INDENT>opt_action = _YesNoAction<EOL><DEDENT>else:<EOL><INDENT>opt_action = "<STR_LIT:store>"<EOL><DEDENT>parser.add_argument(option,<EOL>action = opt_action,<EOL>default = setting.default,<EOL>type = opt_type,<EOL>help = opt_help,<EOL>metavar = name.upper(),<EOL>dest = dest)<EOL><DEDENT>return parser<EOL>

Make a command-line option parser.

        The returned parser may be used as a parent parser for application
        argument parser.

        :Parameters:
            - `settings`: list of PyXMPP2 settings to consider. By default
              all 'basic' settings are provided.
            - `option_prefix`: custom prefix for PyXMPP2 options. E.g.
              ``'--xmpp'`` to differentiate them from not xmpp-related
              application options.
            - `add_help`: when `True` a '--help' option will be included
              (probably already added in the application parser object)
        :Types:
            - `settings`: list of `unicode`
            - `option_prefix`: `str`
            - `add_help`:

        :return: an argument parser object.
        :returntype: :std:`argparse.ArgumentParser`


if hasattr(ElementTree, '<STR_LIT>'):<EOL><INDENT>return ElementTree.tounicode("<STR_LIT>")<EOL><DEDENT>elif sys.version_info.major < <NUM_LIT:3>:<EOL><INDENT>return unicode(ElementTree.tostring(element))<EOL><DEDENT>else:<EOL><INDENT>return ElementTree.tostring(element, encoding = "<STR_LIT>")<EOL><DEDENT>

Serialize an XML element into a unicode string.

    This should work the same on Python2 and Python3 and with all
    :etree:`ElementTree` implementations.

    :Parameters:
        - `element`: the XML element to serialize
    :Types:
        - `element`: :etree:`ElementTree.Element`


def xml_elements_equal(element1, element2, ignore_level1_cdata = False):

<EOL>if None in (element1, element2) or element1.tag != element2.tag:<EOL><INDENT>return False<EOL><DEDENT>attrs1 = element1.items()<EOL>attrs1.sort()<EOL>attrs2 = element2.items()<EOL>attrs2.sort()<EOL>if not ignore_level1_cdata:<EOL><INDENT>if element1.text != element2.text:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>if attrs1 != attrs2:<EOL><INDENT>return False<EOL><DEDENT>if len(element1) != len(element2):<EOL><INDENT>return False<EOL><DEDENT>for child1, child2 in zip(element1, element2):<EOL><INDENT>if child1.tag != child2.tag:<EOL><INDENT>return False<EOL><DEDENT>if not ignore_level1_cdata:<EOL><INDENT>if element1.text != element2.text:<EOL><INDENT>return False<EOL><DEDENT><DEDENT>if not xml_elements_equal(child1, child2):<EOL><INDENT>return False<EOL><DEDENT><DEDENT>return True<EOL>

Check if two XML elements are equal.

    :Parameters:
        - `element1`: the first element to compare
        - `element2`: the other element to compare
        - `ignore_level1_cdata`: if direct text children of the elements
          should be ignored for the comparision
    :Types:
        - `element1`: :etree:`ElementTree.Element`
        - `element2`: :etree:`ElementTree.Element`
        - `ignore_level1_cdata`: `bool`

    :Returntype: `bool`


<EOL>ts = time.time()<EOL>cur = datetime.datetime.fromtimestamp(ts)<EOL>cur_utc = datetime.datetime.utcfromtimestamp(ts)<EOL>offset = cur - cur_utc<EOL>t = utc<EOL>d = datetime.timedelta(hours = <NUM_LIT:2>)<EOL>while d > _MINUTE:<EOL><INDENT>local = t + offset<EOL>tm = local.timetuple()<EOL>tm = tm[<NUM_LIT:0>:<NUM_LIT:8>] + (<NUM_LIT:0>, )<EOL>ts = time.mktime(tm)<EOL>u = datetime.datetime.utcfromtimestamp(ts)<EOL>diff = u - utc<EOL>if diff < _MINUTE and diff > -_MINUTE:<EOL><INDENT>break<EOL><DEDENT>if diff > _NULLDELTA:<EOL><INDENT>offset -= d<EOL><DEDENT>else:<EOL><INDENT>offset += d<EOL><DEDENT>d //= <NUM_LIT:2><EOL><DEDENT>return local<EOL>

An ugly hack to convert naive :std:`datetime.datetime` object containing
UTC time to a naive :std:`datetime.datetime` object with local time.
It seems standard Python 2.3 library doesn't provide any better way to
do that.


timestamp = time.mktime(local.timetuple())<EOL>return datetime.datetime.utcfromtimestamp(timestamp)<EOL>

Simple function to convert naive :std:`datetime.datetime` object containing
local time to a naive :std:`datetime.datetime` object with UTC time.


if settings is None:<EOL><INDENT>settings = XMPPSettings()<EOL><DEDENT>self.settings = settings<EOL>self.peer_sasl_mechanisms = None<EOL>self.authenticator = None<EOL>


def make_stream_features(self, stream, features):

mechs = self.settings['<STR_LIT>']<EOL>if mechs and not stream.authenticated:<EOL><INDENT>sub = ElementTree.SubElement(features, MECHANISMS_TAG)<EOL>for mech in mechs:<EOL><INDENT>if mech in sasl.SERVER_MECHANISMS:<EOL><INDENT>ElementTree.SubElement(sub, MECHANISM_TAG).text = mech<EOL><DEDENT><DEDENT><DEDENT>return features<EOL>

Add SASL features to the <features/> element of the stream.

        [receving entity only]

        :returns: update <features/> element.


def handle_stream_features(self, stream, features):

element = features.find(MECHANISMS_TAG)<EOL>self.peer_sasl_mechanisms = []<EOL>if element is None:<EOL><INDENT>return None<EOL><DEDENT>for sub in element:<EOL><INDENT>if sub.tag != MECHANISM_TAG:<EOL><INDENT>continue<EOL><DEDENT>self.peer_sasl_mechanisms.append(sub.text)<EOL><DEDENT>if stream.authenticated or not self.peer_sasl_mechanisms:<EOL><INDENT>return StreamFeatureNotHandled("<STR_LIT>", mandatory = True)<EOL><DEDENT>username = self.settings.get("<STR_LIT:username>")<EOL>if not username:<EOL><INDENT>if stream.me.local:<EOL><INDENT>username = stream.me.local<EOL><DEDENT>else:<EOL><INDENT>username = None<EOL><DEDENT><DEDENT>self._sasl_authenticate(stream, username, self.settings.get("<STR_LIT>"))<EOL>return StreamFeatureHandled("<STR_LIT>", mandatory = True)<EOL>

Process incoming <stream:features/> element.

        [initiating entity only]


@stream_element_handler(AUTH_TAG, "<STR_LIT>")<EOL><INDENT>def process_sasl_auth(self, stream, element):<DEDENT>

if self.authenticator:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return False<EOL><DEDENT>password_db = self.settings["<STR_LIT>"]<EOL>mechanism = element.get("<STR_LIT>")<EOL>if not mechanism:<EOL><INDENT>stream.send_stream_error("<STR_LIT>")<EOL>raise FatalStreamError("<STR_LIT>")<EOL><DEDENT>stream.auth_method_used = mechanism<EOL>self.authenticator = sasl.server_authenticator_factory(mechanism,<EOL>password_db)<EOL>content = element.text.encode("<STR_LIT>")<EOL>ret = self.authenticator.start(stream.auth_properties,<EOL>a2b_base64(content))<EOL>if isinstance(ret, sasl.Success):<EOL><INDENT>element = ElementTree.Element(SUCCESS_TAG)<EOL>element.text = ret.encode()<EOL><DEDENT>elif isinstance(ret, sasl.Challenge):<EOL><INDENT>element = ElementTree.Element(CHALLENGE_TAG)<EOL>element.text = ret.encode()<EOL><DEDENT>else:<EOL><INDENT>element = ElementTree.Element(FAILURE_TAG)<EOL>ElementTree.SubElement(element, SASL_QNP + ret.reason)<EOL><DEDENT>stream.write_element(element)<EOL>if isinstance(ret, sasl.Success):<EOL><INDENT>self._handle_auth_success(stream, ret)<EOL><DEDENT>elif isinstance(ret, sasl.Failure):<EOL><INDENT>raise SASLAuthenticationFailed("<STR_LIT>"<EOL>.format(ret.reason))<EOL><DEDENT>return True<EOL>

Process incoming <sasl:auth/> element.

        [receiving entity only]


def _handle_auth_success(self, stream, success):

if not self._check_authorization(success.properties, stream):<EOL><INDENT>element = ElementTree.Element(FAILURE_TAG)<EOL>ElementTree.SubElement(element, SASL_QNP + "<STR_LIT>")<EOL>return True<EOL><DEDENT>authzid = success.properties.get("<STR_LIT>")<EOL>if authzid:<EOL><INDENT>peer = JID(success.authzid)<EOL><DEDENT>elif "<STR_LIT:username>" in success.properties:<EOL><INDENT>peer = JID(success.properties["<STR_LIT:username>"], stream.me.domain)<EOL><DEDENT>else:<EOL><INDENT>peer = None<EOL><DEDENT>stream.set_peer_authenticated(peer, True)<EOL>

Handle successful authentication.

        Send <success/> and mark the stream peer authenticated.

        [receiver only]


@stream_element_handler(CHALLENGE_TAG, "<STR_LIT>")<EOL><INDENT>def _process_sasl_challenge(self, stream, element):<DEDENT>

if not self.authenticator:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return False<EOL><DEDENT>content = element.text.encode("<STR_LIT>")<EOL>ret = self.authenticator.challenge(a2b_base64(content))<EOL>if isinstance(ret, sasl.Response):<EOL><INDENT>element = ElementTree.Element(RESPONSE_TAG)<EOL>element.text = ret.encode()<EOL><DEDENT>else:<EOL><INDENT>element = ElementTree.Element(ABORT_TAG)<EOL><DEDENT>stream.write_element(element)<EOL>if isinstance(ret, sasl.Failure):<EOL><INDENT>stream.disconnect()<EOL>raise SASLAuthenticationFailed("<STR_LIT>")<EOL><DEDENT>return True<EOL>

Process incoming <sasl:challenge/> element.

        [initiating entity only]


@stream_element_handler(RESPONSE_TAG, "<STR_LIT>")<EOL><INDENT>def _process_sasl_response(self, stream, element):<DEDENT>

if not self.authenticator:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return False<EOL><DEDENT>content = element.text.encode("<STR_LIT>")<EOL>ret = self.authenticator.response(a2b_base64(content))<EOL>if isinstance(ret, sasl.Success):<EOL><INDENT>element = ElementTree.Element(SUCCESS_TAG)<EOL>element.text = ret.encode()<EOL><DEDENT>elif isinstance(ret, sasl.Challenge):<EOL><INDENT>element = ElementTree.Element(CHALLENGE_TAG)<EOL>element.text = ret.encode()<EOL><DEDENT>else:<EOL><INDENT>element = ElementTree.Element(FAILURE_TAG)<EOL>ElementTree.SubElement(element, SASL_QNP + ret.reason)<EOL><DEDENT>stream.write_element(element)<EOL>if isinstance(ret, sasl.Success):<EOL><INDENT>self._handle_auth_success(stream, ret)<EOL><DEDENT>elif isinstance(ret, sasl.Failure):<EOL><INDENT>raise SASLAuthenticationFailed("<STR_LIT>"<EOL>.format(ret.reson))<EOL><DEDENT>return True<EOL>

Process incoming <sasl:response/> element.

        [receiving entity only]


def _check_authorization(self, properties, stream):

authzid = properties.get("<STR_LIT>")<EOL>if not authzid:<EOL><INDENT>return True<EOL><DEDENT>try:<EOL><INDENT>jid = JID(authzid)<EOL><DEDENT>except ValueError:<EOL><INDENT>return False<EOL><DEDENT>if "<STR_LIT:username>" not in properties:<EOL><INDENT>result = False<EOL><DEDENT>elif jid.local != properties["<STR_LIT:username>"]:<EOL><INDENT>result = False<EOL><DEDENT>elif jid.domain != stream.me.domain:<EOL><INDENT>result = False<EOL><DEDENT>elif jid.resource:<EOL><INDENT>result = False<EOL><DEDENT>else:<EOL><INDENT>result = True<EOL><DEDENT>return result<EOL>

Check authorization id and other properties returned by the
        authentication mechanism.

        [receiving entity only]

        Allow only no authzid or authzid equal to current username@domain

        FIXME: other rules in s2s

        :Parameters:
            - `properties`: data obtained during authentication
        :Types:
            - `properties`: mapping

        :return: `True` if user is authorized to use a provided authzid
        :returntype: `bool`


@stream_element_handler(SUCCESS_TAG, "<STR_LIT>")<EOL><INDENT>def _process_sasl_success(self, stream, element):<DEDENT>

if not self.authenticator:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return False<EOL><DEDENT>content = element.text<EOL>if content:<EOL><INDENT>data = a2b_base64(content.encode("<STR_LIT>"))<EOL><DEDENT>else:<EOL><INDENT>data = None<EOL><DEDENT>ret = self.authenticator.finish(data)<EOL>if isinstance(ret, sasl.Success):<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>authzid = ret.properties.get("<STR_LIT>")<EOL>if authzid:<EOL><INDENT>me = JID(authzid)<EOL><DEDENT>elif "<STR_LIT:username>" in ret.properties:<EOL><INDENT>me = JID(ret.properties["<STR_LIT:username>"], stream.peer.domain)<EOL><DEDENT>else:<EOL><INDENT>me = None<EOL><DEDENT>stream.set_authenticated(me, True)<EOL><DEDENT>else:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>raise SASLAuthenticationFailed("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>return True<EOL>

Process incoming <sasl:success/> element.

        [initiating entity only]


@stream_element_handler(FAILURE_TAG, "<STR_LIT>")<EOL><INDENT>def _process_sasl_failure(self, stream, element):<DEDENT>

_unused = stream<EOL>if not self.authenticator:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return False<EOL><DEDENT>logger.debug("<STR_LIT>".format(<EOL>element_to_unicode(element)))<EOL>raise SASLAuthenticationFailed("<STR_LIT>")<EOL>

Process incoming <sasl:failure/> element.

        [initiating entity only]


@stream_element_handler(ABORT_TAG, "<STR_LIT>")<EOL><INDENT>def _process_sasl_abort(self, stream, element):<DEDENT>

_unused, _unused = stream, element<EOL>if not self.authenticator:<EOL><INDENT>logger.debug("<STR_LIT>")<EOL>return False<EOL><DEDENT>self.authenticator = None<EOL>logger.debug("<STR_LIT>")<EOL>return True<EOL>

Process incoming <sasl:abort/> element.

        [receiving entity only]


def _sasl_authenticate(self, stream, username, authzid):

if not stream.initiator:<EOL><INDENT>raise SASLAuthenticationFailed("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>if stream.features is None or not self.peer_sasl_mechanisms:<EOL><INDENT>raise SASLNotAvailable("<STR_LIT>")<EOL><DEDENT>props = dict(stream.auth_properties)<EOL>if not props.get("<STR_LIT>") and (<EOL>stream.peer and stream.peer.domain):<EOL><INDENT>props["<STR_LIT>"] = stream.peer.domain<EOL><DEDENT>if username is not None:<EOL><INDENT>props["<STR_LIT:username>"] = username<EOL><DEDENT>if authzid is not None:<EOL><INDENT>props["<STR_LIT>"] = authzid<EOL><DEDENT>if "<STR_LIT:password>" in self.settings:<EOL><INDENT>props["<STR_LIT:password>"] = self.settings["<STR_LIT:password>"]<EOL><DEDENT>props["<STR_LIT>"] = self.peer_sasl_mechanisms<EOL>enabled = sasl.filter_mechanism_list(<EOL>self.settings['<STR_LIT>'], props,<EOL>self.settings['<STR_LIT>'])<EOL>if not enabled:<EOL><INDENT>raise SASLNotAvailable(<EOL>"<STR_LIT>")<EOL><DEDENT>props["<STR_LIT>"] = enabled<EOL>mechanism = None<EOL>for mech in enabled:<EOL><INDENT>if mech in self.peer_sasl_mechanisms:<EOL><INDENT>mechanism = mech<EOL>break<EOL><DEDENT><DEDENT>if not mechanism:<EOL><INDENT>raise SASLMechanismNotAvailable("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>logger.debug("<STR_LIT>".format(mechanism))<EOL>stream.auth_method_used = mechanism<EOL>self.authenticator = sasl.client_authenticator_factory(mechanism)<EOL>initial_response = self.authenticator.start(props)<EOL>if not isinstance(initial_response, sasl.Response):<EOL><INDENT>raise SASLAuthenticationFailed("<STR_LIT>")<EOL><DEDENT>element = ElementTree.Element(AUTH_TAG)<EOL>element.set("<STR_LIT>", mechanism)<EOL>if initial_response.data:<EOL><INDENT>if initial_response.encode:<EOL><INDENT>element.text = initial_response.encode()<EOL><DEDENT>else:<EOL><INDENT>element.text = initial_response.data<EOL><DEDENT><DEDENT>stream.write_element(element)<EOL>

Start SASL authentication process.

        [initiating entity only]

        :Parameters:
            - `username`: user name.
            - `authzid`: authorization ID.
            - `mechanism`: SASL mechanism to use.


def __init__(self, element_or_cond, text = None, language = None):

self.text = None<EOL>self.custom_condition = []<EOL>self.language = language<EOL>if isinstance(element_or_cond, str):<EOL><INDENT>self.condition = ElementTree.Element(self.cond_qname_prefix<EOL>+ element_or_cond)<EOL><DEDENT>elif not isinstance(element_or_cond, ElementClass):<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>self._from_xml(element_or_cond)<EOL><DEDENT>if text:<EOL><INDENT>self.text = text<EOL><DEDENT>

Initialize an StanzaErrorElement object.

        :Parameters:
            - `element_or_cond`: XML <error/> element to decode or an error
              condition name or element.
            - `text`: optional description to override the default one
            - `language`: RFC 3066 language tag for the description
        :Types:
            - `element_or_cond`: :etree:`ElementTree.Element` or `unicode`
            - `text`: `unicode`
            - `language`: `unicode`