The Jabber Building Blocks

At this stage we've got a good impression of the structure of Jabber; what different elements make up a Jabber system, how entities in Jabber are addressed, and how communication between these entities is carried.

Now it's time to look at what gets carried—the fragments that we touched upon in the previous section. These fragments are the heart and soul of Jabber—the lifeblood that courses through Jabber's veins carrying information back and forth—these fragments in many ways define what Jabber is, what it stands for.

Surprisingly, when we look closely at these fragments, with Jabber's capabilities as a messaging platform in mind, we see that there are only three basic elements involved—<message/>, <presence/>, and <iq/>. Three different types of XML fragment, each with a different purpose. But with these three fragment types, all that Jabber promises, and more, can be achieved.

Now let's look at each of these Jabber elements in greater detail. But before we do, let's dive into the XML stream and pull out a handful of XML fragments to get us in the mood. Example 5-2 shows a chunk of conversation between a Jabber client and a Jabber server which occurred immediately after the connection and authentication stages.

Although any conversation between two Jabber entities is contained within two XML documents exchanged in streams, the traditional way to represent both documents at the same time is to use prefixes to show whether a fragment is being sent (SEND:) or received (RECV:), by one of the two entities. When appropriate, the perspective is taken from the viewpoint of the entity that's not the Jabber server; in the case of Example 5-2, the viewpoint is of the Jabber client.

Example 5-2. A Chunk of Conversation between a Jabber client and a Jabber server

SEND: <iq id='roster_0' type='get'>(1)
        <query xmlns='jabber:iq:roster'/>
      </iq>

RECV: <iq id='roster_0' type='result' from='dj@yak/Work'>
        <query xmlns='jabber:iq:roster'>
          <item jid='sabine@yak' name='sabine' subscription='both'>
            <group>Family</group>
          </item>
        </query>
      </iq>

SEND: <presence><status>Online</status></presence>(2)

      ... time passes ...

RECV: <message id='1' to='dj@yak' from='sabine@yak/winjab' type='chat'>(3)
        <thread>3FE7392DDCA919CB49C73A2FFCE9901D</thread>
        <body>Hello</body>
      </message>

Example 5-2 shows three different elements in action, described as follows:

(1)
The user's (dj@yak's) contact list is requested and sent back by the server (the <iq/> elements)
(2)
The client broadcasts the user's availability (the <presence/> element)
(3)
The user receives a message from sabine@yak (the <message/> element)

So, let's have a look at each of these elements, starting with arguably the most commonly occurring—<message/>.

The Message Element

It's obvious that in a messaging architecture such as Jabber, sending messages is fundamental. The <message/> element provides us with this facility. Any data, other than availability information or structured requests and responses (which are handled by the other two element types) sent from one Jabber entity to another, is sent in a <message/> element.

All things considered, the keyword in that last sentence is in. It's a good idea to regard Jabber elements as containers; the simile fits well as the elements themselves remain relatively static (save for the attributes) but the content can change to reflect the circumstances.

Message Attributes

The <message/> element is a container, or envelope, which appropriately requires some form or addressing. The attributes of the <message/> element serve this purpose.

type

Optional

Example: <message type='chat'>

The Jabber protocol defines five different message types. The message type gives an indication to the recipient as to what sort of content is expected; the client software is then able, if it wishes, to handle the incoming message appropriately.

type='normal'

The normal message type is used for simple messages that are often one-time in nature, similar to an email message. If I send you a message and I'm not particularly expecting a response, or a discussion to ensue, then the appropriate message type is normal.

Some clients handle normal message types by placing them in a sort of message inbox, to be viewed by the user when he so chooses. This is in contrast to a chat type message.

Note that the normal message type is the default. So if a message is received without an explicit type attribute, it is interpreted as being normal.

type='chat'

The chat message type differs from the normal message type in that it carries a message that is usually part of a live conversation, which is best handled in real-time with immediate responses—a chat session.

The handling of chat messages in many clients is done with a single window that displays all the chat messages both sent and received between the two parties involved. All the chat messages that belong to the same thread of conversation, that is. There's a subelement of the <message/> element that allows the identification of conversational threads so that the right messages can be grouped together; see the reference to <thread/> later in this section.

type='groupchat'

The groupchat message type is to alert the receiving client that the message being carried is one from a conference (groupchat) room. The user can participate in many conference rooms, and receive messages sent by other participants in those rooms. The groupchat type signifies to the receiving client that the addressee specified in the to attribute (see later in this section) is not the user's JID but the JID of the conference room whence the groupchat message originates.

type='headline'

This is a special message type designed to carry news style information, often accompanied by a URL and description in an attachment qualified by the jabber:x:oob namespace. Messages with their type set to headline can be handled by clients in such a way that their content is placed in a growing list of entries that can be used as reference by the user.

type='error'

The error message type signifies that the message is conveying error information to the client. Errors can originate in many places and under many circumstances. Refer to the description of the <error/> subelement later in this section for more details.

from

Set by server

Example: <message from='dj@yak/Desktop'>

The from attribute of the <message/> element shows the message originator's JID. In many cases this is the JID of a user, but with the message type groupchat for example, it can be the JID of the conference room where the message was originally sent.

Note that the from attribute should not be set by the client. It is the Jabber server, to which the client where the message was originated is connected, that sets the attribute value. This is to prevent spoofing of JIDs. If a from attribute is set, it will be overriden by the server.

to

Optional

Example: <message to='qmacro@jabber.org'>

