ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.34
Committed: Fri Jul 20 20:41:48 2007 UTC (19 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.33: +19 -13 lines
Log Message:
lots of changes. added as_string to Net::XMPP2::Node to restore
the original xml document part of a stanza or subtree.
also implemented the jabber component protocol.

File Contents

# User Rev Content
1 elmex 1.1 package Net::XMPP2::Connection;
2     use strict;
3     use AnyEvent;
4     use IO::Socket::INET;
5     use Net::XMPP2::Parser;
6     use Net::XMPP2::Writer;
7 elmex 1.10 use Net::XMPP2::Util qw/split_jid/;
8 elmex 1.9 use Net::XMPP2::Event;
9     use Net::XMPP2::SimpleConnection;
10 elmex 1.1 use Net::XMPP2::Namespaces qw/xmpp_ns/;
11 elmex 1.28 use Net::XMPP2::Extendable;
12 elmex 1.10 use Net::XMPP2::Error;
13 elmex 1.1 use Net::DNS;
14 elmex 1.2
15 elmex 1.28 our @ISA = qw/Net::XMPP2::SimpleConnection Net::XMPP2::Event Net::XMPP2::Extendable/;
16 elmex 1.1
17     =head1 NAME
18    
19 elmex 1.23 Net::XMPP2::Connection - XML stream that implements the XMPP RFC 3920.
20 elmex 1.1
21     =head1 SYNOPSIS
22    
23     use Net::XMPP2::Connection;
24    
25     my $con =
26     Net::XMPP2::Connection->new (
27     username => "abc",
28     domain => "jabber.org",
29     resource => "Net::XMPP2"
30     );
31    
32     $con->connect or die "Couldn't connect to jabber.org: $!";
33     $con->init;
34     $con->reg_cb (stream_ready => sub { print "XMPP stream ready!\n" });
35    
36     =head1 DESCRIPTION
37    
38     This module represents a XMPP stream as described in RFC 3920. You can issue the basic
39     XMPP XML stanzas with methods like C<send_iq>, C<send_message> and C<send_presence>.
40    
41     And receive events with the C<reg_cb> event framework from the connection.
42    
43     If you need instant messaging stuff please take a look at C<Net::XMPP2::IM::Connection>.
44    
45     =head1 METHODS
46    
47 elmex 1.20 =over 4
48    
49     =item B<new (%args)>
50 elmex 1.1
51     Following arguments can be passed in C<%args>:
52    
53     =over 4
54    
55     =item language => $tag
56    
57     This should be the language of the human readable contents that
58     will be transmitted over the stream. The default will be 'en'.
59    
60     Please look in RFC 3066 how C<$tag> should look like.
61    
62 elmex 1.10 =item jid => $jid
63    
64     This can be used to set the settings C<username>, C<domain>
65     (and optionally C<resource>) from a C<$jid>.
66    
67 elmex 1.1 =item resource => $resource
68    
69     If this argument is given C<$resource> will be passed as desired
70     resource on resource binding.
71    
72     Note: You have to take care that the stringprep profile for
73     resources can be applied at: C<$resource>. Otherwise the server
74     might signal an error. See L<Net::XMPP2::Util> for utility functions
75     to check this.
76    
77     =item domain => $domain
78    
79     This is the destination host we are going to connect to.
80     As the connection won't be automatically connected use C<connect>
81     to initiate the connect.
82    
83     Note: A SRV RR lookup will be performed to discover the real hostname
84     and port to connect to. See also C<connect>.
85    
86 elmex 1.9 =item override_host => $host
87     =item override_port => $port
88    
89     This will be used as override to connect to.
90    
91 elmex 1.1 =item port => $port
92    
93     This is optional, the default port is 5222.
94    
95     Note: A SRV RR lookup will be performed to discover the real hostname
96     and port to connect to. See also C<connect>.
97    
98     =item username => $username
99    
100     This is your C<$username> (the userpart in the JID);
101    
102     Note: You have to take care that the stringprep profile for
103     nodes can be applied at: C<$username>. Otherwise the server
104     might signal an error. See L<Net::XMPP2::Util> for utility functions
105     to check this.
106    
107     =item password => $password
108    
109     This is the password for the C<username> above.
110    
111 elmex 1.5 =item disable_ssl => $bool
112    
113     If C<$bool> is true no SSL will be used.
114    
115 elmex 1.1 =back
116    
117     =cut
118    
119     sub new {
120     my $this = shift;
121     my $class = ref($this) || $this;
122 elmex 1.34 my $self =
123     $class->SUPER::new (
124     language => 'en',
125     stream_namespace => 'client',
126     @_
127     );
128 elmex 1.1
129     $self->{parser} = new Net::XMPP2::Parser;
130     $self->{writer} = Net::XMPP2::Writer->new (
131 elmex 1.33 write_cb => sub { $self->write_data ($_[0]) },
132     send_iq_cb => sub { $self->event (send_iq_hook => @_) },
133     send_msg_cb => sub { $self->event (send_message_hook => @_) },
134     send_pres_cb => sub { $self->event (send_presence_hook => @_) },
135 elmex 1.1 );
136    
137     $self->{parser}->set_stanza_cb (sub {
138     $self->handle_stanza (@_);
139     });
140 elmex 1.19 $self->{parser}->set_error_cb (sub {
141 elmex 1.29 my ($ex, $data, $type) = @_;
142     if ($type eq 'xml') {
143     my $pe = Net::XMPP2::Error::Parser->new (exception => $_[0], data => $_[1]);
144     $self->event (xml_parser_error => $pe);
145     $self->disconnect ("xml error: $_[0], $_[1]");
146     } else {
147     my $pe = Net::XMPP2::Error->new (
148     text => "uncaught exception in stanza handling: $ex"
149     );
150     $self->event (uncaught_exception_error => $pe);
151     $self->disconnect ($pe->string);
152     }
153 elmex 1.19 });
154 elmex 1.1
155 elmex 1.15 $self->{iq_id} = 1;
156     $self->{default_iq_timeout} = 60;
157 elmex 1.1
158     $self->{disconnect_cb} = sub {
159     my ($host, $port, $message) = @_;
160 elmex 1.7 delete $self->{authenticated};
161     delete $self->{ssl_enabled};
162 elmex 1.1 $self->event (disconnect => $host, $port, $message);
163     };
164    
165 elmex 1.10 if ($self->{jid}) {
166     my ($user, $host, $res) = split_jid ($self->{jid});
167     $self->{username} = $user;
168     $self->{domain} = $host;
169     $self->{resource} = $res if defined $res;
170     }
171    
172 elmex 1.28 my $proxy_cb = sub {
173     my ($self, $er) = @_;
174     $self->event (error => $er);
175     1
176     };
177    
178     $self->reg_cb (
179     xml_parser_error => $proxy_cb,
180     sasl_error => $proxy_cb,
181     stream_error => $proxy_cb,
182     bind_error => $proxy_cb,
183 elmex 1.31 iq_result_cb_exception => sub {
184     my ($self, $ex) = @_;
185     $self->event (error =>
186     Net::XMPP2::Error::Exception->new (
187     exception => $ex, context => 'iq result callback execution'
188     )
189     );
190     1
191     },
192 elmex 1.28 tls_error => sub {
193     my ($self) = @_;
194     $self->event (error =>
195     Net::XMPP2::Error->new (text => 'tls_error: tls negotiation failed')
196     );
197     1
198     },
199     );
200    
201 elmex 1.1 return $self;
202     }
203    
204 elmex 1.20 =item B<connect ($no_srv_rr)>
205 elmex 1.1
206     Try to connect to the domain and port passed in C<new>.
207    
208     A SRV RR lookup will be performed on the domain to discover
209     the host and port to use. If you don't want this set C<$no_srv_rr>
210     to a true value. C<$no_srv_rr> is false by default.
211    
212     As the SRV RR lookup might return multiple host and you fail to
213     connect to one you might just call this function again to try a
214     different host.
215    
216     If C<connect> was successful and we connected a true value is returned.
217     If the connect was unsuccessful undef is returned and C<$!> will be set
218     to the error that occured while connecting.
219    
220     If you want to know whether further connection attempts might be more
221     successful (as SRV RR lookup may return multiple hosts) call C<may_try_connect>
222     (see also C<may_try_connect>).
223    
224     Note that an internal list will be kept of tried hosts. Use
225     C<reset_connect_tries> to reset the internal list of tried hosts.
226    
227     =cut
228    
229     sub connect {
230     my ($self, $no_srv_rr) = @_;
231    
232     my ($host, $port) = ($self->{domain}, $self->{port} || 5222);
233 elmex 1.9 if ($self->{override_host}) {
234 elmex 1.34 $host = $self->{override_host};
235     $port = $self->{override_port} if defined $self->{override_port};
236 elmex 1.1
237 elmex 1.9 } else {
238     unless ($no_srv_rr) {
239     my $res = Net::DNS::Resolver->new;
240     my $p = $res->query ('_xmpp-client._tcp.'.$host, 'SRV');
241     if ($p) {
242     my @srvs = grep { $_->type eq 'SRV' } $p->answer;
243     if (@srvs) {
244     @srvs = sort { $a->priority <=> $b->priority } @srvs;
245     @srvs = sort { $b->weight <=> $a->weight } @srvs; # TODO
246     $port = $srvs[0]->port;
247     $host = $srvs[0]->target;
248     }
249 elmex 1.1 }
250     }
251     }
252    
253     if ($self->SUPER::connect ($host, $port)) {
254     $self->event (connect => $host, $port);
255     return 1;
256     } else {
257     return undef;
258     }
259     }
260    
261 elmex 1.20 =item B<may_try_connect>
262 elmex 1.1
263     Returns the number of left alternatives of hosts to connect to for the
264     domain passed to C<new>.
265    
266     An internal list of tried hosts will be managed by C<connect> and those
267     hosts will be ignored by a SRV RR lookup (which will be done if you
268     call this function).
269    
270     Use C<reset_connect_tries> to reset the internal list of tried hosts.
271    
272     =cut
273    
274     sub may_try_connect {
275     # TODO
276     }
277    
278 elmex 1.20 =item B<reset_connect_tries>
279 elmex 1.1
280     This function resets the internal list of tried hosts for C<connect>.
281     See also C<connect>.
282    
283     =cut
284    
285     sub reset_connect_tries {
286     # TODO
287     }
288    
289     sub handle_data {
290     my ($self, $buf) = @_;
291     $self->event (debug_recv => $$buf);
292     $self->{parser}->feed (substr $$buf, 0, (length $$buf), '');
293     }
294    
295 elmex 1.5 sub debug_wrote_data {
296     my ($self, $data) = @_;
297     $self->event (debug_send => $data);
298     }
299    
300 elmex 1.1 sub write_data {
301     my ($self, $data) = @_;
302     $self->SUPER::write_data ($data);
303     }
304    
305     sub handle_stanza {
306     my ($self, $p, $node) = @_;
307    
308 elmex 1.18 if (not defined $node) { # got stream end
309     $self->disconnect ("end of 'XML' stream encountered");
310     return;
311     }
312    
313 elmex 1.31 $self->event (recv_stanza_xml => $node);
314    
315 elmex 1.1 if ($node->eq (stream => 'features')) {
316     $self->event (stream_features => $node);
317 elmex 1.28 $self->{features} = $node;
318 elmex 1.1 $self->handle_stream_features ($node);
319 elmex 1.5
320 elmex 1.2 } elsif ($node->eq (tls => 'proceed')) {
321     $self->enable_ssl;
322     $self->{parser}->init;
323     $self->{writer}->init;
324 elmex 1.34 $self->{writer}->send_init_stream (
325     $self->{language}, $self->{domain}, $self->{stream_namespace}
326     );
327 elmex 1.2
328 elmex 1.11 } elsif ($node->eq (tls => 'failure')) {
329     $self->event ('tls_error');
330     $self->disconnect ('TLS failure on TLS negotiation.');
331    
332 elmex 1.1 } elsif ($node->eq (sasl => 'challenge')) {
333     $self->handle_sasl_challenge ($node);
334 elmex 1.11
335 elmex 1.1 } elsif ($node->eq (sasl => 'success')) {
336     $self->handle_sasl_success ($node);
337 elmex 1.11
338     } elsif ($node->eq (sasl => 'failure')) {
339     my $error = Net::XMPP2::Error::SASL->new (node => $node);
340     $self->event (sasl_error => $error);
341 elmex 1.28 $self->disconnect ('SASL authentication failure: ' . $error->string);
342 elmex 1.11
343 elmex 1.1 } elsif ($node->eq (client => 'iq')) {
344 elmex 1.32 $self->event (iq_xml => $node);
345 elmex 1.1 $self->handle_iq ($node);
346 elmex 1.11
347 elmex 1.4 } elsif ($node->eq (client => 'message')) {
348 elmex 1.6 $self->event (message_xml => $node);
349 elmex 1.11
350 elmex 1.4 } elsif ($node->eq (client => 'presence')) {
351 elmex 1.6 $self->event (presence_xml => $node);
352 elmex 1.11
353 elmex 1.1 } elsif ($node->eq (stream => 'error')) {
354     $self->handle_error ($node);
355     }
356     }
357    
358 elmex 1.20 =item B<init ()>
359 elmex 1.1
360     Initiate the XML stream.
361    
362     =cut
363    
364     sub init {
365     my ($self) = @_;
366 elmex 1.34 $self->{writer}->send_init_stream ($self->{language}, $self->{domain}, $self->{stream_namespace});
367 elmex 1.1 }
368    
369 elmex 1.20 =item B<is_connected ()>
370 elmex 1.10
371     Returns true if the connection is still connected and stanzas can be
372     sent.
373    
374     =cut
375    
376     sub is_connected {
377     my ($self) = @_;
378     $self->{authenticated}
379     }
380    
381 elmex 1.20 =item B<set_default_iq_timeout ($seconds)>
382 elmex 1.15
383     This sets the default timeout for IQ requests. If the timeout runs out
384     the request will be aborted and the callback called with a L<Net::XMPP2::Error::IQ> object
385 elmex 1.22 where the C<condition> method returns a special value (see also C<condition> method of L<Net::XMPP2::Error::IQ>).
386 elmex 1.15
387     The default timeout for IQ is 60 seconds.
388    
389     =cut
390    
391     sub set_default_iq_timeout {
392     my ($self, $sec) = @_;
393     $self->{default_iq_timeout} = $sec;
394     }
395    
396 elmex 1.20 =item B<send_iq ($type, $create_cb, $result_cb, %attrs)>
397 elmex 1.1
398     This method sends an IQ XMPP request.
399    
400     Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
401 elmex 1.15 about the meaning of C<$type>, C<$create_cb> and C<%attrs> (with the exception
402     of the 'timeout' key of C<%attrs>, see below).
403 elmex 1.1
404 elmex 1.15 C<$result_cb> will be called when a result was received or the timeout reached.
405     The first argument to C<$result_cb> will be a Net::XMPP2::Node instance
406     containing the IQ result stanza contents.
407 elmex 1.1
408     If the IQ resulted in a stanza error the second argument to C<$result_cb> will
409     be C<undef> (if the error type was not 'continue') and the third argument will
410 elmex 1.10 be a L<Net::XMPP2::Error::IQ> object.
411 elmex 1.1
412 elmex 1.15 The timeout can be set by C<set_default_iq_timeout> or passed seperatly
413     in the C<%attrs> array as the value for the key C<timeout> (timeout in seconds btw.).
414    
415 elmex 1.4 This method returns the newly generated id for this iq request.
416    
417 elmex 1.1 =cut
418    
419     sub send_iq {
420     my ($self, $type, $create_cb, $result_cb, %attrs) = @_;
421     my $id = $self->{iq_id}++;
422     $self->{iqs}->{$id} = $result_cb;
423 elmex 1.15
424     my $timeout = delete $attrs{timeout} || $self->{default_iq_timeout};
425     if ($timeout) {
426     $self->{iq_timers}->{$id} =
427 elmex 1.25 AnyEvent->timer (after => $timeout, cb => sub {
428 elmex 1.16 delete $self->{iq_timers}->{$id};
429 elmex 1.15 my $cb = delete $self->{iqs}->{$id};
430 elmex 1.16 $cb->(undef, Net::XMPP2::Error::IQ->new)
431 elmex 1.15 });
432     }
433    
434 elmex 1.1 $self->{writer}->send_iq ($id, $type, $create_cb, %attrs);
435 elmex 1.4 $id
436     }
437    
438 elmex 1.20 =item B<reply_iq_result ($req_iq_node, $create_cb, %attrs)>
439 elmex 1.4
440     This method will generate a result reply to the iq request C<Net::XMPP2::Node>
441     in C<$req_iq_node>.
442    
443     Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
444     about the meaning C<$create_cb> and C<%attrs>.
445    
446 elmex 1.6 Use C<$create_cb> to create the XML for the result.
447    
448 elmex 1.4 The type for this iq reply is 'result'.
449    
450     =cut
451    
452     sub reply_iq_result {
453     my ($self, $iqnode, $create_cb, %attrs) = @_;
454     $self->{writer}->send_iq ($iqnode->attr ('id'), 'result', $create_cb, %attrs);
455     }
456    
457 elmex 1.20 =item B<reply_iq_error ($req_iq_node, $error_type, $error, %attrs)>
458 elmex 1.4
459     This method will generate an error reply to the iq request C<Net::XMPP2::Node>
460     in C<$req_iq_node>.
461    
462     C<$error_type> is one of 'cancel', 'continue', 'modify', 'auth' and 'wait'.
463     C<$error> is one of the defined error conditions described in
464 elmex 1.22 C<write_error_tag> method of L<Net::XMPP2::Writer>.
465 elmex 1.4
466     Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
467 elmex 1.6 about the meaning of C<%attrs>.
468 elmex 1.4
469     The type for this iq reply is 'error'.
470    
471     =cut
472    
473     sub reply_iq_error {
474     my ($self, $iqnode, $errtype, $error, %attrs) = @_;
475    
476     $self->{writer}->send_iq (
477     $iqnode->attr ('id'), 'error',
478     sub { $self->{writer}->write_error_tag ($iqnode, $errtype, $error) },
479     %attrs
480     );
481 elmex 1.1 }
482    
483     sub handle_iq {
484     my ($self, $node) = @_;
485    
486 elmex 1.4 my $type = $node->attr ('type');
487    
488 elmex 1.15 my $id = $node->attr ('id');
489     delete $self->{iq_timers}->{$id} if defined $id;
490    
491 elmex 1.4 if ($type eq 'result') {
492 elmex 1.15 if (my $cb = delete $self->{iqs}->{$id}) {
493 elmex 1.27 eval {
494     $cb->($node);
495     };
496     if ($@) { $self->event (iq_result_cb_exception => $@) }
497 elmex 1.1 }
498 elmex 1.9
499 elmex 1.4 } elsif ($type eq 'error') {
500 elmex 1.15 if (my $cb = delete $self->{iqs}->{$id}) {
501 elmex 1.1
502 elmex 1.10 my $error = Net::XMPP2::Error::IQ->new (node => $node);
503     $cb->(($error->type eq 'continue' ? $node : undef), $error);
504 elmex 1.1 }
505 elmex 1.4
506     } else {
507     my $handled = 0;
508 elmex 1.6 $self->event ("iq_${type}_request_xml" => $node, \$handled);
509 elmex 1.4
510     my @from;
511     push @from, (to => $node->attr ('from')) if $node->attr ('from');
512    
513     unless ($handled) {
514 elmex 1.21 $self->reply_iq_error ($node, undef, 'service-unavailable', @from);
515 elmex 1.4 }
516 elmex 1.1 }
517     }
518    
519 elmex 1.12 sub send_sasl_auth {
520     my ($self, @mechs) = @_;
521 elmex 1.34
522     for (qw/username password domain/) {
523     die "No '$_' argument given to new, but '$_' is required\n"
524     unless $self->{$_};
525     }
526    
527 elmex 1.12 $self->{writer}->send_sasl_auth (
528     (join ' ', map { $_->text } @mechs),
529     $self->{username}, $self->{domain}, $self->{password}
530     );
531     }
532    
533 elmex 1.1 sub handle_stream_features {
534     my ($self, $node) = @_;
535     my @bind = $node->find_all ([qw/bind bind/]);
536 elmex 1.2 my @tls = $node->find_all ([qw/tls starttls/]);
537 elmex 1.13
538     # and yet another weird thingie: in XEP-0077 it's said that
539     # the register feature MAY be advertised by the server. That means:
540     # it MAY not be advertised even if it is available... so we don't
541     # care about it...
542     # my @reg = $node->find_all ([qw/register register/]);
543 elmex 1.1
544 elmex 1.5 if (not ($self->{disable_ssl}) && not ($self->{ssl_enabled}) && @tls) {
545 elmex 1.2 $self->{writer}->send_starttls;
546    
547 elmex 1.12 } elsif (not $self->{authenticated}) {
548 elmex 1.28 my $continue = 1;
549     $self->event (stream_pre_authentication => \$continue);
550     if ($continue) {
551     $self->authenticate;
552 elmex 1.12 }
553 elmex 1.1
554     } elsif (@bind) {
555     $self->do_rebind ($self->{resource});
556     }
557     }
558    
559 elmex 1.28 =item B<authenticate>
560    
561     This method should be called after the C<stream_pre_authentication> event
562     was emitted to continue authentication of the stream.
563    
564     Usually this method only has to be called when you want to register before
565     you authenticate. See also the documentation of the C<stream_pre_authentication>
566     event below.
567    
568     =cut
569    
570     sub authenticate {
571     my ($self) = @_;
572     my $node = $self->{features};
573     my @mechs = $node->find_all ([qw/sasl mechanisms/], [qw/sasl mechanism/]);
574     my @iqa = $node->find_all ([qw/iqauth auth/]);
575    
576     if (@mechs) {
577     $self->send_sasl_auth (@mechs)
578     } elsif (@iqa) {
579     $self->do_iq_auth;
580     }
581     }
582    
583 elmex 1.1 sub handle_sasl_challenge {
584     my ($self, $node) = @_;
585     $self->{writer}->send_sasl_response ($node->text);
586     }
587    
588     sub handle_sasl_success {
589     my ($self, $node) = @_;
590     $self->{authenticated} = 1;
591     $self->{parser}->init;
592     $self->{writer}->init;
593 elmex 1.34 $self->{writer}->send_init_stream ($self->{language}, $self->{domain}, $self->{stream_namespace});
594 elmex 1.1 }
595    
596     sub handle_error {
597     my ($self, $node) = @_;
598 elmex 1.10 my $error = Net::XMPP2::Error::Stream->new (node => $node);
599    
600 elmex 1.18 $self->event (stream_error => $error);
601 elmex 1.1 $self->{writer}->send_end_of_stream;
602     }
603    
604 elmex 1.18 sub do_iq_auth {
605     my ($self) = @_;
606     # TODO
607     }
608    
609 elmex 1.20 =item B<send_presence ($type, $create_cb, %attrs)>
610 elmex 1.4
611     This method sends a presence stanza, for the meanings
612     of C<$type>, C<$create_cb> and C<%attrs> please take a look
613 elmex 1.22 at the documentation for C<send_presence> method of L<Net::XMPP2::Writer>.
614 elmex 1.4
615     This methods does attach an id attribute to the message stanza and
616     will return the id that was used (so you can react on possible replies).
617    
618     =cut
619    
620     sub send_presence {
621     my ($self, $type, $create_cb, %attrs) = @_;
622     my $id = $self->{iq_id}++;
623     $self->{writer}->send_presence ($id, $type, $create_cb, %attrs);
624     $id
625     }
626    
627 elmex 1.20 =item B<send_message ($to, $type, $create_cb, %attrs)>
628 elmex 1.4
629     This method sends a presence stanza, for the meanings
630     of C<$to>, C<$type>, C<$create_cb> and C<%attrs> please take a look
631 elmex 1.22 at the documentation for C<send_message> method of L<Net::XMPP2::Writer>.
632 elmex 1.4
633     This methods does attach an id attribute to the message stanza and
634     will return the id that was used (so you can react on possible replies).
635    
636     =cut
637    
638     sub send_message {
639     my ($self, $to, $type, $create_cb, %attrs) = @_;
640     my $id = $self->{iq_id}++;
641     $self->{writer}->send_message ($id, $to, $type, $create_cb, %attrs);
642     $id
643     }
644    
645 elmex 1.20 =item B<do_rebind ($resource)>
646 elmex 1.1
647     In case you got a C<bind_error> event and want to retry
648     binding you can call this function to set a new C<$resource>
649     and retry binding.
650    
651     If it fails again you can call this again. Becareful not to
652     end up in a loop!
653    
654     If binding was successful the C<stream_ready> event will be generated.
655    
656     =cut
657    
658     sub do_rebind {
659     my ($self, $resource) = @_;
660     $self->{resource} = $resource;
661     $self->send_iq (
662     set =>
663     sub {
664     my ($w) = @_;
665     if ($self->{resource}) {
666     $w->startTag ([xmpp_ns ('bind'), 'bind']);
667     $w->startTag ([xmpp_ns ('bind'), 'resource']);
668     $w->characters ($self->{resource});
669     $w->endTag;
670     $w->endTag;
671     } else {
672     $w->emptyTag ([xmpp_ns ('bind'), 'bind'])
673     }
674     },
675     sub {
676 elmex 1.13 my ($ret_iq, $error) = @_;
677 elmex 1.1
678 elmex 1.13 if ($error) {
679 elmex 1.28 # TODO: make bind error into a seperate error class?
680 elmex 1.30 if ($error->xml_node ()) {
681     my ($res) = $error->xml_node ()->find_all ([qw/bind bind/], [qw/bind resource/]);
682     $self->event (bind_error => $error, ($res ? $res : $self->{resource}));
683     } else {
684     $self->event (bind_error => $error);
685     }
686 elmex 1.1
687     } else {
688     my @jid = $ret_iq->find_all ([qw/bind bind/], [qw/bind jid/]);
689     my $jid = $jid[0]->text;
690     unless ($jid) { die "Got empty JID tag from server!\n" }
691     $self->{jid} = $jid;
692    
693     $self->event (stream_ready => $jid);
694     }
695     }
696     );
697     }
698    
699 elmex 1.20 =item B<jid>
700 elmex 1.1
701     After the stream has been bound to a resource the JID can be retrieved via this
702     method.
703    
704     =cut
705    
706     sub jid { $_[0]->{jid} }
707    
708 elmex 1.20 =item B<features>
709 elmex 1.4
710     Returns the last received <features> tag in form of an L<Net::XMPP2::Node> object.
711    
712     =cut
713    
714     sub features { $_[0]->{features} }
715    
716 elmex 1.20 =back
717    
718 elmex 1.1 =head1 EVENTS
719    
720     These events can be registered on with C<reg_cb>:
721    
722     =over 4
723    
724 elmex 1.11 =item stream_features => $node
725 elmex 1.1
726 elmex 1.4 This event is sent when a stream feature (<features>) tag is received. C<$node> is the
727     L<Net::XMPP2::Node> object that represents the <features> tag.
728 elmex 1.1
729 elmex 1.28 =item stream_pre_authentication => $rcontinue
730    
731     This event is emitted after TLS/SSL was initiated (if enabled) and before any
732     authentication happened. C<$rcontinue> is a reference to a scalar that per default
733     holds a true value. If that scalar is true the authentication will continue
734     after handling this event. If you set C<$$rcontinue> to a false value
735     the authentication will stop and you have to call the C<authenticate>
736     method later.
737    
738     This event is usually used when you want to do in-band registration,
739     see also L<Net::XMPP2::Ext::Registration>.
740    
741 elmex 1.1 =item stream_ready => $jid
742    
743     This event is sent if the XML stream has been established (and
744     resources have been bound) and is ready for transmitting regular stanzas.
745    
746     C<$jid> is the bound jabber id.
747    
748 elmex 1.28 =item error => $error
749    
750     This event is generated whenever some error occured.
751     C<$error> is an instance of L<Net::XMPP2::Error>.
752     Trivial error reporting may look like this:
753    
754     $con->reg_cb (error => sub { warn "xmpp error: " . $_[1]->string . "\n"; 1 });
755    
756     Basically this event is a collect event for all other error events.
757    
758 elmex 1.10 =item stream_error => $error
759 elmex 1.6
760     This event is sent if a XML stream error occured. C<$error>
761 elmex 1.10 is a L<Net::XMPP2::Error::Stream> object.
762 elmex 1.6
763 elmex 1.28 =item xml_parser_error => $error
764    
765     This event is generated whenever the parser trips over XML that it can't
766     read. C<$error> is a L<Net::XMPP2::Error::Parser> object.
767    
768 elmex 1.11 =item tls_error
769    
770     This event is emitted when a TLS error occured on TLS negotiation.
771     After this the connection will be disconnected.
772    
773     =item sasl_error => $error
774    
775     This event is emitted on SASL authentication error.
776    
777 elmex 1.10 =item bind_error => $error, $resource
778 elmex 1.6
779 elmex 1.10 This event is generated when the stream was unable to bind to
780     any or the in C<new> specified resource. C<$error> is a L<Net::XMPP2::Error::IQ>
781     object. C<$resource> is the errornous resource string or undef if none
782     was received.
783 elmex 1.6
784 elmex 1.10 The C<condition> of the C<$error> might be one of: 'bad-request',
785     'not-allowed' or 'conflict'.
786 elmex 1.1
787 elmex 1.20 Node: this is untested, I couldn't get the server to send a bind error
788 elmex 1.1 to test this.
789    
790     =item connect => $host, $port
791    
792     This event is generated when a successful connect was performed to
793     the domain passed to C<new>.
794    
795     Note: C<$host> and C<$port> might be different from the domain you passed to
796     C<new> if C<connect> performed a SRV RR lookup.
797    
798     If this connection is lost a C<disconnect> will be generated with the same
799     C<$host> and C<$port>.
800    
801     =item disconnect => $host, $port, $message
802    
803     This event is generated when the connection was lost or another error
804     occured while writing or reading from it.
805    
806     C<$message> is a humand readable error message for the failure.
807     C<$host> and C<$port> were the host and port we were connected to.
808    
809     Note: C<$host> and C<$port> might be different from the domain you passed to
810     C<new> if C<connect> performed a SRV RR lookup.
811    
812 elmex 1.31 =item recv_stanza_xml => $node
813    
814     This event is generated before any processing of a "XML" stanza happens.
815     C<$node> is the node of the stanza that is being processed, it's of
816     type L<Net::XMPP2::Node>.
817    
818     This method might not be as handy for debuggin purposes as C<debug_recv>.
819    
820     =item send_stanza_data => $data
821    
822     This event is generated shortly before data is sent to the socket.
823     C<$data> contains a complete "XML" stanza or the end of stream closing
824     tag. This method is useful for debugging purposes and I recommend
825     using XML::Twig or something like that to display it nicely.
826    
827     See also the event C<debug_send>.
828    
829     =item debug_send => $data
830    
831     This method is invoked whenever data is written out. This event
832     is mostly the same as C<send_stanza_data>.
833    
834     =item debug_recv => $data
835    
836     This method is incoked whenever a chunk of data was received.
837    
838     It works to filter C<$data> through L<XML::Twig> for debugging
839     display purposes sometimes, but as C<$data> is some arbitrary chunk
840     of bytes you might get a XML parse error (did I already mention that XMPP's
841     application of "XML" sucks?).
842    
843     So you might want to use C<recv_stanza_xml> to detect
844     complete stanzas. Unfortunately C<recv_stanza_xml> doesn't have the
845     bytes anymore and just a datastructure (L<Net::XMPP2::Node>).
846    
847 elmex 1.6 =item presence_xml => $node
848 elmex 1.4
849     This event is sent when a presence stanza is received. C<$node> is the
850     L<Net::XMPP2::Node> object that represents the <presence> tag.
851    
852 elmex 1.6 =item message_xml => $node
853 elmex 1.4
854     This event is sent when a message stanza is received. C<$node> is the
855     L<Net::XMPP2::Node> object that represents the <message> tag.
856    
857 elmex 1.32 =item iq_xml => $node
858    
859     This event is emitted when a iq stanza arrives. C<$node> is the
860     L<Net::XMPP2::Node> object that represents the <iq> tag.
861    
862 elmex 1.6 =item iq_set_request_xml => $node, $handled_ref
863 elmex 1.4
864 elmex 1.6 =item iq_get_request_xml => $node, $handled_ref
865 elmex 1.4
866     These events are sent when an iq request stanza of type 'get' or 'set' is received.
867     C<$type> will either be 'get' or 'set' and C<$node> will be the L<Net::XMPP2::Node>
868     object of the iq tag.
869    
870     If C<$$handled_ref> is true an event handler should not handle this message anymore.
871    
872     If one of the event handlers handled this message the scalar pointed at by
873     the reference in C<$handled_ref> should be set to 1 true value. If C<$$handled_ref>
874     is still false after all event handlers were executed an error iq will be generated.
875    
876 elmex 1.27 =item iq_result_cb_exception => $exception
877    
878     If the C<$result_cb> of a C<send_iq> operation somehow threw a exception
879     or failed this event will be generated.
880    
881 elmex 1.33 =item send_iq_hook => $id, $type, $attrs, $rcreate_cbs
882    
883     This event lets you add any desired number of additional create callbacks
884     to a IQ stanza that is about to be sent.
885    
886     C<$id>, C<$type> are described in the documentation of C<send_iq> of L<Net::XMPP2::Writer>.
887     C<$attrs> is the hashref to the C<%attrs> hash that can be passed to C<send_iq> and also has
888     the exact same semantics as described in the documentation of C<send_iq>.
889    
890     C<$rcreate_cbs> is a array reference where you should push further callbacks on
891     that have the same semantic as C<$create_cb> in the documentation of C<send_iq>.
892    
893     =item send_message_hook => $id, $to, $type, $attrs, $rcreate_cbs
894    
895     This event lets you add any desired number of additional create callbacks
896     to a message stanza that is about to be sent.
897    
898     C<$id>, C<$to>, C<$type> and the hashref C<$attrs> are described in the documentation
899     for C<send_message> of L<Net::XMPP2::Writer> (C<$attrs> is C<%attrs> there).
900    
901     For semantics of C<$rcreate_cbs> see also the documentation of the C<send_iq_hook> event above.
902    
903     =item send_presence_hook => $id, $type, $attrs, $rcreate_cbs
904    
905     This event lets you add any desired number of additional create callbacks
906     to a presence stanza that is about to be sent.
907    
908     C<$id>, C<$type> and the hashref C<$attrs> are described in the documentation
909     for C<send_presence> of L<Net::XMPP2::Writer> (C<$attrs> is C<%attrs> there).
910    
911     For semantics of C<$rcreate_cbs> see also the documentation of the C<send_iq_hook> event above.
912    
913 elmex 1.1 =back
914    
915     =head1 AUTHOR
916    
917 elmex 1.20 Robin Redeker, C<< <elmex at ta-sa.org> >>, JID: C<< <elmex at jabber.org> >>
918 elmex 1.1
919     =head1 COPYRIGHT & LICENSE
920    
921     Copyright 2007 Robin Redeker, all rights reserved.
922    
923     This program is free software; you can redistribute it and/or modify it
924     under the same terms as Perl itself.
925    
926     =cut
927    
928     1; # End of Net::XMPP2