pontarius-xmpp- An incomplete implementation of RFC 6120 (XMPP: Core)

Safe HaskellNone




The Extensible Messaging and Presence Protocol (XMPP) is an open technology for near-real-time communication, which powers a wide range of applications including instant messaging, presence, multi-party chat, voice and video calls, collaboration, lightweight middleware, content syndication, and generalized routing of XML data. XMPP provides a technology for the asynchronous, end-to-end exchange of structured data by means of direct, persistent XML streams among a distributed network of globally addressable, presence-aware clients and servers.

Pontarius XMPP is an XMPP client library, implementing the core capabilities of XMPP (RFC 6120): setup and teardown of XML streams, channel encryption, authentication, error handling, and communication primitives for messaging.

For low-level access to Pontarius XMPP, see the Network.Xmpp.Internal module.


Session management

data Session Source

A concurrent interface to Pontarius XMPP.



:: HostName

The hostname / realm

-> SessionConfiguration

configuration details

-> Maybe ([SaslHandler], Maybe Text)

SASL handlers and the desired JID resource (or Nothing to let the server decide)

-> IO (Either XmppFailure Session) 

Creates a Session object by setting up a connection with an XMPP server.

Will connect to the specified host with the provided configuration. If the third parameter is a Just value, session will attempt to authenticate and acquire an XMPP resource.

data StreamConfiguration Source

Configuration settings related to the stream.




preferredLang :: !(Maybe LangTag)

Default language when no language tag is set

toJid :: !(Maybe (Jid, Bool))

JID to include in the stream element's to attribute when the connection is secured; if the boolean is set to True, then the JID is also included when the ConnectionState is Plain

socketDetails :: Maybe (Socket, SockAddr)

By settings this field, clients can specify the network interface to use, override the SRV lookup of the realm, as well as specify the use of a non-standard port when connecting by IP or connecting to a domain without SRV records.

resolvConf :: ResolvConf

DNS resolver configuration

establishSession :: Bool

Whether or not to perform the legacy session bind as defined in the (outdated) RFC 3921 specification

tlsBehaviour :: TlsBehaviour

How the client should behave in regards to TLS.

tlsParams :: TLSParams

Settings to be used for TLS negotitation

data SessionConfiguration Source

Configuration for the Session object.




sessionStreamConfiguration :: StreamConfiguration

Configuration for the Stream object.

sessionClosedHandler :: XmppFailure -> IO ()

Handler to be run when the session ends (for whatever reason).

sessionStanzaIDs :: IO (IO StanzaID)

Function to generate the stream of stanza identifiers.

extraStanzaHandlers :: [StanzaHandler]

Authentication handlers

The use of scramSha1 is recommended, but digestMd5 might be useful for interaction with older implementations.



:: Text


-> Maybe Text

authorization ID

-> Text


-> SaslHandler 



:: Text

authentication ID (username)

-> Maybe Text

authorization ID

-> Text


-> SaslHandler 



:: Text

Authentication identity (authcid or username)

-> Maybe Text

Authorization identity (authzid)

-> Text


-> SaslHandler 


A JID (historically: Jabber ID) is XMPPs native format for addressing entities in the network. It is somewhat similar to an e-mail address, but contains three parts instead of two.

data Jid Source

A JID is XMPP's native format for addressing entities in the network. It is somewhat similar to an e-mail address but contains three parts instead of two.




localpart :: !(Maybe Text)

The localpart of a JID is an optional identifier placed before the domainpart and separated from the latter by a '@' character. Typically a localpart uniquely identifies the entity requesting and using network access provided by a server (i.e., a local account), although it can also represent other kinds of entities (e.g., a chat room associated with a multi-user chat service). The entity represented by an XMPP localpart is addressed within the context of a specific domain (i.e., localpart@domainpart).

domainpart :: !Text

The domainpart typically identifies the home server to which clients connect for XML routing and data management functionality. However, it is not necessary for an XMPP domainpart to identify an entity that provides core XMPP server functionality (e.g., a domainpart can identify an entity such as a multi-user chat service, a publish-subscribe service, or a user directory).

resourcepart :: !(Maybe Text)

The resourcepart of a JID is an optional identifier placed after the domainpart and separated from the latter by the '/' character. A resourcepart can modify either a localpart@domainpart address or a mere domainpart address. Typically a resourcepart uniquely identifies a specific connection (e.g., a device or location) or object (e.g., an occupant in a multi-user chat room) belonging to the entity associated with an XMPP localpart at a domain (i.e., localpart@domainpart/resourcepart).