The to attribute is used to specify the intended recipient of the message, and is a JID. The recipient may be another Jabber user, in which case the JID will usually be in the form username@hostname (with an optional /resource if a message should be sent to a specific client connection), or it could be a Jabber server identity, in which case the JID will be in the form hostname with an optional /resource depending on the situation.

If no to attribute is specified, then the message will be directed back to the sender, or the server, depending on the circumstances. This may or may not be what you want.

(This is also the case with the to attribute for the <iq/> element, however it is not the case with the <presence/> element. [1] See the sidebar Element Handling by the Jabber Server for an explanation.)

id

Optional

Example: <message id='JCOM_12'>

When a message is sent, and a reply is expected, it is often useful to give the outbound message an identifier. When the recipient responds, the identifier is included in the response. In this way, the originator of the message can work out which reply corresponds to which original message.

At the Jabber server, this works because a reply is usually built from a copy of the original message, with the from and to attributes switched around. So the id attribute remains untouched and in place.

Message Subelements

While the <message/> element itself is a container for the information being carried, the subelements are used to hold and describe the information being carried. Depending on the circumstances and the message type, different subelements can be used.

subject

Optional

Example:

<message to='qmacro@jabber.org' from='piers@jabber.org/Home'>
  <subject>Time to meet?</subject>
  <body>What time to you want to meet this afternoon?</body>
</message>

The <subject/> subelement is used to set a message subject. Message subjects are not that common in chat type messages, but are more appropriate in normal type messages where the subject can be displayed in the style of a list of inbox items. This subelement is also used in groupchat type messages to set the subject (or topic) of a conference room.

body

Optional

Example:

<message to='qmacro@yak' from='john@yak' type='chat'>
  <body>Hey - got a minute?</body>
</message>

Naturally, the <body/> subelement carries the body of the message.

error

Optional

Example:

<message to='piers@pipetree.com/Home' from='qmacro@jaber.org' type='error'>
  <body>Are you there?</body>
  <error code='502'>Unable to resolve hostname.</error>
</message>

The <error/> subelement is for carrying error information in a problem situation. In this example, the original message sent by piers@pipetree.com was a simple “Are you there?” to what he thought was qmacro's id on the Jabber server at jabber.org. However, the to attribute was specified incorrectly (jaber.org) and the Jabber server on pipetree.com wasn't able to resolve the hostname. So Piers receives his message back with an additional <error/> subelement, and the message type has been switched to error (the type='error' attribute).

The <error/> subelement carries two pieces of related information: an error number, specified in the code attribute, and the error text. Table 5-3 shows a list of the standard error codes and texts. The entity generating the error can specify a custom error text to go with the error code; if none is specified, the standard text as shown is used.

html

Optional

Example:

<message id="3" to="dj@yak" type="chat">
  <html xmlns="http://www.w3.org/1999/xhtml">
    <body>
      <span style="font-family: Arial; font-size: 10pt">
        This is really <em>nice!</em>
      </span>
      <br/>
    </body>
  </html>
  <body>This is really nice!</body>
</message>

The <html/> tag is for support of XHTML-formatted messages. The normal <body/> tag carries plain text; text formatted with XHTML markup can be carried in <message/> elements inside the <html/> subelement.

The markup must be qualified by the XHTML namespace http://www.w3.org/1999/xhtml (as shown in the example) and conform to the markup described in the XHTML-Basic specification defined at http://www.w3.org/TR/xhtml-basic.

Note that the content of the message must also be repeated in a normal <body/> subelement without formatting, to comply with the “lowest common denominator” support for different Jabber clients—not all of them will be able to interpret the XHTML formatting so will need to receive the message content in a way that they can understand.

The <html/> subelement effectively is a wrapper around a second, alternative, <body/> subelement.

thread

Optional

Example:

<message to='qmacro@jabber.org' type='chat'>
  <thread>B19217AFEEBDC2611971DD1E8B23AAE4</thread>
  <body>Yes, they're at http://docs.jabber.org</body>
</message>

The <thread/> subelement is used by clients to group together snippets of conversations (between users) so that the whole conversation can be visually presented in a meaningful way. Typically a conversation on a particular topic—a thread—will be displayed in a single window. Giving each conversation thread an identity enables a distinction to be made when more than one conversation is being held at once and chat type messages which are component parts of these conversations are being received (possibly from the same correspondent) in an unpredictable sequence.

Only when a new topic or branch of conversation is initiated must a client generate a thread value. At all other times, the correspondent client must simply include the <thread/> tag in the response. Here thread value is generated from a hash of the message originator's JID and the current time.

x

Optional

Example:

<message to='dj@yak' type='chat' from='sabine@yak/laptop'>
  <body>Hi - let me know when you get back. Thanks.</body>
  <x xmlns='jabber:x:delay' from='dj@yak' stamp='20010514T14:44:09'>
    Offline Storage
  </x>
</message>

The <x/> subelement is special. While the other subelements like <body/> and <thread/> are fixed into the Jabber building blocks design, the <x/> subelement allows <message/> elements to be extended to suit requirements. What the <x/> subelement does is provide an anchor-point for further information to be attached to messages in a structured way.

The information attached to a message is often called the payload. Multiple anchor-points can be used (as in the example) to convey multiple payloads, and each one must be qualified using a namespace.

