ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.17
Committed: Wed Apr 25 19:28:46 2007 UTC (19 years, 5 months ago) by elmex
Branch: MAIN
Changes since 1.16: +3 -3 lines
Log Message:
renamed some files

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