ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.30
Committed: Mon Jul 9 07:32:40 2007 UTC (19 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.29: +6 -2 lines
Log Message:
fixed error in bind iq handling

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.26 my $self = $class->SUPER::new (language => 'en', @_);
123 elmex 1.1
124     $self->{parser} = new Net::XMPP2::Parser;
125     $self->{writer} = Net::XMPP2::Writer->new (
126     write_cb => sub { $self->write_data ($_[0]) }
127     );
128    
129     $self->{parser}->set_stanza_cb (sub {
130     $self->handle_stanza (@_);
131     });
132 elmex 1.19 $self->{parser}->set_error_cb (sub {
133 elmex 1.29 my ($ex, $data, $type) = @_;
134     if ($type eq 'xml') {
135     my $pe = Net::XMPP2::Error::Parser->new (exception => $_[0], data => $_[1]);
136     $self->event (xml_parser_error => $pe);
137     $self->disconnect ("xml error: $_[0], $_[1]");
138     } else {
139     my $pe = Net::XMPP2::Error->new (
140     text => "uncaught exception in stanza handling: $ex"
141     );
142     $self->event (uncaught_exception_error => $pe);
143     $self->disconnect ($pe->string);
144     }
145 elmex 1.19 });
146 elmex 1.1
147 elmex 1.15 $self->{iq_id} = 1;
148     $self->{default_iq_timeout} = 60;
149 elmex 1.1
150     $self->{disconnect_cb} = sub {
151     my ($host, $port, $message) = @_;
152 elmex 1.7 delete $self->{authenticated};
153     delete $self->{ssl_enabled};
154 elmex 1.1 $self->event (disconnect => $host, $port, $message);
155     };
156    
157 elmex 1.10 if ($self->{jid}) {
158     my ($user, $host, $res) = split_jid ($self->{jid});
159     $self->{username} = $user;
160     $self->{domain} = $host;
161     $self->{resource} = $res if defined $res;
162     }
163    
164 elmex 1.7 for (qw/username password domain/) {
165     die "No '$_' argument given to new, but '$_' is required\n"
166     unless $self->{$_};
167     }
168    
169 elmex 1.28 my $proxy_cb = sub {
170     my ($self, $er) = @_;
171     $self->event (error => $er);
172     1
173     };
174    
175     $self->reg_cb (
176     xml_parser_error => $proxy_cb,
177     sasl_error => $proxy_cb,
178     stream_error => $proxy_cb,
179     bind_error => $proxy_cb,
180     tls_error => sub {
181     my ($self) = @_;
182     $self->event (error =>
183     Net::XMPP2::Error->new (text => 'tls_error: tls negotiation failed')
184     );
185     1
186     },
187     );
188    
189 elmex 1.1 return $self;
190     }
191    
192 elmex 1.20 =item B<connect ($no_srv_rr)>
193 elmex 1.1
194     Try to connect to the domain and port passed in C<new>.
195    
196     A SRV RR lookup will be performed on the domain to discover
197     the host and port to use. If you don't want this set C<$no_srv_rr>
198     to a true value. C<$no_srv_rr> is false by default.
199    
200     As the SRV RR lookup might return multiple host and you fail to
201     connect to one you might just call this function again to try a
202     different host.
203    
204     If C<connect> was successful and we connected a true value is returned.
205     If the connect was unsuccessful undef is returned and C<$!> will be set
206     to the error that occured while connecting.
207    
208     If you want to know whether further connection attempts might be more
209     successful (as SRV RR lookup may return multiple hosts) call C<may_try_connect>
210     (see also C<may_try_connect>).
211    
212     Note that an internal list will be kept of tried hosts. Use
213     C<reset_connect_tries> to reset the internal list of tried hosts.
214    
215     =cut
216    
217     sub connect {
218     my ($self, $no_srv_rr) = @_;
219    
220     my ($host, $port) = ($self->{domain}, $self->{port} || 5222);
221 elmex 1.9 if ($self->{override_host}) {
222     ($host, $port) = ($self->{override_host}, $self->{override_port} || 5222);
223 elmex 1.1
224 elmex 1.9 } else {
225     unless ($no_srv_rr) {
226     my $res = Net::DNS::Resolver->new;
227     my $p = $res->query ('_xmpp-client._tcp.'.$host, 'SRV');
228     if ($p) {
229     my @srvs = grep { $_->type eq 'SRV' } $p->answer;
230     if (@srvs) {
231     @srvs = sort { $a->priority <=> $b->priority } @srvs;
232     @srvs = sort { $b->weight <=> $a->weight } @srvs; # TODO
233     $port = $srvs[0]->port;
234     $host = $srvs[0]->target;
235     }
236 elmex 1.1 }
237     }
238     }
239    
240     if ($self->SUPER::connect ($host, $port)) {
241     $self->event (connect => $host, $port);
242     return 1;
243     } else {
244     return undef;
245     }
246     }
247    
248 elmex 1.20 =item B<may_try_connect>
249 elmex 1.1
250     Returns the number of left alternatives of hosts to connect to for the
251     domain passed to C<new>.
252    
253     An internal list of tried hosts will be managed by C<connect> and those
254     hosts will be ignored by a SRV RR lookup (which will be done if you
255     call this function).
256    
257     Use C<reset_connect_tries> to reset the internal list of tried hosts.
258    
259     =cut
260    
261     sub may_try_connect {
262     # TODO
263     }
264    
265 elmex 1.20 =item B<reset_connect_tries>
266 elmex 1.1
267     This function resets the internal list of tried hosts for C<connect>.
268     See also C<connect>.
269    
270     =cut
271    
272     sub reset_connect_tries {
273     # TODO
274     }
275    
276     sub handle_data {
277     my ($self, $buf) = @_;
278     $self->event (debug_recv => $$buf);
279     $self->{parser}->feed (substr $$buf, 0, (length $$buf), '');
280     }
281    
282 elmex 1.5 sub debug_wrote_data {
283     my ($self, $data) = @_;
284     $self->event (debug_send => $data);
285     }
286    
287 elmex 1.1 sub write_data {
288     my ($self, $data) = @_;
289     $self->SUPER::write_data ($data);
290     }
291    
292     sub handle_stanza {
293     my ($self, $p, $node) = @_;
294    
295 elmex 1.18 if (not defined $node) { # got stream end
296     $self->disconnect ("end of 'XML' stream encountered");
297     return;
298     }
299    
300 elmex 1.1 if ($node->eq (stream => 'features')) {
301     $self->event (stream_features => $node);
302 elmex 1.28 $self->{features} = $node;
303 elmex 1.1 $self->handle_stream_features ($node);
304 elmex 1.5
305 elmex 1.2 } elsif ($node->eq (tls => 'proceed')) {
306     $self->enable_ssl;
307     $self->{parser}->init;
308     $self->{writer}->init;
309     $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
310    
311 elmex 1.11 } elsif ($node->eq (tls => 'failure')) {
312     $self->event ('tls_error');
313     $self->disconnect ('TLS failure on TLS negotiation.');
314    
315 elmex 1.1 } elsif ($node->eq (sasl => 'challenge')) {
316     $self->handle_sasl_challenge ($node);
317 elmex 1.11
318 elmex 1.1 } elsif ($node->eq (sasl => 'success')) {
319     $self->handle_sasl_success ($node);
320 elmex 1.11
321     } elsif ($node->eq (sasl => 'failure')) {
322     my $error = Net::XMPP2::Error::SASL->new (node => $node);
323     $self->event (sasl_error => $error);
324 elmex 1.28 $self->disconnect ('SASL authentication failure: ' . $error->string);
325 elmex 1.11
326 elmex 1.1 } elsif ($node->eq (client => 'iq')) {
327     $self->handle_iq ($node);
328 elmex 1.11
329 elmex 1.4 } elsif ($node->eq (client => 'message')) {
330 elmex 1.6 $self->event (message_xml => $node);
331 elmex 1.11
332 elmex 1.4 } elsif ($node->eq (client => 'presence')) {
333 elmex 1.6 $self->event (presence_xml => $node);
334 elmex 1.11
335 elmex 1.1 } elsif ($node->eq (stream => 'error')) {
336     $self->handle_error ($node);
337 elmex 1.11
338 elmex 1.1 } else {
339     warn "Didn't understood stanza: '" . $node->name . "'";
340     }
341     }
342    
343 elmex 1.20 =item B<init ()>
344 elmex 1.1
345     Initiate the XML stream.
346    
347     =cut
348    
349     sub init {
350     my ($self) = @_;
351     $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
352     }
353    
354 elmex 1.20 =item B<is_connected ()>
355 elmex 1.10
356     Returns true if the connection is still connected and stanzas can be
357     sent.
358    
359     =cut
360    
361     sub is_connected {
362     my ($self) = @_;
363     $self->{authenticated}
364     }
365    
366 elmex 1.20 =item B<set_default_iq_timeout ($seconds)>
367 elmex 1.15
368     This sets the default timeout for IQ requests. If the timeout runs out
369     the request will be aborted and the callback called with a L<Net::XMPP2::Error::IQ> object
370 elmex 1.22 where the C<condition> method returns a special value (see also C<condition> method of L<Net::XMPP2::Error::IQ>).
371 elmex 1.15
372     The default timeout for IQ is 60 seconds.
373    
374     =cut
375    
376     sub set_default_iq_timeout {
377     my ($self, $sec) = @_;
378     $self->{default_iq_timeout} = $sec;
379     }
380    
381 elmex 1.20 =item B<send_iq ($type, $create_cb, $result_cb, %attrs)>
382 elmex 1.1
383     This method sends an IQ XMPP request.
384    
385     Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
386 elmex 1.15 about the meaning of C<$type>, C<$create_cb> and C<%attrs> (with the exception
387     of the 'timeout' key of C<%attrs>, see below).
388 elmex 1.1
389 elmex 1.15 C<$result_cb> will be called when a result was received or the timeout reached.
390     The first argument to C<$result_cb> will be a Net::XMPP2::Node instance
391     containing the IQ result stanza contents.
392 elmex 1.1
393     If the IQ resulted in a stanza error the second argument to C<$result_cb> will
394     be C<undef> (if the error type was not 'continue') and the third argument will
395 elmex 1.10 be a L<Net::XMPP2::Error::IQ> object.
396 elmex 1.1
397 elmex 1.15 The timeout can be set by C<set_default_iq_timeout> or passed seperatly
398     in the C<%attrs> array as the value for the key C<timeout> (timeout in seconds btw.).
399    
400 elmex 1.4 This method returns the newly generated id for this iq request.
401    
402 elmex 1.1 =cut
403    
404     sub send_iq {
405     my ($self, $type, $create_cb, $result_cb, %attrs) = @_;
406     my $id = $self->{iq_id}++;
407     $self->{iqs}->{$id} = $result_cb;
408 elmex 1.15
409     my $timeout = delete $attrs{timeout} || $self->{default_iq_timeout};
410     if ($timeout) {
411     $self->{iq_timers}->{$id} =
412 elmex 1.25 AnyEvent->timer (after => $timeout, cb => sub {
413 elmex 1.16 delete $self->{iq_timers}->{$id};
414 elmex 1.15 my $cb = delete $self->{iqs}->{$id};
415 elmex 1.16 $cb->(undef, Net::XMPP2::Error::IQ->new)
416 elmex 1.15 });
417     }
418    
419 elmex 1.1 $self->{writer}->send_iq ($id, $type, $create_cb, %attrs);
420 elmex 1.4 $id
421     }
422    
423 elmex 1.20 =item B<reply_iq_result ($req_iq_node, $create_cb, %attrs)>
424 elmex 1.4
425     This method will generate a result reply to the iq request C<Net::XMPP2::Node>
426     in C<$req_iq_node>.
427    
428     Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
429     about the meaning C<$create_cb> and C<%attrs>.
430    
431 elmex 1.6 Use C<$create_cb> to create the XML for the result.
432    
433 elmex 1.4 The type for this iq reply is 'result'.
434    
435     =cut
436    
437     sub reply_iq_result {
438     my ($self, $iqnode, $create_cb, %attrs) = @_;
439     $self->{writer}->send_iq ($iqnode->attr ('id'), 'result', $create_cb, %attrs);
440     }
441    
442 elmex 1.20 =item B<reply_iq_error ($req_iq_node, $error_type, $error, %attrs)>
443 elmex 1.4
444     This method will generate an error reply to the iq request C<Net::XMPP2::Node>
445     in C<$req_iq_node>.
446    
447     C<$error_type> is one of 'cancel', 'continue', 'modify', 'auth' and 'wait'.
448     C<$error> is one of the defined error conditions described in
449 elmex 1.22 C<write_error_tag> method of L<Net::XMPP2::Writer>.
450 elmex 1.4
451     Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
452 elmex 1.6 about the meaning of C<%attrs>.
453 elmex 1.4
454     The type for this iq reply is 'error'.
455    
456     =cut
457    
458     sub reply_iq_error {
459     my ($self, $iqnode, $errtype, $error, %attrs) = @_;
460    
461     $self->{writer}->send_iq (
462     $iqnode->attr ('id'), 'error',
463     sub { $self->{writer}->write_error_tag ($iqnode, $errtype, $error) },
464     %attrs
465     );
466 elmex 1.1 }
467    
468     sub handle_iq {
469     my ($self, $node) = @_;
470    
471 elmex 1.4 my $type = $node->attr ('type');
472    
473 elmex 1.15 my $id = $node->attr ('id');
474     delete $self->{iq_timers}->{$id} if defined $id;
475    
476 elmex 1.4 if ($type eq 'result') {
477 elmex 1.15 if (my $cb = delete $self->{iqs}->{$id}) {
478 elmex 1.27 eval {
479     $cb->($node);
480     };
481     if ($@) { $self->event (iq_result_cb_exception => $@) }
482 elmex 1.1 }
483 elmex 1.9
484 elmex 1.4 } elsif ($type eq 'error') {
485 elmex 1.15 if (my $cb = delete $self->{iqs}->{$id}) {
486 elmex 1.1
487 elmex 1.10 my $error = Net::XMPP2::Error::IQ->new (node => $node);
488     $cb->(($error->type eq 'continue' ? $node : undef), $error);
489 elmex 1.1 }
490 elmex 1.4
491     } else {
492     my $handled = 0;
493 elmex 1.6 $self->event ("iq_${type}_request_xml" => $node, \$handled);
494 elmex 1.4
495     my @from;
496     push @from, (to => $node->attr ('from')) if $node->attr ('from');
497    
498     unless ($handled) {
499 elmex 1.21 $self->reply_iq_error ($node, undef, 'service-unavailable', @from);
500 elmex 1.4 }
501 elmex 1.1 }
502     }
503    
504 elmex 1.12 sub send_sasl_auth {
505     my ($self, @mechs) = @_;
506     $self->{writer}->send_sasl_auth (
507     (join ' ', map { $_->text } @mechs),
508     $self->{username}, $self->{domain}, $self->{password}
509     );
510     }
511    
512 elmex 1.1 sub handle_stream_features {
513     my ($self, $node) = @_;
514     my @bind = $node->find_all ([qw/bind bind/]);
515 elmex 1.2 my @tls = $node->find_all ([qw/tls starttls/]);
516 elmex 1.13
517     # and yet another weird thingie: in XEP-0077 it's said that
518     # the register feature MAY be advertised by the server. That means:
519     # it MAY not be advertised even if it is available... so we don't
520     # care about it...
521     # my @reg = $node->find_all ([qw/register register/]);
522 elmex 1.1
523 elmex 1.5 if (not ($self->{disable_ssl}) && not ($self->{ssl_enabled}) && @tls) {
524 elmex 1.2 $self->{writer}->send_starttls;
525    
526 elmex 1.12 } elsif (not $self->{authenticated}) {
527 elmex 1.28 my $continue = 1;
528     $self->event (stream_pre_authentication => \$continue);
529     if ($continue) {
530     $self->authenticate;
531 elmex 1.12 }
532 elmex 1.1
533     } elsif (@bind) {
534     $self->do_rebind ($self->{resource});
535     }
536     }
537    
538 elmex 1.28 =item B<authenticate>
539    
540     This method should be called after the C<stream_pre_authentication> event
541     was emitted to continue authentication of the stream.
542    
543     Usually this method only has to be called when you want to register before
544     you authenticate. See also the documentation of the C<stream_pre_authentication>
545     event below.
546    
547     =cut
548    
549     sub authenticate {
550     my ($self) = @_;
551     my $node = $self->{features};
552     my @mechs = $node->find_all ([qw/sasl mechanisms/], [qw/sasl mechanism/]);
553     my @iqa = $node->find_all ([qw/iqauth auth/]);
554    
555     if (@mechs) {
556     $self->send_sasl_auth (@mechs)
557     } elsif (@iqa) {
558     $self->do_iq_auth;
559     }
560     }
561    
562 elmex 1.1 sub handle_sasl_challenge {
563     my ($self, $node) = @_;
564     $self->{writer}->send_sasl_response ($node->text);
565     }
566    
567     sub handle_sasl_success {
568     my ($self, $node) = @_;
569     $self->{authenticated} = 1;
570     $self->{parser}->init;
571     $self->{writer}->init;
572     $self->{writer}->send_init_stream ($self->{language}, $self->{domain});
573     }
574    
575     sub handle_error {
576     my ($self, $node) = @_;
577 elmex 1.10 my $error = Net::XMPP2::Error::Stream->new (node => $node);
578    
579 elmex 1.18 $self->event (stream_error => $error);
580 elmex 1.1 $self->{writer}->send_end_of_stream;
581     }
582    
583 elmex 1.18 sub do_iq_auth {
584     my ($self) = @_;
585     # TODO
586     }
587    
588 elmex 1.20 =item B<send_presence ($type, $create_cb, %attrs)>
589 elmex 1.4
590     This method sends a presence stanza, for the meanings
591     of C<$type>, C<$create_cb> and C<%attrs> please take a look
592 elmex 1.22 at the documentation for C<send_presence> method of L<Net::XMPP2::Writer>.
593 elmex 1.4
594     This methods does attach an id attribute to the message stanza and
595     will return the id that was used (so you can react on possible replies).
596    
597     =cut
598    
599     sub send_presence {
600     my ($self, $type, $create_cb, %attrs) = @_;
601     my $id = $self->{iq_id}++;
602     $self->{writer}->send_presence ($id, $type, $create_cb, %attrs);
603     $id
604     }
605    
606 elmex 1.20 =item B<send_message ($to, $type, $create_cb, %attrs)>
607 elmex 1.4
608     This method sends a presence stanza, for the meanings
609     of C<$to>, C<$type>, C<$create_cb> and C<%attrs> please take a look
610 elmex 1.22 at the documentation for C<send_message> method of L<Net::XMPP2::Writer>.
611 elmex 1.4
612     This methods does attach an id attribute to the message stanza and
613     will return the id that was used (so you can react on possible replies).
614    
615     =cut
616    
617     sub send_message {
618     my ($self, $to, $type, $create_cb, %attrs) = @_;
619     my $id = $self->{iq_id}++;
620     $self->{writer}->send_message ($id, $to, $type, $create_cb, %attrs);
621     $id
622     }
623    
624 elmex 1.20 =item B<do_rebind ($resource)>
625 elmex 1.1
626     In case you got a C<bind_error> event and want to retry
627     binding you can call this function to set a new C<$resource>
628     and retry binding.
629    
630     If it fails again you can call this again. Becareful not to
631     end up in a loop!
632    
633     If binding was successful the C<stream_ready> event will be generated.
634    
635     =cut
636    
637     sub do_rebind {
638     my ($self, $resource) = @_;
639     $self->{resource} = $resource;
640     $self->send_iq (
641     set =>
642     sub {
643     my ($w) = @_;
644     if ($self->{resource}) {
645     $w->startTag ([xmpp_ns ('bind'), 'bind']);
646     $w->startTag ([xmpp_ns ('bind'), 'resource']);
647     $w->characters ($self->{resource});
648     $w->endTag;
649     $w->endTag;
650     } else {
651     $w->emptyTag ([xmpp_ns ('bind'), 'bind'])
652     }
653     },
654     sub {
655 elmex 1.13 my ($ret_iq, $error) = @_;
656 elmex 1.1
657 elmex 1.13 if ($error) {
658 elmex 1.28 # TODO: make bind error into a seperate error class?
659 elmex 1.30 if ($error->xml_node ()) {
660     my ($res) = $error->xml_node ()->find_all ([qw/bind bind/], [qw/bind resource/]);
661     $self->event (bind_error => $error, ($res ? $res : $self->{resource}));
662     } else {
663     $self->event (bind_error => $error);
664     }
665 elmex 1.1
666     } else {
667     my @jid = $ret_iq->find_all ([qw/bind bind/], [qw/bind jid/]);
668     my $jid = $jid[0]->text;
669     unless ($jid) { die "Got empty JID tag from server!\n" }
670     $self->{jid} = $jid;
671    
672     $self->event (stream_ready => $jid);
673     }
674     }
675     );
676     }
677    
678 elmex 1.20 =item B<jid>
679 elmex 1.1
680     After the stream has been bound to a resource the JID can be retrieved via this
681     method.
682    
683     =cut
684    
685     sub jid { $_[0]->{jid} }
686    
687 elmex 1.20 =item B<features>
688 elmex 1.4
689     Returns the last received <features> tag in form of an L<Net::XMPP2::Node> object.
690    
691     =cut
692    
693     sub features { $_[0]->{features} }
694    
695 elmex 1.20 =back
696    
697 elmex 1.1 =head1 EVENTS
698    
699     These events can be registered on with C<reg_cb>:
700    
701     =over 4
702    
703 elmex 1.11 =item stream_features => $node
704 elmex 1.1
705 elmex 1.4 This event is sent when a stream feature (<features>) tag is received. C<$node> is the
706     L<Net::XMPP2::Node> object that represents the <features> tag.
707 elmex 1.1
708 elmex 1.28 =item stream_pre_authentication => $rcontinue
709    
710     This event is emitted after TLS/SSL was initiated (if enabled) and before any
711     authentication happened. C<$rcontinue> is a reference to a scalar that per default
712     holds a true value. If that scalar is true the authentication will continue
713     after handling this event. If you set C<$$rcontinue> to a false value
714     the authentication will stop and you have to call the C<authenticate>
715     method later.
716    
717     This event is usually used when you want to do in-band registration,
718     see also L<Net::XMPP2::Ext::Registration>.
719    
720 elmex 1.1 =item stream_ready => $jid
721    
722     This event is sent if the XML stream has been established (and
723     resources have been bound) and is ready for transmitting regular stanzas.
724    
725     C<$jid> is the bound jabber id.
726    
727 elmex 1.28 =item error => $error
728    
729     This event is generated whenever some error occured.
730     C<$error> is an instance of L<Net::XMPP2::Error>.
731     Trivial error reporting may look like this:
732    
733     $con->reg_cb (error => sub { warn "xmpp error: " . $_[1]->string . "\n"; 1 });
734    
735     Basically this event is a collect event for all other error events.
736    
737 elmex 1.10 =item stream_error => $error
738 elmex 1.6
739     This event is sent if a XML stream error occured. C<$error>
740 elmex 1.10 is a L<Net::XMPP2::Error::Stream> object.
741 elmex 1.6
742 elmex 1.28 =item xml_parser_error => $error
743    
744     This event is generated whenever the parser trips over XML that it can't
745     read. C<$error> is a L<Net::XMPP2::Error::Parser> object.
746    
747 elmex 1.11 =item tls_error
748    
749     This event is emitted when a TLS error occured on TLS negotiation.
750     After this the connection will be disconnected.
751    
752     =item sasl_error => $error
753    
754     This event is emitted on SASL authentication error.
755    
756 elmex 1.10 =item bind_error => $error, $resource
757 elmex 1.6
758 elmex 1.10 This event is generated when the stream was unable to bind to
759     any or the in C<new> specified resource. C<$error> is a L<Net::XMPP2::Error::IQ>
760     object. C<$resource> is the errornous resource string or undef if none
761     was received.
762 elmex 1.6
763 elmex 1.10 The C<condition> of the C<$error> might be one of: 'bad-request',
764     'not-allowed' or 'conflict'.
765 elmex 1.1
766 elmex 1.20 Node: this is untested, I couldn't get the server to send a bind error
767 elmex 1.1 to test this.
768    
769     =item connect => $host, $port
770    
771     This event is generated when a successful connect was performed to
772     the domain passed to C<new>.
773    
774     Note: C<$host> and C<$port> might be different from the domain you passed to
775     C<new> if C<connect> performed a SRV RR lookup.
776    
777     If this connection is lost a C<disconnect> will be generated with the same
778     C<$host> and C<$port>.
779    
780     =item disconnect => $host, $port, $message
781    
782     This event is generated when the connection was lost or another error
783     occured while writing or reading from it.
784    
785     C<$message> is a humand readable error message for the failure.
786     C<$host> and C<$port> were the host and port we were connected to.
787    
788     Note: C<$host> and C<$port> might be different from the domain you passed to
789     C<new> if C<connect> performed a SRV RR lookup.
790    
791 elmex 1.6 =item presence_xml => $node
792 elmex 1.4
793     This event is sent when a presence stanza is received. C<$node> is the
794     L<Net::XMPP2::Node> object that represents the <presence> tag.
795    
796 elmex 1.6 =item message_xml => $node
797 elmex 1.4
798     This event is sent when a message stanza is received. C<$node> is the
799     L<Net::XMPP2::Node> object that represents the <message> tag.
800    
801 elmex 1.6 =item iq_set_request_xml => $node, $handled_ref
802 elmex 1.4
803 elmex 1.6 =item iq_get_request_xml => $node, $handled_ref
804 elmex 1.4
805     These events are sent when an iq request stanza of type 'get' or 'set' is received.
806     C<$type> will either be 'get' or 'set' and C<$node> will be the L<Net::XMPP2::Node>
807     object of the iq tag.
808    
809     If C<$$handled_ref> is true an event handler should not handle this message anymore.
810    
811     If one of the event handlers handled this message the scalar pointed at by
812     the reference in C<$handled_ref> should be set to 1 true value. If C<$$handled_ref>
813     is still false after all event handlers were executed an error iq will be generated.
814    
815 elmex 1.27 =item iq_result_cb_exception => $exception
816    
817     If the C<$result_cb> of a C<send_iq> operation somehow threw a exception
818     or failed this event will be generated.
819    
820 elmex 1.1 =back
821    
822     =head1 AUTHOR
823    
824 elmex 1.20 Robin Redeker, C<< <elmex at ta-sa.org> >>, JID: C<< <elmex at jabber.org> >>
825 elmex 1.1
826     =head1 COPYRIGHT & LICENSE
827    
828     Copyright 2007 Robin Redeker, all rights reserved.
829    
830     This program is free software; you can redistribute it and/or modify it
831     under the same terms as Perl itself.
832    
833     =cut
834    
835     1; # End of Net::XMPP2