Just as the content of XML streams is qualified by a namespace (one from the list in Table 5-2 earlier in this Chapter), so the content of the <x/> attachment must be qualified. There are a number of Jabber-standard namespaces that are defined for various purposes. One of these, jabber:x:delay, is used in the example. They are described in Chapter 5a. But there's nothing to stop you defining your own namespace to describe (and qualify) the data that you wish to transport in a <message/>. Namespaces beginning jabber: are reserved, anything else is OK.

Briefly, you can see how payloads are attached from the example. For every <x/> subelement, there's an xmlns attribute that qualifies it, and the data contained within the <x/> tag is formatted depending on the namespace.

In the example, the payload is carried in addition to the <body/> subelement. However, as the <body/> is actually optional in a message, it is possible to transmit structured payloads between Jabber entities without the need for “conventional” message content.

Table 5-3. Standard Error Codes and Texts

CodeText
400Bad Request
401Unauthorized
402Payment Required
403Forbidden
404Not Found
405Not Allowed
406Not Acceptable
407Registration Required
408Request Timeout
409Conflict
500Internal Server Error
501Not Implemented
502Remove Server Error
503Service Unavailable
504Remove Server Timeout
510Disconnected

The Presence Element

The <presence/> element is that which is used to convey a Jabber entity's availability. An entity can be available, which means that it's connected and any packets sent to it will be delivered immediately, or it can be unavailable, which means that it's not connected, and any packets sent to it will be stored and delivered the next time a connection is made.

For the large part, it is the entity itself, not the Jabber server to which it connects, that controls the availability information. The Jabber server will communicate an entity's unavailability if that entity disconnects from the server, but will only do that if the entity has communicated its availability beforehand.

Availability information isn't a free-for-all. Presence in Jabber is usually exchanged within a subscription mechanism. See the section called Presence Subscription for an explanation.

Presence Attributes

The attributes of the <presence/> element are similar to those of the <message/> element.

type

Optional

Example: <presence type='unavailable'>

The type attribute of the <presence/> element is used for many purposes. The basic usage is to convey availability. Two values are used: available and unavailable. Another value is to signify that <presence/> packet is being used to query the packet recipient's presence (value is probe). The rest of the values (subscribe, unsubscribe, subscribed, unsubscribed) are used in the subscription structure which is described in the section called Presence Subscription.

type='available'

The available presence type is used by entities to announce their availability. This announcement is usually made to the Jabber server which manages the presence subscription mechanism (see the section called Presence Subscription for more details). However it can also be directed to a particular JID if the entity wants to control presence information itself.

The available presence isn't a simple binary “on/off”, there are varying degrees of availability which are specified using subelements of the <presence/> packet. These include <show/> and <status/>. These subelements are described next.

If no type attribute is specified, then this value of available is assumed. It makes sense, as the most common type of <presence/> packet sent by entities is usually the available type, optionally qualified with the <show/> and <status/> subelements, as the user of the connected client changes his circumstances over time (off for a break, back, out to lunch, and so on).

type='unavailable'

The unavailable presence type is the antithesis of the available presence type. It is used to qualify an entity's unavailability. An entity is unavailable when its client has disconnected from the Jabber server.

So how can the client send an unavailable presence packet if it's disconnected? Furthermore, how can we make sure that clients actually send such a packet when they disconnect (to keep the presence information equilibrium)? Well, it can't, and we don't, respectively. It is the Jabber server that sends out unavailable presence packets on behalf of the entity once it disconnects. This is part of the presence service of the JSM and closely related to the presence subscription mechanism. See the sidebar Availability Tracker for more details.

While the <show/> and <status/> subelements qualify the available presence packet, there's no point in any embellishment of the fact that the entity is unavailable, so no subelements are used when the packet is of the unavailable type.

When a user is unavailable, any packets (<message/>, <presence/> or <iq/>) sent to that user are stored offline and delivered when he comes online and establishes his availability.

type='probe'

The probe presence type is a query, or probe, on another entity's availability. This probe is used by the Jabber server to determine the presence of entities in its management of the presence subscription mechanism. Under normal circumstances this presence probe should not be used directly by a client—availability information is always pushed to the client by the server. Regardless, if a client insists on using a probe, there are two things to bear in mind:

  • Information will only be returned in response to an availability probe if the probing entity already has a subscription to the entity being probed. This means that you can't bypass the subscription model and probe random entities for availability information—only those who have previously given you permission to be informed of their availability. See the section called Presence Subscription for more details.

  • The <presence/> packet must be specified with a from attribute specifying the sender's JID in the form username@hostname before it is sent. The Jabber server does not add this attribute. The presence mechanism will use the full JID (including any resource) when working out whether the prober has permission. This will ultimately fail because permission is determined on a username@hostname basis, not a username@hostname/resource basis.

type='subscribe'

This presence type is a request to subscribe to an entity's presence. (“Will you allow me to be sent your presence information by the server?”) See the section called Presence Subscription for details.

type='unsubscribe'

This presence type is a request to unsubscribe from an entity's presence. (“I don't want to be sent your presence information anymore, please have the server stop sending it to me.”) See the section called Presence Subscription for details.

type='subscribed'

This presence type is sent in reply to a presence subscription request, used to accept the request. (“Okay, I accept your request; the server will send you my presence information.”) See the section called Presence Subscription for details.

type='unsubscribed'

This presence type is sent in reply to a presence unsubscription request, used to accept the request. (“Okay, I accept your unsubscription request; the server will stop sending you my presence information.”)

