protocol
— XML Stream implementation¶
This module contains the XMLStream
class, which implements the XML
stream protocol used by XMPP. It makes extensive use of the aioxmpp.xml
module and the aioxmpp.xso
subpackage to parse and serialize XSOs
received and sent on the stream.
In addition, helper functions to work with XMLStream
instances are
provided; these are not included in the class itself because they provide
additional functionality solely based on the public interface of the
class. Separating them helps with testing.
-
class
aioxmpp.protocol.
XMLStream
(to, features_future=None, sorted_attributes=False, base_logger=<Logger aioxmpp (WARNING)>, default_namespace='jabber:client', from_=None, loop=None)[source]¶ XML stream implementation. This is an streaming
asyncio.Protocol
which translates the received bytes into XSOs.- Parameters
to (
JID
) – Domain of the server the stream connects to.features_future (
asyncio.Future
) – Usefeatures_future()
instead.sorted_attributes (
bool
) – Sort attributes deterministically on output (debug option; not part of the public interface)default_namespace (
str
) – Set the default namespace to advertise on the stream header.from – The value of the from attribute of the stream header.
base_logger (
logging.Logger
) – Parent logger for this stream
- Tpye fromfrom_
to must identify the remote server to connect to. This is used as the
to
attribute on the stream header.features_future may be a future. The XML stream will set the first
StreamFeatures
node it receives as the result of the future. The future will also receive any pre-stream-features exception.sorted_attributes is a testing/debugging option to enable sorted output of the XML attributes emitted on the stream. See
XMPPXMLGenerator
for details. Do not use outside of unit testing code, as it has a negative performance impact.base_logger may be a
logging.Logger
instance to use. The XML stream will create a child calledXMLStream
at that logger and use that child for logging purposes. This eases debugging and allows for connection-specific loggers.Deprecated since version 0.12: Using features_future as positional or keyword argument is deprecated and will be removed in version 1.0. Use
features_future()
to obtain a future instead.Receiving XSOs:
-
stanza_parser
¶ A
XSOParser
instance which is wired to aXMPPXMLProcessor
which processes the received bytes.To receive XSOs over the XML stream, use
stanza_parser
and register class callbacks on it usingadd_class()
.
-
error_handler
¶ This should be assigned a callable, taking two arguments: a
xso.XSO
instance, which is the partial(!) top-level stream element and an exception indicating the failure.Partial here means that it is not guaranteed that anything but the attributes on the partial XSO itself are there. Any children or text payload is most likely missing, as it probably caused the error.
New in version 0.4.
Sending XSOs:
-
send_xso
(obj)[source]¶ Send an XSO over the stream.
- Parameters
obj (
XSO
) – The object to send.- Raises
ConnectionError – if the connection is not fully established yet.
aioxmpp.errors.StreamError – if a stream error was received or sent.
OSError – if the stream got disconnected due to a another permanent transport error
Exception – if serialisation of obj failed
Calling
send_xso()
while the stream is disconnected, disconnecting or still waiting for the remote to send a stream header causesConnectionError
to be raised. If the stream got disconnected due to a transport or stream error, that exception is re-raised instead of theConnectionError
.Changed in version 0.9: Exceptions occurring during serialisation of obj are re-raised and no content is sent over the stream. The stream is still valid and usable afterwards.
Manipulating stream state:
-
async
starttls
(ssl_context, post_handshake_callback=None)[source]¶ Start TLS on the transport and wait for it to complete.
The ssl_context and post_handshake_callback arguments are forwarded to the transports
aioopenssl.STARTTLSTransport.starttls()
coroutine method.If the transport does not support starttls,
RuntimeError
is raised; support for starttls can be discovered by queryingcan_starttls()
.After
starttls()
returns, you must callreset()
. Any other method may fail in interesting ways as the internal state is discarded when starttls succeeds, for security reasons.reset()
re-creates the internal structures.
-
reset
()[source]¶ Reset the stream by discarding all state and re-sending the stream header.
Calling
reset()
when the stream is disconnected or currently disconnecting results in eitherConnectionError
being raised or the exception which caused the stream to die (possibly a received stream error or a transport error) to be reraised.reset()
puts the stream intoSTREAM_HEADER_SENT
state and it cannot be used for sending XSOs until the peer stream header has been received. Usually, this is not a problem as stream resets only occur during stream negotiation and stream negotiation typically waits for the peers feature node to arrive first.
-
close
()[source]¶ Close the XML stream and the underlying transport.
This gracefully shuts down the XML stream and the transport, if possible by writing the eof using
asyncio.Transport.write_eof()
after sending the stream footer.After a call to
close()
, no other stream manipulating or sending method can be called; doing so will result in aConnectionError
exception or any exception caused by the transport during shutdown.Calling
close()
while the stream is closing or closed is a no-op.
-
abort
()[source]¶ Abort the stream by writing an EOF if possible and closing the transport.
The transport is closed using
asyncio.BaseTransport.close()
, so buffered data is sent, but no more data will be received. The stream is inState.CLOSED
state afterwards.This also works if the stream is currently closing, that is, waiting for the peer to send a stream footer. In that case, the stream will be closed locally as if the stream footer had been received.
New in version 0.5.
Controlling debug output:
-
mute
()[source]¶ A context-manager which prohibits logging of data sent over the stream.
Data sent over the stream is replaced with
<!-- some bytes omitted -->
. This is mainly useful during authentication.
Waiting for stream state changes:
-
error_future
()[source]¶ Return a future which will receive the next XML stream error as exception.
It is safe to cancel the future at any time.
-
features_future
()[source]¶ Return a future which will receive the next XML stream features (as return value) or the next XML stream error (as exception), whichever happens first.
It is safe to cancel this future at any time.
Monitoring stream aliveness:
-
deadtime_soft_limit
¶ This is part of the timeout handling of
XMLStream
objects. The timeout handling works like this:There exist two timers, soft and hard limit.
Reception of any data resets both timers.
When the soft limit timer is triggered, the
on_deadtime_soft_limit_tripped()
signal is emitted. Nothing else happens. The user is expected to do something which would cause the server to send data to prevent the hard limit from tripping.When the hard limit timer is triggered, the stream is considered dead and it is aborted and closed with an appropriate
ConnectionError
.
This attribute controls the timeout for the soft limit timer, as
datetime.timedelta
. The default isNone
, which disables the timer altogether.New in version 0.10.
-
deadtime_hard_limit
¶ This is part of the timeout handling of
XMLStream
objects. Seedeadtime_soft_limit
for details.This attribute controls the timeout for the hard limit timer, as
datetime.timedelta
. The default isNone
, which disables the timer altogether.Setting the hard limit timer to
None
means that theXMLStream
will never timeout by itself.New in version 0.10.
Signals:
-
signal
on_closing
(reason)¶ A
Signal
which fires when the underlying transport of the stream reports an error or when a stream error is received. The signal is fired with the corresponding exception as the only argument.If the stream gets closed by the application without any error, the argument is
None
.By the time the callback fires, the stream is already unusable for sending stanzas. It may however still receive stanzas, if the stream shutdown was initiated by the application and the peer has not yet send its stream footer.
If the application is not able to handle these stanzas, it is legitimate to disconnect their handlers from the
stanza_parser
; the stream will be able to deal with unhandled top level stanzas correctly at this point (by ignoring them).
-
signal
on_deadtime_soft_limit_tripped
()¶ Emits when the soft limit dead time has been exceeded.
See
deadtime_soft_limit
for general information on the timeout handling.New in version 0.10.
Timeouts:
-
shutdown_timeout
¶ The maximum time to wait for the peer
</stream:stream>
before forcing to close the transport and considering the stream closed.
Utilities for XML streams¶
Enumerations¶
-
class
aioxmpp.protocol.
Mode
(value)[source]¶ Possible modes of connection for an XML stream. These define the namespaces used.
-
C2S
¶ A client stream connected to a server. This is the default mode and, currently, the only available mode.
-
-
class
aioxmpp.protocol.
State
(value)[source]¶ The possible states of a
XMLStream
:-
READY
¶ The initial state; this is the case when no underlying transport is connected.
-
STREAM_HEADER_SENT
¶ After a
asyncio.Transport
callsXMLStream.connection_made()
on the xml stream, it sends the stream header and enters this state.
-
OPEN
¶ When the stream header of the peer is received, this state is entered and the XML stream can be used for sending and receiving XSOs.
-
CLOSING
¶ After
XMLStream.close()
is called, this state is entered. We sent a stream footer and an EOF, if the underlying transport supports this. We still have to wait for the peer to close the stream.In this state and all following states,
ConnectionError
instances are raised whenever an attempt is made to write to the stream. The exact instance depends on the reason of the closure.In this state, the stream waits for the remote to send a stream footer and the connection to shut down. For application purposes, the stream is already closed.
-
CLOSING_STREAM_FOOTER_RECEIVED
¶ At this point, the stream is properly closed on the XML stream level. This is the point where
XMLStream.close_and_wait()
returns.
-
CLOSED
¶ This state is entered when the connection is lost in any way. This is the final state.
-