The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Jabber::Lite - Standalone library for communicating with Jabber servers.


  use Jabber::Lite;

  my $jlobj = Jabber::Lite->new();

  $jlobj->connect( %args );
  $jlobj->authenticate( %args );
  my $stillgoing = 1;
  while( $stillgoing ){
        my $tval = $jlobj->process();
        if( $tval == 1 ){
                my $curobj = $jlobj->get_latest();

                # Process based on the object.

        }elsif( $tval < 0 ){
                $stillgoing = 0;


Jabber::Lite is intended to be a pure perl library for interacting with Jabber servers, and be able to run under any version of perl that has the Sockets library.


Jabber::Lite is, as the name implies, a small 'lite' library for dealing with Jabber servers, implemented entirely in perl. Whilst it is small, it does try to be fairly complete for common tasks.

Whats in the box? Jabber::Lite is able to connect to a Jabber server, read from the socket, and supply XML objects to the application as the application reads them. Its function calls are mostly compatible with Jabber::NodeFactory and Jabber::Connection. Surprisingly, it can also function as a stand-alone XML parser (which was not the author's original intent, but hey, it works).

Whats not in the box? Any requirement for a recent perl version, UTF-8 support, as well as a fully XML-compliant Parser.

Applications using this library will need to be aware that this library uses a combination of 'pull' and 'push' methods of supplying XML objects. Handlers for given object types can be put in place, however if an object is not fully handled by a Handler, the object will 'block' further objects until the Application retrieves it. Read the notes on ->process and ->get_latest() for further details.

The inbuilt parser, fully implemented in perl, is more properly termed an XML Recogniser. If you want a fully compliant XML Parser, look elsewhere. This one recognises just enough XML for its purposes ;)


The methods within have been organised into several categories, listed here for your searching pleasure:

Dealing with <stream:features>
Handling Packets
So Long, and Thanks for all the <fish/>
These are a few of my incidental things
Object common
Object detailed and other stuff.

METHODS - Initialisation


Returns a new instance of the object. Takes a hash of arguments which are passed straight to ->init();


(Re-)initialises data stored on the object, removing most references. Used by ->new() to ensure that there is no 'bad' stuff around. Takes a hash of values including:


The number of bytes to request (but not expect) from the socket at any one time. Defaults to 1500 to ensure that an ethernet packet will be read in one call. Do not set this excessively high. Likewise, setting it too low will result in excessive polls.


A boolean indicating whether to disconnect on exceeding maxobjectsize bytes, maxnamesize or maxobjectdepth in a single object. The default, 0, will continue to read and parse the object, but will not save more of the object's data or attributes into memory.


The maximum number of bytes allowed in a single object. There is no default. This is intended as protection against an excessively large packet.


The maximum number of subtags allowed in a single object. There is no default.


The maximum length of a single tag name, eg, the 'foo' in '<foo/>'. There is no default. Note that this is applied against every tag, not just the parent tag. This is intended as protecting against a really long <taaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaag>, which may still consume memory if the maxobject size is exceeded and disconnectonmax is left at 0.


A debug qualifier. If set to '1', will show all debug messages. If set to a comma-seperated string, will show all debug messages generated by those subroutines.

The various 'max' settings are enforced by ->do_read. Calling ->parse_more directly will not incur the dubious protections afforded by this.

METHODS - Resolving

Before connecting, you may need to resolve something in order to find out where to point the connection methods to. Heres some methods for resolving.


Deals with the intricacies of figuring out what you need to connect to. Understands SRV records, and how things can resolve differently depending on whether you want a server or client connection. Takes a hash of 'Domain', a 'Timeout' value (in seconds) and a 'Type' of 'client' or 'server'. Returns a boolean success value of 1 (success) or 0 (failure).

Note that no DNSSEC or TSIG verification is done.


Returns a list of what the last ->resolve request actually resolved to. This is an ordered-by-priority, randomised-by-weight @list of 'IP.address,port'. If there is no ',port', then no port information was present in the DNS, and the application's own idea of default port should be used.

The ordering is done according to the method set out in RFC2782(DNS SRV Records). Of particular note is page 3, where a randomisation function is applied to the ordering of SRV RRs with equal priority. Thus, each time this function is called, it may return a different ordering of IPs.


As per ->resolve, but submit in the background. This returns 1 if the query could be submitted, and 0 if not. ( Actually, ->resolve is simply a wrapper around ->bgresolve and ->bgresolved )


Checks to see whether the last ->bgresolve request completed. Only one request in the background can be ongoing at a time. Returns -1 if the resolution is still pending, 0 if the resolution failed, and 1 if the resolution was successful. ->resolved can then be called to retrieve the list.

METHODS - Connecting

Before jabbering at other entities, you need to connect to a remote host.


Connect to a Jabber server. Only one connection at a time is supported on any given object. Returns 0 if unsuccessful, 1 if successful.

Takes a hash of values as follows:


The Host (name or IP address) to connect to. Default is no host, and thus no connection. Note that if a name of the Host is used, then gethostbyname will be implicitly used by IO::Socket::INET, blocking the application whilst doing so. Calling applications may wish to avail themselves of the ->resolve methods listed earlier to avoid this.


The port to connect to on the remote host. Defaults to 5222.


The domain to request on the remote Host. Defaults to the value of the Host option. The meaning of this depends on the connection type (StreamXMLNS). If connecting as a client, refers to the domain that the Username and Password credentials belong to. If connecting as a component, refers to the domain that this connection wants to bind as.


Initiate a SSL/TLS connection immediately on connecting, for example, if you are connecting to a server which offers SSL on an alternative port. Defaults to 0. This is used internally to redo the connection.


Negotiate a TLS connection if <starttls> is listed as one of the connection features, and IO::Socket::SSL is available. Defaults to 1, as everyone likes encryption.


The connection must be encrypted before considering the connection to be opened. This defaults to 0. If this is set to 1, and IO::Socket::SSL is not available, the connection will fail.


This simply opens a connection and returns without having sent any packets, except for any required to initiate SSL if requested. The calling program is responsible for sending any initial packets down the link, and responding to any packets received. Defaults to 0.


This simply opens a connection and sends the initial '<stream:stream>' tag, then returns. The default is 0. It is used internally for a number of things, each time a new '<stream:stream>' tag needs to be sent, which is surprisingly often (once when connect, once after TLS is negotiated, and once after SASL has been negotiated).


This checks to see if the server domain returned to us is the same as the Domain that was requested. The default, 1, allows this check to be skipped.


The type of connection that we're telling the server this is. Defaults to 'jabber:client'. For component connections, use 'jabber:component:accept', and for servers, use 'jabber:server'. Or use the ConstXMLNS method documented towards the end (use 'client' or 'component').


The default language used over the connection, as per xml:lang. Defaults to undef (not sent).


A client-initiated Identifier. RFC3920 4.4 says that the stream id SHOULD only be used from the receiving entity to the intiating entity. However, some applications may think otherwise. Defaults to undef (not sent).


The number of seconds to hang around whilst waiting for a connection to succeed. Defaults to 30. Note that the time taken for connect may be more than this, as the same value is used in the connection, SSL negotiation and waiting for the remote server to respond phases.

Note that during the SSL negotiation, the application will block, due to the perl SSL libraries not obviously supporting a backgroundable method.


The version to declare to the remote Jabber server. The default, '1.0', attempts to steer the conversation along the lines of RFC3920, xmpp-core.


Any option beginning with 'SSL' will be passed to IO::Socket::SSL as-is, which may be useful if you are expecting to exchange certificate information. No values are set up by default.


A boolean which indicates that a socket has previously been created by methods unknown to this library, and stored via ->socket(). Thus, ->connect doesn't actually have to do a TCP connection, and can just continue on with the connection methods.

Note for people with their own connection requirements: The ->connect method is comparitively simple (ha!); just initiating a TCP connection and setting up handlers to negotiate TLS. Those wishing to set up their own connection handlers are welcome to do so, but search this library's code for the string 'grok incomplete' before doing so.


The ->bgconnect method is just the same as the ->connect method, except it returns straight away. Use the ->bgconnected method to test for an answer to that 4am question, am I connected or not?

Returns 1 if the TCP connection could be started, and 0 if not. If this method returns 0, you probably have bigger problems.

Note: The ->bgconnect method just calls ->connect with the background flag set.


This tests to see whether the current connection has succeeded. It returns -1 if not yet, 0 if failed (and socket has been closed) and 1 if successful. It takes a hash of:

        RunProcess - Invoke ->process internally
        ProcessTime - time to pass to ->process (default 0 )

If RunProcess is not specified, you will have to invoke ->process() seperately.

METHODS - Authenticating

It helps if the remote server knows who you are.


Attempt to authenticate to the Jabber server over a connected socket. It takes a hash of:


The username to authenticate as.


The password to use.


Specify a resource method to use. If a Resource is not specified, a default value of 'Jabber::Lite' is used. Note that the Resource accepted by the server may be different; use ->connect_jid() to find out what the server considers the Resource to be.


The domain to use if the authentication method requires it. Defaults to the value specified for ->connect().


The secret to use if authenticating as a component, or if the chosen authentication method requires just a password, not a username.


The preferred authentication method to use. Either 'sasl' or 'jabber:iq:auth'. The default is 'jabber:iq:auth' (JEP-0078), unless the server has supplied a list of authentication mechanisms as per xmpp-core (RFC3920), in which case 'sasl' is used.


A preferred mechanism to use for authentication. The library will try to use any available mechanisms that are considered more secure than the one supplied, but should not try mechanisms that are considered less secure. The mechanisms available, in order of highest security to lowest, are:


A boolean indicating whether to bind the nominated resource if so requested by the remote server. The default, 1, is for applications that do not wish to deal with this step, or for people for whom urn:ietf:params:xml:ns:xmpp-bind is at a significant altitude. If you know what you are doing, set this to 0, and be sure to read the ->bind() method. Note that if the server requires binding, and this is not done, the server will most probably return a '<not-authorized>' stanza back and disconnect (so says RFC3920 section 7).


A boolean indicating whether to initiate a session if so requested by the remote server. The default, 1, is for applications that do not wish to deal with this step, or for people for whom urn:ietf:params:xml:ns:xmpp-session is at a significant altitude. If you know what you are doing, set this to 0, and be sure to read the ->session() method. Note that if the server requires sessions, and this is not done, the server will most probably return a '<not-authorized>' stanza back and disconnect (so says RFC3921 section 3).


A boolean indicating whether a random Resource identifier can be used in the case of conflicts. Defaults to 0.

It returns 1 on success, and 0 on failure.


This accepts the same arguments as ->authenticate(), but returns after sending the initial packets required to start the authentication steps.

Note: This method will block on older servers where ->listauths() has to ask for a packet.


This tests to see whether the current authentication steps have succeeded. It returns -1 if not yet, 0 if failed and 1 if successful. It takes a hash of:

        RunProcess - Invoke ->process internally
        ProcessTime - time to pass to ->process (default 0 )

If RunProcess is not specified, you will have to invoke ->process() seperately.


This is the Jabber::Connection compatibility call. It takes 1 or 3 arguments, being either the shared password (for use when connecting as a component), or the username, password and resource. It returns 1 if successful, 0 if unsuccessful.


This is the Net::XMPP::Protocol/Net::Jabber::Component compatibility call. It takes a hash of 'username', 'password' and 'resource', or "secret" and returns a @list of two values, being a success ('ok')/failure string, and a message. Note that apart from 'ok', the success/failure string may not be the same as returned by the Net::XMPP libraries.

METHODS - Dealing with <stream:features>

Some incidental things.


This method returns the latest <stream:features> tag received from the server, or undef. It is used internally by the ->bind and ->session methods.

Note that during the ->connect() and ->authenticate() phases, certain of these features may get 'used', and thus not returned by the server the next time it issues a <stream:features> tag.


This method lists the authentication methods available either to the library or provided by this Jabber server by way of <stream:features>. An optional hash may be provided, where 'Ask' triggers the asking of the server for authentication information according to the 'jabber:iq:auth' namespace (JEP-0078), with the optional 'Username' being supplied as required.

The return value is either an @array or %hash of possible authentication methods and mechanisms depending on the 'Want' option ('array' or 'hash'), arranged as per 'method-mechanism', eg 'sasl-digest-md5' or 'jabber:iq:auth-plain'.

This method should be called after ->connect(), obviously.

Note: If Ask (or JustAsk) is specified, this method will call ->process, until it gets the reply it is expecting. If other packets are expected during this time, use ->register_handler to set up callbacks for them, making sure that any <iq> packets in the 'jabber:iq:auth' namespace (<query> subtag) are not swallowed.


Starts a session with the remote server, if required by the <stream:features> packet. Called internally by ->authenticate() if DoSession is set as the default '1'. Takes an optional hash of:


A string of either 'if-required' or 'always', indicating whether to always do so, or just if required to do so.

Returns 1 if successful, 0 otherwise.


Checks to see if the session establishment has completed, returning -1 on still going, 0 on refused and 1 on success.


Binds a Resource value to the connection, if required by the <stream:features> packet. Called internally by ->authenticate() if DoBind is set as the default '1'. Takes an optional hash of:


A string of either 'if-required' or 'always', indicating whether to always do so, or just if required to do so.


A Resource string to use.


Start using a random resource if the requested Resource was rejected by the server.

Returns 1 if successful, 0 otherwise. If successful, will update the value used by ->connect_jid().


Background version of bind. Takes the same arguments as the ->bind() call.


Technically this should be 'bgbound', but for consistency with other 'bg' methods, its named this way. Checks to see if the binding has completed, returning -1 on still going, 0 on refused and 1 on success.

METHODS - Handling Packets


This clears any handlers that have been put on the object. Some applications may wish to do this after the standard ->connect and ->authenticate methods have returned successfully, as these use handlers to do their jobs.

Alternatively, specifying a 'Class' of 'connect' and 'authenticate' will remove just the handlers created by ->connect and ->authenticate respectively.

WARNING: The standard ->connect and ->authenticate (and/or their bg varients) require their configured handlers to be in place. Do not execute ->clear_handlers between ->connect and ->authenticate, lest your application suddenly fail to work.

This takes a hash of optional arguments, being 'Type' and 'Class'. The 'Type' is the same as the Type supplied to 'register_handler', and if supplied, will delete all callbacks of that Type. The 'Class' is the same as the optional Class supplied to 'register_handler', and if supplied, will delete all callbacks of that class.


Record a packet type and a subroutine to be invoked when the matching packet type is received. Multiple handlers for the same packet type can be registered. Each of these handlers is called in succession with the received packet until one returns the constant r_HANDLED .

Each handler is invoked with two arguments; the object representing the current packet, and a value received from calls to previous handlers. so-called 'parcel' or 'persistent' data. The return value is either the r_HANDLED constant or parcel/persistent data to be handed to the next handler.

Note: See notes regarding handlers under ->process.

Note: The ->connect and ->authenticate methods use handlers to function.

Note: A third argument can be supplied to indicate the 'class' of this handler, for usage with ->clear_handlers. If not supplied, defaults to 'user'.


Records a time interval and a subroutine to be invoked when the appropriate time period has elapsed. Takes a hash of:


The frequency which this subroutine should be executed, in seconds.


A reference to the actual subroutine. Since I keep forgetting how to do so myself, if you want to call an object-based method with your working object, you do so via 'Sub => sub { $objname->some_method(@_) }'


If supplied, will be supplied as the second argument.


A boolean as to whether this routine should be executed just once (after Interval seconds). Defaults to 0.


A boolean as to whether this routine's first execution should be the next time ->process() is invoked, or after Interval seconds have elapsed. Defaults to 0.

The subroutine is invoked with a single argument of the current connection object (in case you want to send something), and the value of the 'Argument' hash if supplied.

Note: These are executed as a side-effect of running ->process(). If you do not regularly invoke ->process() (or via ->start()), these timeouts will not be invoked. Executing ->process() from within the handler may cause odd things to happen.


This is the Jabber::Connection compatibility call, and takes two arguments, a time interval and a subroutine. Invokes ->register_interval .


For most applications, this is the function to use. It checks to see if anything is available to be read on the socket, reads it in, and returns a success (or otherwise) value. It takes an optional timeout argument, for how long the ->can_read() call can hang around for (default 0).

The values returned, which MUST be checked on each call, are:

        -2: Invalid XML was read.

        -1: EOF was reached.

         0: No action.  Data may or may not have been read.

         1: A complete object has been read, and is available for
            retrieval via get_latest().

         2: A complete object was read, but was eaten 
            by a defined handler.

Note that after a complete object has been read, any further calls to ->process() will not create additional objects until the current complete object has been retrieved via ->get_latest(). This does not apply if the object was eaten/accepted by a defined handler.

Note: ->process() is a wrapper around ->can_read() and ->do_read(), but it executes handlers as well. ->process will return after every packet read (imho, a better behaviour than simply reading from the socket until the remote end stops sending us data).


Sends either text or an object down the connected socket. Returns a count of the number of bytes read. Will return '-1' if an error occured and the text was not sent.

Note that if you send non-XML data (gibberish or incomplete), thats your problem, not mine.

METHODS - So Long, and Thanks for all the <fish/>


Disconnect from the Jabber server by sending the closing tags and then closing the connection. Note that no closing '</presence>' tag is sent, but the closing </stream:stream> tag is sent.


Close the connection abruptly. If the connection is not to a Jabber server, use abort() instead of disconnect().

METHODS - These are a few of my incidental things


Returns (or sets) the socket that this object is using. This is provided to support a parent program designed around its own IO::Select() loop. A previously opened socket/filehandle can be supplied as the argument.

Note: The library uses sysread() and send/syswrite() as required. Passing in filehandles that do not support these functions is probably a bad idea.

Note: There is some juggling of sockets within the ->connect method when SSL starts up. Whilst a select() on the original, or parent socket will probably still work, it would probably be safer to not include the socket returned by ->socket() in any select() until the ->connect() and ->authenticate methods have returned.


Checks to see whether there is anything further on the socket. Returns 1 if there is data to be read, 0 otherwise.


Checks to see whether the socket can be written to. Returns 1 if so, 0 otherwise.


Reads in the latest text from the socket, and submits it to be added to the current XML object. Returns:

-2 if the parsing indicated invalid XML,
-1 if the socket reached EOF,
0 if the socket was ok and data was read happily.
1 if there is a complete object (use ->get_latest() )

Applications MUST check the return value on each call. Takes a hash of optional arguments, the most important being:

        PendingOnly (default 0) - Only process the pending data, do not
        attempt to read from the socket.

->do_read also checks the maxobjectsize, maxobjectdepth and maxnamesize.

->do_read also checks the likely size of the object as it is being read. If it is larger than the maxobjectsize value passed to ->new/->init, the appropriate behaviour will be taken. Note that if the behaviour chosen is to continue parsing but not save (the default), then an attack consisting of <foo><foo><foo> repeated ad nauseum will still eventually exhaust memory.

This is because to properly parse the object, the parser must know at which point the object is at, meaning that the name of each <tag> must be stored.


Sees whether the socket is still around, based on the last call to ->do_read(). Returns 1 if the socket is at EOF, 0 if the socket not at EOF.


Returns 1 or 0 whether this connection has been authenticated yet.


Returns 1 or 0 whether this connection is currently connected.


Returns 1 or 0 whether this connection is currently encrypted.


Returns the JID currently associated with this connection, or undef.

_connect_starttls handler

This is a helper function (for ->connect) for the starting up of TLS/SSL via the <starttls> tag.

_connect_handler handler

This is a helper function (for ->connect) for the handling of some initial tags.


This returns the version supplied by the last <?xml?> tag received.


This returns the encoding supplied by the last <?xml?> tag received.

METHODS - Object common

These are for the library as XML parser, creating new objects, reading attributes etc.


Returns the latest complete object or undef. This function is only valid on the parent connection object.

WARNING: This is a destructive process; a second call will return undef until another object has been read.


This returns a copy of the latest object, whether or not it is actually complete. An optional argument may be supplied, which will be used to replace the current object.

WARNING: This may return objects which are incomplete, and may not make too much sense. Supplying an argument which is not of this class may produce odd results.


This clears the latest object.


Creates a new Node or tag, and returns the object thus created. Takes two arguments, being a required name for the object, and an optional xmlns value. Returns undef if a name was not supplied.

A previously created object can be supplied instead.


Creates a new Node or tag from a supplied string, and returns the object thus created. Takes a single argument, being the string for the object. Returns undef if a string was not supplied.

Note: If there was more than one object in the string, the remaining string is tossed away; you only get one object back.


Inserts a tag into the current object. Takes the same arguments as ->newNode, and returns the object created.


Returns, or sets, the name of the object. Takes an optional argument for the new name.

Note: No checking or escaping is done on the supplied name.


Return 1 or 0 whether the current object is complete.


Return an @array of subobjects.


Return a specific child tag if it exists. Takes the name of the tag, and optionally the xmlns value of the tag (first found wins in the case of duplicates).


Return an @array of attributes on the current object.


Return or set the contents of an attribute. Takes an attribute name as the first argument, and the optional attribute contents (replacing anything there) as the second argument.


Sets or returns the value of the xmlns attribute.


Returns or sets the data associated with this object. Take an optional argument supplying the data to replace any existing data. Performs encoding/decoding of common XML escapes.


The same as ->data(), but without the encodings/decodings used. Make sure anything that you add doesn't include valid XML tag characters, or something else will break.


Returns the parent object of the current object, or undef.


Remove references to the current object from the parent object, effectively deleting it. Returns 1 if successful, 0 if no valid parent. If there are any child-objects, removes references to this object from them.


Remove references to a child object. Takes an argument of a child object to delete. Returns 1 if successful, 0 if not.


This routine removes references to this object, and to objects below it. In certain versions of perl, this may assist with cleanup.


Returns the object in a single string. Takes an optional hash consisting of 'FH', being a filehandle reference to send output to instead (useful if you aren't wanting to copy the object into a local variable), and 'GenClose', which defaults to 1 and ensures that the first tag has the proper '/' character when closing the tag.

If set to '0', '<stream>' will be output instead of '<stream/>', a highly important distinction when first connecting to Jabber servers (remember that a Jabber connection is really one long '<stream>' tag ).


This is the Net::XMPP::Stanza compatibility call, and simply invokes ->toStr. Note for Ryan: where is ->GetXML actually documented?

METHODS - Object detailed and other stuff.


Creates and returns a new instance of an object. Invoked by ->do_read() and ->parse_more(). Takes as an optional argument some text to parse.

Returns the new object (or undef), a success value, and any unprocessed text. Success values can be one of:

        -2 Invalid XML
        0 No errors
        1 Complete object


Parses some text and adds it to an existing object. Creates further sub-objects as appropriate. Returns a success value, and any unprocessed text. Success values can be one of:

        -2 if a parsing error was found.
        0 if no obvious bugs were found.
        1 if a complete object was found.

The parser, such as it is, will sometimes return text to be prepended with any new text. If the calling application does not keep track of the returned text and supply it the next time, the parser's behaviour is undefined. Most applications will be invoking ->parse_more() via ->do_read or ->process(), so this situation will not come up.

This needs

An optional second argument can be supplied which, if 1, will inhibit the saving of most text to memory. This is used by do_read to indicate that an excessively-large object is being read.


Returns the current status of the parser on the current object. Used by the ->connect method, but may be useful in debugging the parser.


When passed a string, returns the string with appropriate XML escapes put in place, eg '&' to '&amp;', '<' to '&lt;' etc.


When passed a string, returns the string with the XML escapes reversed, eg '&amp;' to '&' and so forth.


When passed an '&' escape string, will return the text that it expands to, based on both a set of predefined escapes, and any escapes that may have been _previously_ defined within the document. Will return undef if it cannot expand the string.

This function is non-intuitive, as it will replace 'amp' with 'amp', but 'pre-defined-escape' with 'text that was declared in the <!ENTITY> declaration for pre-defined-escape'. Its prime usage is in the storage of hopefully-compliant-XML data into the object, and is used as part of the data verification routines.


This helper function keeps several xmlns strings in one place, to make for easier (sic) upgrading. It takes one argument, and returns the result of that argument's lookup.


Helper function to load Net::DNS into the current namespace.


Helper function to load Digest::SHA1 into the current namespace.


Helper function to load Digest::MD5 into the current namespace.


Helper function to load Authen::SASL into the current namespace.


Helper function to load MIME::Base64 into the current namespace.


Helper function to load IO::Socket::SSL into the current namespace.


Debug is vor finding de bugs!

Prints the supplied string, along with some other useful information, to STDERR, if the initial object was created with the debug flag.


Returns the major version of the library.


September 2005: During implementation of a Jabber-based project, the author encountered a machine which for political reasons, could not be upgraded to a version of perl which supported a current version of various Jabber libraries. After getting irritated with having to build a completely new standalone perl environment, together with the ~10 meg, no 11, no 12, no 15 (etc), footprint of libraries required to support XML::Parser, the desire for a lightweight Jabber library was born.

December 2005: The author, merrily tossing large chunks of data through his Jabber servers, discovered that XML::Parser does not deal with large data sizes in a graceful fashion.

January 2006: The author completed a version which would, at least, not barf on most things.

January through September 2006: Being busy with other things, the author periodically ran screaming from memory leakage problems similar to XML::Parser.. Finally, a casual mention in one of the oddest places lead the author to a good explanation of how Perl does not deal with circular dependencies.


IO::Socket::INET, IO::Select . Thats it. Although, if you want encryption on your connection, SASL support or reasonable garbage collection in various versions of perl, there are soft dependencies on:


Library for handling SSL/TLS encryption.


This is used for some authentication methods.


SASL magic. Hooray.


This is used for some authentication methods.


Helps with memory management, saving this library from being caught in the hell of circular dependencies, which in turn avoids circular dependencies from making the use of this library hell on memory, which if I remember avoids the circular dependency hell.


Perl's garbage collection is at times rather dubious. A prime example is when you have double-linked lists, otherwise known as circular references. Since both objects refer to each other (in recording parent <-> child relationships), perl does not clean them up until the end of the program. Whilst this library does do some tricks to get around this in newer versions of perl, involving proxy objects and 'weaken' from Scalar::Util , this library may leak memory in older versions of perl. Invoking ->hidetree on a retrieved object before it falls out of scope is recommended (the library does this on some internal objects, perhaps obsessively). Note that you may need to create a copy of a object via newNodeFromStr/toStr due to this.


Bruce Campbell, Zerlargal VOF, 2005-7 . See


Copyright (c) 2005-7 Bruce Campbell. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


I am primarily a Sysadmin, and like Perl programmers, Sysadmins are lazy by nature. So, bits of this library were copied from other, existing libraries as follows:

        encode(), decode() and some function names: Jabber::NodeFactory.
        ConstXMLNS(), SASL handling: XML::Stream