It is also used to deny a presence subscription request. (“No, I don't accept your subscription request; I don't want the server to send you my presence information.”) See the section called Presence Subscription for details.

from

Set by server

Example: <presence from='dj@yak'/>

Similar to the attribute of the same name in the <message/> element, here the from attribute is set by the server and represents the JID where the availability information originates.

If you are sending a presence probe type='probe' you must set the from attribute yourself, as mentioned earlier.

to

Optional

Example: <presence to='sabine@yak'/>

The to attribute is optional; if you are just announcing availability (with the intention of having that announcement reflected to the appropriate members of your roster), then specifying a to attribute is not appropriate. [2]

If you want to send your availability to a specific entity, then do so using this to attribute, specifying that entity's JID. Why might you want to do this? See the sidebar Availability Tracker for an answer.

id

Optional

Example: <presence id='p1'/>

All Jabber elements support an id attribute for tracking purposes. So, the <presence/> packet is no different from the <message/> packet in this respect. As presence notification is usually a one-way thing, it is very uncommon to see <presence/> packets qualified with an id attribute.

Presence Subelements

show

Optional

Example:

<presence>
  <show>xa</show>
  <status>Gone home for the evening</status>
</presence>

When an available presence is sent, it can be qualified with more detail. The detail comes in two parts, and is represented by two subelements of the <presence/> element. The first part of the detail is in the form of a <show/> tag, which by convention contains one of five possible values. Table 5-4 lists these values, and their meaning.

Table 5-4. Presence 'show' values

ValueMeaning
awayThe user is available, but temporarily away from the client.
chatThis is similar to the normal value, but suggests that the user is open to conversation.
dnd“Do Not Disturb.” Although online and available, the user doesn't want to be disturbed by anyone. Don't forget, unless the user is actually offline (unavailable, or disconnected from the Jabber server), messages to that user will be sent immediately and retrieved by the user when they change their status to available.
normalThis is the normal availability; there's nothing really special about this qualification—the user is simply available. If no <show/> tag is specified in an available <presence/> element, a value of normal is assumed.
xaThis is an extreme form of the away value—xa stands for Extended Away, and is probably as near to an unavailable presence as you can get.

status

Optional

Example:

<presence>
  <show>dnd</show>
  <status>working on my book!</status>
</presence>

The other part of the detail that qualifies a user's availability is the <status/> subelement. It allows for a more descriptive remark that embellishes the <show/> data.

The examples for this subelement and the <show/> subelement show how the <status/> value is used as a textual description to explain the <show/> value's "short-code", or mnemonic.

priority

Optional

Example:

<presence>
  <show>chat</show>
  <status>coffee break</status>
  <priority>5</priority>
</presence>

Earlier in this chapter, the section called Resources and Priority describes how a user's priority is used to determine the primary session to which messages should be sent.

As we see here, the priority is set using the <presence/> element. In this example, we see that the user has set the priority high to make sure that messages are routed to him on the Jabber client running on this machine.

x

Optional

Example:

<presence from='dj@yak/Work' to='sabine@yak'>
  <status>Online</status>
  <priority>1</priority>
  <x xmlns='jabber:x:delay' from='dj@yak/Work'
     stamp='20011005T10:58:28'/>
</presence>

Just as with the <message/> element, extra information can be attached to the <presence/> element by means of the <x/> tag. In the same way, each <x/> tag must be qualified with a namespace.

While there aren't many external uses for payloads in a <presence/> packet, the Jabber server uses this facility to add information. In this example, we see that dj@yak's notification of availability (remember, type='available' is assumed for <presence/> packets without an explicit type attribute) is being sent to sabine@yak. While dj@yak connected to the Jabber server and send his availability (which was stamped on receipt by the Jabber server) just before 11 a.m., sabine@yak is just logging on now (say, 30 minutes later). When she receives dj@yak's presence, she knows how long that presence status has been valid for.

See the section called The X Namespaces in Chapter 5a to find out what namespaces are available to qualify <x/>-included payloads.

Presence Subscription

Presence subscription is the name given to the mechanism that allows control over how entity presence information is made available to other entities. By default, the availability of an entity is unknown to other entities.

Let's put this into more concrete terms. For example, let's assume that you and I are both Jabber users. I'm registered with the Jabber server running at jabber.org, my JID is qmacro@jabber.org, and you are registered with a Jabber server running at your company, and your JID is you@yourserver.com.

If you want to know whether I'm available, you have to subscribe to my presence. This is done by sending a <presence/> packet to me with the type attribute set to subscribe. In the example that follows, the XML fragments are sent and received from your perspective):

SEND: <presence type='subscribe' to='qmacro@jabber.org'/>

I receive the <presence/> packet, and when I receive it, it's been stamped (by your Jabber server) with a from attribute with the value you@yourserver.com. So, based upon who it is, I decide to accept the subscription request and send back a reply:

RECV: <presence type='subscribed' to='you@yourserver.com'/>

This lets you know that I've accepted your subscription request. From now on, every time my availability changes (when I send a <presence/> packet or when I disconnect (and the server generates an unavailable <presence/> packet on my behalf), that availability information will be relayed to you.

But how does this work? How does the Jabber server know that you've subscribed to my presence and I've accepted that subscription?

