I use a Git
that sends commit notifications to a Jabber server using the
For the first year or so of its operation, the hook would connect to the
Jabber server (first jabberd 1.4, later
Ejabberd) that I ran on oryx.com,
and send the commit message as email@example.com, and all was well. Recently,
we reorganised our servers. The git repository stayed in the same place,
but we wanted it to connect to the Jabber server on aox.toroid.org and
send notifications as firstname.lastname@example.org.
I run Ejabberd on toroid.org too, and it was the work of a moment to add
aox.org to its list of hostnames and create an account for email@example.com.
But when I tried to make my hook connect to the new server, I discovered
Net::XMPP does not allow me to specify the name of the
server independently of the hostname in the Jabber ID:
my $client = new Net::Jabber::Client ();
hostname => 'aox.toroid.org',
) or die "Can't connect: $!\n";
my @r = $client->AuthSend(
username => 'git',
password => '...',
resource => 'aox.git'
die "Cannot authenticate (@r)\n" if $r ne "ok";
This code would connect to aox.toroid.org and try to authenticate as
firstname.lastname@example.org. Changing hostname to "aox.org" didn't work (even
though we had SRV records pointing to the right server). Changing the
username to "email@example.com" didn't work either. I spent some time looking
through the code and a tcpdump of the session to understand the problem.
It turns out that an XMPP session begins with a
<stream> element like this:
What is needed is to connect to aox.toroid.org and send
to='aox.org' in the stream, because Ejabberd rejects
connections to a hostname not listed in its configuration.
XML::Stream (the underlying
module) use the hostname passed to
Connect() to decide
where to connect and what to send in the
XML::Stream did support SRV lookups, but it
would replace the hostname with the result of the lookup and
use that name to compose the stream; and
Net::XMPP had no
way to enable the SRV lookups anyway.
I whipped up a patch to solve these problems. It adds "servername" and
"srv" parameters to the
Connect() method, which are passed
XML::Stream. If the servername is specified, it is
used to decide where to connect (and if not, the old behaviour remains
unchanged). The srv parameter enables SRV lookups, and the results are
used to set (only) the servername; but the hostname is used to compose
the stream in every case. Thus the two are separated enough for my hook
to work again.
I sent my patch to the module maintainers, but did not receive a reply.
The patch is archived here.
It applies to
Net::XMPP 1.02 and
1.23, but may need minor tweaking to apply cleanly to other versions.