isBare :: Jid -> BoolSource

Returns True if the JID is bare, and False otherwise.

isFull :: Jid -> BoolSource

Returns True if the JID is full, and False otherwise.

jidFromText :: Text -> Maybe JidSource

Converts a Text to a JID.

jidFromTexts :: Maybe Text -> Text -> Maybe Text -> Maybe JidSource

Converts localpart, domainpart, and resourcepart strings to a JID. Runs the appropriate stringprep profiles and validates the parts.


The basic protocol data unit in XMPP is the XML stanza. The stanza is essentially a fragment of XML that is sent over a stream. Stanzas come in 3 flavors:

  • Message, for traditional push-style message passing between peers
  • Presence, for communicating status updates
  • Info/Query (or IQ), for request-response semantics communication

All stanza types have the following attributes in common:

  • The id attribute is used by the originating entity to track any response or error stanza that it might receive in relation to the generated stanza from another entity (such as an intermediate server or the intended recipient). It is up to the originating entity whether the value of the id attribute is unique only within its current stream or unique globally.
  • The from attribute specifies the JID of the sender.
  • The to attribute specifies the JID of the intended recipient for the stanza.
  • The type attribute specifies the purpose or context of the message, presence, or IQ stanza. The particular allowable values for the 'type' attribute vary depending on whether the stanza is a message, presence, or IQ stanza.


The message stanza is a push mechanism whereby one entity pushes information to another entity, similar to the communications that occur in a system such as email. It is not to be confused with instant messaging which is handled in the IM module

data Message Source

The message stanza. Used for push type communication.


data MessageType Source