Enter the roster, stage right. The roster is a list of JIDs maintained for each user, stored on the server-side. A roster is similar to an AOL's Buddy List; one could say that it's a sort of personal address book, but it's more than that. The presence subscription and roster mechanisms are tightly intertwined. We'll be examining the roster in more detail in the section called jabber:iq:roster in Chapter 5a. Here, we'll just look at the characteristics of the roster that are relevant for the presence subscription mechanism. The roster is managed using the third basic Jabber element—<iq/>—which will be explained in more detail later in this section. Ignore the tags that you aren't yet familiar with; it's just important to get the basic drift of what's going on.

While the roster is stored and maintained on the server-side, any changes to the roster are made by the server are reflected (pushed) in the client so it can be synchronized with a local copy. [4]

Let's expand the simple exchange of <presence/> packets from above and look how the roster is used to record presence subscription information.

If you wish to subscribe to my presence and add my JID to your roster at the same time, these two actions are linked for obvious and practical reasons. Many Jabber clients use the roster as a basis for displaying availability information, and with the exception of an entity sending presence information directly to another entity irrespective of roster membership, presence subscription information is stored by-user in the roster. Here's the order in which the subscription would take place:

  1. A request is sent to the server to update your roster, adding my JID to it:

    SEND: <iq id="adduser1" type="set">
            <query xmlns="jabber:iq:roster">
              <item jid="qmacro@jabber.org" name="DJ Adams"/>
            </query>
          </iq>

    You add an id attribute to be able to track the request and match up the response when it comes.

  2. The server responds with a push of the updated (new) roster item:

    RECV: <iq type='set'>
             <query xmlns='jabber:iq:roster'>
               <item jid='qmacro@jabber.org' name='DJ Adams'
                     subscription='none'/>
             </query>
           </iq>

    Note that in the update, an additional attribute subscription='none' is sent, reflecting the presence subscription relationship between you and me. At this stage, the relationship is that I don't have a subscription to your presence and you don't have a subscription to my presence, hence the value none.

  3. It also acknowledges the original update request, confirming its success:

    RECV: <iq id='adduser1' type='result'
              from='you@yourserver.com/Work'
              to='you@yourserver.com/Work'/>

    Note the id='adduser1' identity is passed back so we can track the original request and from where this response is being made.

  4. Meanwhile, you send the subscription request:

    SEND: <presence to="qmacro@jabber.org" type="subscribe"/>

  5. The server notes the subscription request going through and once more updates your roster and pushes the item out to you:

    RECV: <iq type='set'>
            <query xmlns='jabber:iq:roster'>
              <item jid='qmacro@jabber.org' name='DJ Adams'
                    subscription='none' ask='subscribe'/>
            </query>
          </iq>

    The current subscription relationship is reflected with the subscription='none' attribute. In addition, we have a subscription request status, with ask='subscribe'. This request status shows that there is an outstanding presence subscription request to the JID in that roster item. If you've ever seen the word “Pending” next to a username in a Jabber roster, this is where that comes from. Don't forget that a subscription request might not get an immediate response, so we need to remember that the request is still outstanding.

  6. Your subscription request is received and accepted, and a subscribed type is sent back to you as part of a <presence/> packet:

    RECV: <presence to='you@yourserver.com'
                    type='subscribed' from='qmacro@jabber.org'/>

  7. The server also notices the subscription request acceptance, and yet again updates your roster to keep track of the presence subscription. Again, it pushes the subscription information out to you so your client can keep its copy up to date:

    RECV: <iq type='set'>
             <query xmlns='jabber:iq:roster'>
               <item jid='qmacro@jabber.org' name='DJ Adams'
                     subscription='to'/>
             </query>
           </iq>

    This time, the subscription attribute in the roster item has been set to to. This means that the roster owner (you) has a presence subscription to the JID in the roster item (i.e., me).

  8. The server knows you've just subscribed to my presence, it generates a presence probe on your behalf which causes my presence information to be retrieved and sent to you.

    RECV: <presence from='qmacro@jabber.org/Work'
                    to='you@yourserver.com'>
            <status>Available</status>
            <priority>1</priority>
            <x xmlns='jabber:x:delay'
               from='qmacro@jabber.org/Work'
               stamp='20010515T11:37:40'/>
          </presence>

Of course, at this stage, our relationship is a little unbalanced, in that you have a subscription request to me, but I don't have a subscription request to you. So you are aware of my availability, but not the other way around. In order to rectify this situation, I can repeat the process in the opposite direction, asking for a subscription to your presence information.

The only difference to the sequence that we've just seen is that you will already exist on my roster because the server will have maintained an item for your JID to record the presence subscription relationship. While the item in your roster that represents my JID has a subscription attribute value of to (the roster owner has a presence subscription to this JID)—we've seen this in Step 7—the item in my roster that represents your JID has a subscription attribute value of from (the roster owner has a presence subscription from this JID).

Once I repeat this sequence to subscribe to your presence (and you accept the request), the value for the subscription attribute in the items in each of our rosters will be set to both.

The upshot of all this is that when an entity announces its presence, it does so using a single <presence/> packet, with no to attribute specified. All the members in that entity's roster who have a subscription to that entity's presence will receive a copy of that <presence/> packet and thereby be informed. [5]

The IQ Element

The third and final element in the Jabber building block set is the <iq/> element (“iq” stands for “Info/Query”), which represents a mechanism for sending and receiving information. What the <iq/> element has over the <message/> element for this purpose is structure and inherent meaning. It is useful to liken the info/query mechanism to the request/response model of the HyperText Transfer Protocol (HTTP) using GET and POST.

The <iq/> element allows a structured conversation between two Jabber entities. The conversation exists to exchange data, to retrieve or set it, and to notify the other party as to the success (or not) of that retrieve or set action. There are four states that an <iq/> element can be in, each reflecting one of the activities in this conversation:

get

Get information.

set

Set information.

result

The result, in the case where the get or set was successful.

error

An error, in the case where the get or set was not successful.

At the beginning of this section, we saw various elements in action in Example 5-2. The first two were <iq/> elements, and show a retrieval request and response for roster information.

First comes the request:

SEND: <iq id='roster_0' type='get'>
        <query xmlns='jabber:iq:roster'/>
      </iq>

Then the response:

RECV: <iq id='roster_0' type='result' from='dj@yak/Work'>
        <query xmlns='jabber:iq:roster'>
          <item jid='sabine@yak' name='sabine' subscription='both'>
            <group>Family</group>
          </item>
        </query>
      </iq>

There's a number of things we can see in this snippet:

So, if we look at the first <iq/> element:

<iq id='roster_0' type='get'>

We can see that this “request” <iq/> doesn't contain a to attribute. This is because the request is being made of the Jabber server (specifically the JSM), instead of a particular user. Next we see the response from the server:

<iq id='roster_0' type='result' from='dj@yak/Work'>

This “response” <iq/> contains a from attribute stating that the result is coming back from the original requester! This is simply because the from attribute is a hang-over from the original request to the Jabber server, which is stamped with its origin (dj@yak/Work) in the form of the from attribute. Here, as in many other places in the Jabber server, the response is simply built by turning the incoming request packet around and adding whatever was required to it before sending it back.

Okay, let's examine the details of the <iq/> element.

IQ Attributes

The attributes of the <iq/> element are the same as those of the <presence/> and <message/> elements, and used pretty much in the same way.

type

Required

Example: <iq type='get'/>

As mentioned already, the from attribute is used to specify the activity.

type='get'

This is used to specify that the <iq/> element is being used in request mode, to retrieve information. The actual subject of the request is specified using the namespace qualification of the <query/> subelement; see later in this section for details.

Using the HTTP parallel, this is the equivalent of the GET verb.

type='set'

While the get <iq/> type is used to retrieve data, the corresponding set type is used to send data, and is the equivalent of the POST verb in the HTTP parallel.

Very often, a get request will be made of an entity, to discover fields that are to be completed to register with that entity. The Jabber User Directory (JUD) is a component that plugs into the jabberd backbone and provides simple directory services; users can register an entry in the JUD address book, on which searches can be performed.

Let's have a look how IQ elements are used to interact with the JUD.

The registration conversation with the JUD starts with an <iq/> get to discover the fields that can be used for registration, followed by an <iq/> set filling those fields in the act of registration. Note how each time, the JUD responds with an <iq/> result to confirm each action's success.

Here we are requesting registration information from the JUD. Note the namespace that qualifies the <query/> subelement (and hence the <iq/>).

SEND: <iq type='get' to='jud.yak'
                   id='judreg_ask'>
        <query xmlns='jabber:iq:register'/>
      </iq>

The JUD responds with the fields to fill in. The response is basically a copy of the request, with new attributes and tags.

RECV: <iq type='result' to='dj@yak/Work'
          from='jud.yak' id='judreg_ask'>
        <query xmlns='jabber:iq:register'>
          <instructions>
            Complete the form to submit your details
            to the User Directory
          </instructions>
          <name/>
          <first/>
          <last/>
          <nick/>
          <email/>
        </query>
      </iq>

Now we know what to send:

SEND: <iq type='set' to='jud.yak' id='judreg_do'>
        <query xmlns='jabber:iq:register'>
          <name>DJ Adams</name>
          <first>DJ</first>
          <last>Adams</last>
          <nick>qmacro</nick>
          <email>dj@mailserver.org</email>
        </query>
      </iq>

And the JUD responds saying our set request was successful.

RECV: <iq type='result' to='dj@yak/Work'
                   from='jud.yak' id='judreg_do'/>

type='result'