The type of a Message being sent (http://xmpp.org/rfcs/rfc6121.html#message-syntax-type)



The message is sent in the context of a one-to-one chat session. Typically an interactive client will present a message of type chat in an interface that enables one-to-one chat between the two parties, including an appropriate conversation history.


The message is sent in the context of a multi-user chat environment (similar to that of IRC). Typically a receiving client will present a message of type groupchat in an interface that enables many-to-many chat between the parties, including a roster of parties in the chatroom and an appropriate conversation history.


The message provides an alert, a notification, or other transient information to which no reply is expected (e.g., news headlines, sports updates, near-real-time market data, or syndicated content). Because no reply to the message is expected, typically a receiving client will present a message of type headline in an interface that appropriately differentiates the message from standalone messages, chat messages, and groupchat messages (e.g., by not providing the recipient with the ability to reply).


The message is a standalone message that is sent outside the context of a one-to-one conversation or groupchat, and to which it is expected that the recipient will reply. Typically a receiving client will present a message of type normal in an interface that enables the recipient to reply, but without a conversation history.

This is the default value.


answerMessage :: Message -> [Element] -> Maybe MessageSource

Produce an answer message with the given payload, switching the from and to attributes in the original message. Produces a Nothing value of the provided message message has no from attribute.


sendMessage :: Message -> Session -> IO ()Source

Send a message stanza.


pullMessage :: Session -> IO (Either MessageError Message)Source

Read an element from the inbound stanza channel, discardes any non-Message stanzas from the channel

getMessage :: Session -> IO MessageSource

Get the next received message

waitForMessage :: (Message -> Bool) -> Session -> IO MessageSource

Pulls a (non-error) message and returns it if the given predicate returns True.

waitForMessageError :: (MessageError -> Bool) -> Session -> IO MessageErrorSource

Pulls an error message and returns it if the given predicate returns True.

filterMessages :: (MessageError -> Bool) -> (Message -> Bool) -> Session -> IO (Either MessageError Message)Source

Pulls a message and returns it if the given predicate returns True.


XMPP includes the ability for an entity to advertise its network availability, or presence, to other entities. In XMPP, this availability for communication is signaled end-to-end by means of a dedicated communication primitive: the presence stanza.

data Presence Source

The presence stanza. Used for communicating status updates.


data PresenceType Source

PresenceType holds Xmpp presence types. The error message type is left out as errors are using PresenceError.



Sender wants to subscribe to presence


Sender has approved the subscription


Sender is unsubscribing from presence


Sender has denied or cancelled a subscription


Sender requests current presence; should only be used by servers



presTo :: Presence -> Jid -> PresenceSource

Add a recipient to a presence notification.


Sends a presence stanza. In general, the presence stanza should have no to attribute, in which case the server to which the client is connected will broadcast that stanza to all subscribed entities. However, a publishing client may also send a presence stanza with a to attribute, in which case the server will route or deliver that stanza to the intended recipient.

sendPresence :: Presence -> Session -> IO ()Source

Send a presence stanza.


pullPresence :: Session -> IO (Either PresenceError Presence)Source

Read an element from the inbound stanza channel, discardes any non-Presence stanzas from the channel

waitForPresence :: (Presence -> Bool) -> Session -> IO PresenceSource

Pulls a (non-error) presence and returns it if the given predicate returns True.


Info/Query, or IQ, is a request-response mechanism, similar in some ways to the Hypertext Transfer Protocol HTTP. The semantics of IQ enable an entity to make a request of, and receive a response from, another entity. The data content and precise semantics of the request and response is defined by the schema or other structural definition associated with the XML namespace that qualifies the direct child element of the IQ element. IQ interactions follow a common pattern of structured data exchange such as get/result or set/result (although an error can be returned in reply to a request if appropriate)


data IQRequest Source

A request Info/Query (IQ) stanza is one with either get or set as type. It always contains an xml payload.


data IQRequestTicket Source

Contains whether or not a reply has been sent, and the IQ request body to reply to.

data IQRequestType Source

The type of IQ request that is made.



data IQResult Source

The (non-error) answer to an IQ request.


data IQError Source

The answer to an IQ request that generated an error.


data IQResponse Source

A response Info/Query (IQ) stanza is either an IQError, an IQ stanza of type result (IQResult) or a Timeout.




:: Maybe Int


-> Maybe Jid

Recipient (to)

-> IQRequestType

IQ type (Get or Set)

-> Maybe LangTag

Language tag of the payload (Nothing for default)

-> Element

The IQ body (there has to be exactly one)

-> Session 
-> IO (TMVar IQResponse) 

Sends an IQ, returns a TMVar that will be filled with the first inbound IQ with a matching ID that has type result or error.

sendIQ' :: Maybe Jid -> IQRequestType -> Maybe LangTag -> Element -> Session -> IO IQResponseSource

Like sendIQ, but waits for the answer IQ. Times out after 3 seconds



:: IQRequestType

Type of IQs to receive (Get or Set)

-> Text

Namespace of the child element

-> Session 
-> IO (Either (TChan IQRequestTicket) (TChan IQRequestTicket)) 

Retrieves an IQ listener channel. If the namespace/IQRequestType is not already handled, a new TChan is created and returned as a Right value. Otherwise, the already existing channel will be returned wrapped in a Left value. Note that the Left channel might need to be duplicated in order not to interfere with existing consumers.


data StanzaError Source

All stanzas (IQ, message, presence) can cause errors, which in the Xmpp stream looks like to='sender' type='error'. These errors are wrapped in the StanzaError type. TODO: Sender XML is (optional and is) not yet included.

data StanzaErrorType Source

StanzaErrors always have one of these types.



Error is unrecoverable - do not retry


Conditition was a warning - proceed


Change the data and retry


Provide credentials and retry


Error is temporary - wait and retry

data StanzaErrorCondition Source

Stanza errors are accommodated with one of the error conditions listed below.



Malformed XML.


Resource or session with name already exists.


Insufficient permissions.


Entity can no longer be contacted at this address.


Does not meet policy criteria.


No entity may perform this action.


Must provide proper credentials.


Temporarily unavailable.


Redirecting to other entity, usually temporarily.


Entity lacks the necessary system resources.


Application-specific condition.


Badly timed request.


dupSession :: Session -> IO SessionSource

Create a new session object with the inbound channel duplicated


data LangTag Source

The language tag in accordance with RFC 5646 (in the form of en-US). It has a primary tag and a number of subtags. Two language tags are considered equal if and only if they contain the same tags (case-insensitive).




primaryTag :: !Text
subtags :: ![Text]

data XmppFailure Source

Signals an XMPP stream error or another unpredicted stream-related situation. This error is fatal, and closes the XMPP stream.


StreamErrorFailure StreamErrorInfo

An error XML stream element has been encountered.


The stream has been closed. This exception is caught by the concurrent implementation, and will thus not be visible through use of Session.

StreamCloseError ([Element], XmppFailure)

When an XmppFailure is encountered in closeStreams, this constructor wraps the elements collected so far.


All attempts to TCP connect to the server failed.


The TCP details provided did not validate.

TlsError TLSError

An error occurred in the TLS layer


The server does not support the use of TLS


An action that required an active stream were performed when the StreamState was Closed


Authentication with the server failed unrecoverably


Connection already secured


Undefined condition. More information should be available in the log.

XmppIOException IOException

An IOException occurred

data StreamErrorInfo Source

Encapsulates information about an XMPP stream error.

data StreamErrorCondition Source



The entity has sent XML that cannot be processed.


The entity has sent a namespace prefix that is unsupported, or has sent no namespace prefix on an element that needs such a prefix


The server either (1) is closing the existing stream for this entity because a new stream has been initiated that conflicts with the existing stream, or (2) is refusing a new stream for this entity because allowing the new stream would conflict with an existing stream (e.g., because the server allows only a certain number of connections from the same IP address or allows only one server-to-server stream for a given domain pair as a way of helping to ensure in-order processing


One party is closing the stream because it has reason to believe that the other party has permanently lost the ability to communicate over the stream.


The value of the to attribute provided in the initial stream header corresponds to an FQDN that is no longer serviced by the receiving entity


The value of the to attribute provided in the initial stream header does not correspond to an FQDN that is serviced by the receiving entity.


A stanza sent between two servers lacks a to or from attribute, the from or to attribute has no value, or the value violates the rules for XMPP addresses


The server has experienced a misconfiguration or other internal error that prevents it from servicing the stream.


The data provided in a from attribute does not match an authorized JID or validated domain as negotiated (1) between two servers using SASL or Server Dialback, or (2) between a client and a server via SASL authentication and resource binding.


The entity has sent invalid XML over the stream to a server that performs validation


The entity has attempted to send XML stanzas or other outbound data before the stream has been authenticated, or otherwise is not authorized to perform an action related to stream negotiation; the receiving entity MUST NOT process the offending data before sending the stream error.


The initiating entity has sent XML that violates the well-formedness rules of [XML] or [XML‑NAMES].


The entity has violated some local service policy (e.g., a stanza exceeds a configured size limit); the server MAY choose to specify the policy in the <text/> element or in an application-specific condition element.


The server is unable to properly connect to a remote entity that is needed for authentication or authorization (e.g., in certain scenarios related to Server Dialback [XEP‑0220]); this condition is not to be used when the cause of the error is within the administrative domain of the XMPP service provider, in which case the internal-server-error/ condition is more appropriate.


The server is closing the stream because it has new (typically security-critical) features to offer, because the keys or certificates used to establish a secure context for the stream have expired or have been revoked during the life of the stream , because the TLS sequence number has wrapped, etc. The reset applies to the stream and to any security context established for that stream (e.g., via TLS and SASL), which means that encryption and authentication need to be negotiated again for the new stream (e.g., TLS session resumption cannot be used)


The server lacks the system resources necessary to service the stream.


he entity has attempted to send restricted XML features such as a comment, processing instruction, DTD subset, or XML entity reference


The server will not provide service to the initiating entity but is redirecting traffic to another host under the administrative control of the same service provider.


The server is being shut down and all active streams are being closed.


The error condition is not one of those defined by the other conditions in this list


The initiating entity has encoded the stream in an encoding that is not supported by the server or has otherwise improperly encoded the stream (e.g., by violating the rules of the [UTF‑8] encoding).


The receiving entity has advertised a mandatory-to-negotiate stream feature that the initiating entity does not support, and has offered no other mandatory-to-negotiate feature alongside the unsupported feature.


The initiating entity has sent a first-level child of the stream that is not supported by the server, either because the receiving entity does not understand the namespace or because the receiving entity does not understand the element name for the applicable namespace (which might be the content namespace declared as the default namespace)


The version attribute provided by the initiating entity in the stream header specifies a version of XMPP that is not supported by the server.

data AuthFailure Source

Signals a (non-fatal) SASL authentication error condition.


AuthNoAcceptableMechanism [Text]

No mechanism offered by the server was matched by the provided acceptable mechanisms; wraps the mechanisms offered by the server

AuthSaslFailure SaslFailure

A SASL failure element was encountered


The credentials provided did not conform to the SASLprep Stringprep profile


Other failure; more information is available in the log