As shown in the JUD conversation, the 'result' type <iq/> packet is used to convey a result. Whether that result is boolean (it worked, as opposed to it didn't work) or conveys information (such as the registration fields that were requested), each get or set request is followed by a result response, if successful.

type='error'

If not successful, the get or set request is not followed by a result response, but an error response. In the same way that a subelement <error/> carries information about what went wrong in a <message type='error'/> element, so it also provides the same service for <iq type='error'/> elements. [6]

Let's have a look at an <iq type='error'> in action. A user, who is trying to join a conference room, is notified that his entrance is barred because he hasn't supplied a required password.

First, the user requests information on the room he wishes to join.

SEND: <iq type="get" id="conf1" to="cellar@conference.yak">
        <query xmlns="jabber:iq:conference"/>
      </iq>

The conference component instance, to which the <iq/> was addressed (with the to='cellar@conference.yak' attribute), responds with information about the 'cellar' room, including the fact that a nickname and password must be specified to gain entrance.

RECV: <iq type='result' id='conf1' to='dj@yak/winjab'
                            from='cellar@conference.yak'>
        <query xmlns='jabber:iq:conference'>
          <name>Dingy Cellar</name>
          <nick/>
          <secret/>
        </query>
      </iq>

After sending availability to the room, to have the availability tracker kick in for that room's JID (see the sidebar Availability Tracker earlier in this section)…

SEND: <presence to="cellar@conference.yak"/>

…entrance to the room is attempted with a nickname but no password is specified.

SEND: <iq to="cellar@conference.yak" type="set" id="conf2">
        <query xmlns="jabber:iq:conference">
          <nick>dj</nick>
        </query>
      </iq>

The entrance attempt was unsuccessful. An error response is given with an <error/> subelement explaining what the problem was.

RECV: <iq to='dj@yak/winjab' type='error' id='conf2'
           from='cellar@conference.yak'>
        <query xmlns='jabber:iq:conference'>
          <nick>dj</nick>
        </query>
        <error code='401'>Unauthorized</error>
      </iq>

Again, the response is simply the request with modified attributes and data (the <error/> tag) added.

from

Set by server

Example: <iq from='dj@yak/Work'/>

Similar to the from attribute in the <message/> and <presence/> elements, this is set by the server and represents the JID where the <iq/> originated.

to

Optional

Example: <iq to='jdev@conference.jabber.org'/>

This attribute is used to specify the intended recipient of the info/query action or response. If no to attribute is specified, the delivery of the packet is set to the sender, as is the case for <message/> packets. However, unlike the case for <message/> packets, <iq/> packets are usually dealt with enroute and handled by the JSM.

What does that mean? Packets sent from a client travel over a jabber:client XML stream and reach the Jabber server, where they're routed to the JSM. [7]

A large part of the JSM consists of a series of packet handlers whose job it is to review packets as they pass through and act upon them as appropriate; some of these actions may cause the packet to be deemed to have been “delivered” to its intended destination (thus causing the packet routing to end for that packet) before it gets there.

So in the case of <iq/> packets without a to attribute, the default destination is the sender's JID, as we've already seen with the <message/> element. But because JSM handlers that receive the packet may perform some action to handle it and cause that packet's delivery to be terminated (marked complete) prematurely, the effect is that something sensible will happen to the <iq/> packet that doesn't have a to attribute and it won't appear to act like a boomerang.

Here's an example:

The namespace jabber:iq:browse represents a powerful browsing mechanism that pervades much of the Jabber server's services and components. Sending a simple browse request without specifying a destination (no to attribute):

SEND: <iq type='get'>
        <query xmlns='jabber:iq:browse'/>
      </iq>

will technically be determined to have a destination of the sender's JID. However, a JSM handler called mod_browse which performs browsing services gets a look-in at the packet before it reaches the sender and handles the packet to the extent that the query is deemed to have been answered and so the delivery completed. The packet stops travelling in the sender's direction, having been responded to by mod_browse:

RECV: <iq type='result' to='dj@yak/sjabber' from='dj@yak'>
        <user name='DJ Adams' xmlns='jabber:iq:browse' jid='dj@yak'/>
      </iq>

And while we're digressing, here's a meta-digression: We see from this example that a browse to a particular JID is handled at the server. The client doesn't even get a chance to respond. So, as one of browsing's remits is to facilitate resource discovery (the idea is that you can query someone's client to find out what that client supports—whiteboarding or XHTML text display, for example), how is this going to work if the client doesn't see the request and can't respond? [8]

The answer lies in the distinction of specifying the recipient JID with or without resource. As a resource is per-client connection and often represents that client, it makes sense to send a browse request to a JID including a specific resource:

SEND: <iq type='get' to='qmacro@jabber.org/sjabber'>
        <query xmlns='jabber:iq:browse'/>
      </iq>

This time the destination JID is resource-specific and the packet passes by the mod_browse handler to reach the client (sjabber), where a response can be returned: [9]

RECV: <iq type='result' to='piers@jabber.org/WinJab
                      from='qmacro@jabber.org/sjabber'>
        <user type='client' xmlns='jabber:iq:browse'
                         jid='qmacro@jabber.org/sjabber'>
          <whiteboard/>
          <videochat/>
          <PGP/>
        </user>
      </iq>

id

Optional

Example: <iq type='get' id='roster1'>

If we're going to rank the elements in terms of tracking importance, <iq/> would arguably come out on top, as it inherently describes a request-response mechanism. So this element also has an id attribute for tracking purposes.

Don't forget that the pair of XML streams that represent the two-way traffic between Jabber client and server are independent, and any related packets such as a request (travelling in one XML stream) and the corresponding response (travelling in the other) are asynchronous. So a tracking mechanism like the id attribute is essential to be able to match packets up.

IQ Subelements

We've seen two of these three subelements of the <iq/> element already in earlier examples - <query/> and <error/>. The other one is <key/>. Here's a review of them.

query

Required

Example:

<iq type='get' to='yak'>
<query xmlns='jabber:iq:version'/>
</iq>

We've already seen the <query/> subelement performing the task of container for the info/query activity.

  • For a get activity, the subelement usually just contains a qualifying namespace that in turn defines the essence of the get activity. This is evident in the example here, where the <iq/> element is a retrieval of the server (yak) version information.

  • For a set activity, it contains the qualifying namespace and also child tags that hold the data to be set, as in this example where a vCard (an electronic “business card”) is being updated:

    SEND: <iq type='set'>
            <vCard xmlns='vcard-temp' version='3.0'>
            ... [vCard information] ...
            </vCard>
          </iq>

  • When result information is returned, it is enclosed within a <query/> subelement qualified with the appropriate namespace, like in this response to the earlier request for server version information:

    RECV: <iq type='result' to='dj@yak/Work' from='yak'>
            <query xmlns='jabber:iq:version'>
              <name>jsm</name>
              <version>1.4.1</version>
              <os>Linux 2.2.12-45SAP</os>
            </query>
          </iq>

    Of course, there are some results that don't carry any further information—the so-called boolean results. When there's no information to return in a result, the <query/> subelement isn't necessary. A typical case where a boolean result is returned is on successfully authenticating to the Jabber server (where the credentials are sent in a set request in the jabber:iq:auth namespace); the result <iq/> element would look like this:

    RECV: <iq type='result' id='auth_0'/>

  • And for an error situation, while the actual error information is carried in an <error/> subelement, any context in which the error occurred is returned too in a <query/> subelement. This is usually because the service returning the error just turns around the set <iq/> packet—which already contains the context as the data being set—and adds the <error/> subelement before returning it.

    Here we see that the authentication step of connecting to the Jabber server failed because Sabine mistyped her password:

    RECV: <iq type='error' id='auth_0'>
            <query xmlns='jabber:iq:auth'>
              <username>sabine</username>
              <password>geheimnix</password>
              <resource>pavilion</resource>
            </query>
            <error code='401'>Unauthorized</error>
          </iq>

Whoa! Hold on a minute, what's that <vCard xmlns='vcard-temp' version='3.0'> doing up there? Shouldn't it be <query xmlns='vcard-temp' version='3.0'>?

Actually, no. The name of the subelement doesn't really matter, in fact. By convention it's <query/>. [10] But it can be anything. When you're interacting with a Jabber server via telnet and are writing the stream fragments by hand, you'll soon appreciate the fact that you can write something like

<q xmlns='.....'>

instead of

<query xmlns='.....'>

It doesn't seem much, but after the twentieth <iq/> packet, you'll think otherwise!

The critical part of the subelement is the namespace specification with the xmlns attribute. And we've seen this somewhere before—in the definition of component instance configuration in the section called Server Configuration in Chapter 4 we learn that the tag wrapping the component instance's configuration, like that for the c2s service:

<service id="c2s">
  ...
  <pthcsock xmlns='jabber:config:pth-csock'>
    ... [configuration here] ...
  </pthcsock>
</service>

which is pthcsock here, is irrelevant, while the namespace defining that tag (jabber:config:pth-csock) is important because it's what is used by the component to retrieve the configuration.

We've seen this feature in this chapter too; remember the <iq/> examples in the jabber:iq:browse namespace? The result of a browse request that returned user information looked like this:

RECV: <iq type='result' to='dj@yak/sjabber' from='dj@yak'>
        <user name='DJ Adams' xmlns='jabber:iq:browse' jid='dj@yak'/>
      </iq>

Again, the query tag is actually <user/>. In fact, in browsing, the situation is extreme, as the <iq/> response's subelement tag name will be different depending on what was being browsed. But what is always consistent is the namespace qualifying the subelement; in this example it's jabber:iq:browse.

error

Optional

Example:

<iq type='error' from='dj@yak/Work' to='dj@yak/Work'>
  <query xmlns='jabber:iq:browse'/>
  <error code='406'>Not Acceptable</error>
</iq>

The error subelement carries error information back in the response to a request that could not be fulfilled. Table 5-3 shows the standard error codes and default accompanying texts.

The example here shows the response to a browse request, but why might the request have been erroneous? Because the <iq/> type attribute had been specified as set instead of get. Browsing is a read-only mechanism.

key

Optional

Example:

<iq type='result' id='callback_13' to='dj@yak/Work' from='callback.yak'>
  <query xmlns='jabber:iq:register'>
    <password/>
    <instructions>
      Please specify a name and password to register for this service.
    </instructions>
    <key>cff28e89afa94e734aabfb11ec1099780450d80e</key>
  </query>
</iq>

The <key/> tag is used in registration sequences to add a simple form of security between the service and the entity registering.

The example here shows the result of an <iq/> get request, qualified by the jabber:iq:register namespace, made to an imaginary alarm service (callback) running on the Jabber server yak. What must happen for a successful registration is that the key enclosed in the <key/> tag must be sent as-is in the <iq/> set request along with the rest of the information required (name and password). This is so that the service can verify that the requester is known to the service as having previously asked for procedural instructions.

The value of the key is a hash value randomly generated by the server.

Notes

[1]

Actually, it is, internally, but the effect is that it isn't. The packet is swallowed on its final delivery stage by the presence handler.

[2]

In fact, as in the cases for the other two elements <message/> and <iq/>, not specifying a to attribute will cause the <presence/> packet to be sent to the sender. However, in the case of the presence handler mechanism, the packet is swallowed before it can reach its destination to prevent reflective presence problems.

[3]

The example here contains a room JID with no resource specified; this is taken from the 0.4 version of the Conferencing protocol. An earlier version of the protocol (Groupchat 1.0) required that the nickname for the person entering the room be specified as a resource to the room's JID; for example: jdev@conference.jabber.org/dj.

[4]

The local copy would only exist for the duration of the user's session and should always be regarded as a slave copy.

[5]

That is, where there's a value of to or both in the roster item's subscription attribute.

[6]

Table 5-3 lists the standard Jabber error codes and their default descriptions.

[7]

with the internal <route/> packet; see the section called Component types in Chapter 4 for more details.

[8]

Whiteboarding is collaborative sketching, not a form of surfing atop wave crests.

[9]

Well, I can dream, can't I?

[10]

There is, of course an exception to this rule. The name of the tag must be query in the user registration and authentication steps; see the description for the jabber:iq:auth namespace in the next section, and Chapter 6.