ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.38
Committed: Thu Jul 26 19:45:29 2007 UTC (19 years, 2 months ago) by elmex
Branch: MAIN
CVS Tags: HEAD
Changes since 1.37: +1 -0 lines
Log Message:
added send_stanza_data callback which i missed to implement

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     };
176    
177     $self->reg_cb (
178     xml_parser_error => $proxy_cb,
179     sasl_error => $proxy_cb,
180     stream_error => $proxy_cb,
181     bind_error => $proxy_cb,
182 elmex 1.31 iq_result_cb_exception => sub {
183     my ($self, $ex) = @_;
184     $self->event (error =>
185     Net::XMPP2::Error::Exception->new (
186     exception => $ex, context => 'iq result callback execution'
187     )
188     );
189     },
190 elmex 1.28 tls_error => sub {
191     my ($self) = @_;
192     $self->event (error =>
193     Net::XMPP2::Error->new (text => 'tls_error: tls negotiation failed')
194     );
195     },
196     );
197    
198 elmex 1.1 return $self;
199     }
200    
201 elmex 1.20 =item B<connect ($no_srv_rr)>
202 elmex 1.1
203     Try to connect to the domain and port passed in C<new>.
204    
205     A SRV RR lookup will be performed on the domain to discover
206     the host and port to use. If you don't want this set C<$no_srv_rr>
207     to a true value. C<$no_srv_rr> is false by default.
208    
209     As the SRV RR lookup might return multiple host and you fail to
210     connect to one you might just call this function again to try a
211     different host.
212    
213     If C<connect> was successful and we connected a true value is returned.
214     If the connect was unsuccessful undef is returned and C<$!> will be set
215     to the error that occured while connecting.
216    
217     If you want to know whether further connection attempts might be more
218     successful (as SRV RR lookup may return multiple hosts) call C<may_try_connect>
219     (see also C<may_try_connect>).
220    
221     Note that an internal list will be kept of tried hosts. Use
222     C<reset_connect_tries> to reset the internal list of tried hosts.
223    
224     =cut
225    
226     sub connect {
227     my ($self, $no_srv_rr) = @_;
228    
229     my ($host, $port) = ($self->{domain}, $self->{port} || 5222);
230 elmex 1.9 if ($self->{override_host}) {
231 elmex 1.34 $host = $self->{override_host};
232     $port = $self->{override_port} if defined $self->{override_port};
233 elmex 1.1
234 elmex 1.9 } else {
235     unless ($no_srv_rr) {
236     my $res = Net::DNS::Resolver->new;
237     my $p = $res->query ('_xmpp-client._tcp.'.$host, 'SRV');
238     if ($p) {
239     my @srvs = grep { $_->type eq 'SRV' } $p->answer;
240     if (@srvs) {
241     @srvs = sort { $a->priority <=> $b->priority } @srvs;
242     @srvs = sort { $b->weight <=> $a->weight } @srvs; # TODO
243     $port = $srvs[0]->port;
244     $host = $srvs[0]->target;
245     }
246 elmex 1.1 }
247     }
248     }
249    
250     if ($self->SUPER::connect ($host, $port)) {
251     $self->event (connect => $host, $port);
252     return 1;
253     } else {
254     return undef;
255     }
256     }
257    
258 elmex 1.20 =item B<may_try_connect>
259 elmex 1.1
260     Returns the number of left alternatives of hosts to connect to for the
261     domain passed to C<new>.
262    
263     An internal list of tried hosts will be managed by C<connect> and those
264     hosts will be ignored by a SRV RR lookup (which will be done if you
265     call this function).
266    
267     Use C<reset_connect_tries> to reset the internal list of tried hosts.
268    
269     =cut
270    
271     sub may_try_connect {
272     # TODO
273     }
274    
275 elmex 1.20 =item B<reset_connect_tries>
276 elmex 1.1
277     This function resets the internal list of tried hosts for C<connect>.
278     See also C<connect>.
279    
280     =cut
281    
282     sub reset_connect_tries {
283     # TODO
284     }
285    
286     sub handle_data {
287     my ($self, $buf) = @_;
288     $self->event (debug_recv => $$buf);
289     $self->{parser}->feed (substr $$buf, 0, (length $$buf), '');
290     }
291    
292 elmex 1.5 sub debug_wrote_data {
293     my ($self, $data) = @_;
294     $self->event (debug_send => $data);
295     }
296    
297 elmex 1.1 sub write_data {
298     my ($self, $data) = @_;
299 elmex 1.38 $self->event (send_stanza_data => $data);
300 elmex 1.1 $self->SUPER::write_data ($data);
301     }
302    
303     sub handle_stanza {
304     my ($self, $p, $node) = @_;
305    
306 elmex 1.18 if (not defined $node) { # got stream end
307     $self->disconnect ("end of 'XML' stream encountered");
308     return;
309     }
310    
311 elmex 1.31 $self->event (recv_stanza_xml => $node);
312    
313 elmex 1.1 if ($node->eq (stream => 'features')) {
314     $self->event (stream_features => $node);
315 elmex 1.28 $self->{features} = $node;
316 elmex 1.1 $self->handle_stream_features ($node);
317 elmex 1.5
318 elmex 1.2 } elsif ($node->eq (tls => 'proceed')) {
319     $self->enable_ssl;
320     $self->{parser}->init;
321     $self->{writer}->init;
322 elmex 1.34 $self->{writer}->send_init_stream (
323     $self->{language}, $self->{domain}, $self->{stream_namespace}
324     );
325 elmex 1.2
326 elmex 1.11 } elsif ($node->eq (tls => 'failure')) {
327     $self->event ('tls_error');
328     $self->disconnect ('TLS failure on TLS negotiation.');
329    
330 elmex 1.1 } elsif ($node->eq (sasl => 'challenge')) {
331     $self->handle_sasl_challenge ($node);
332 elmex 1.11
333 elmex 1.1 } elsif ($node->eq (sasl => 'success')) {
334     $self->handle_sasl_success ($node);
335 elmex 1.11
336     } elsif ($node->eq (sasl => 'failure')) {
337     my $error = Net::XMPP2::Error::SASL->new (node => $node);
338     $self->event (sasl_error => $error);
339 elmex 1.28 $self->disconnect ('SASL authentication failure: ' . $error->string);
340 elmex 1.11
341 elmex 1.1 } elsif ($node->eq (client => 'iq')) {
342 elmex 1.32 $self->event (iq_xml => $node);
343 elmex 1.1 $self->handle_iq ($node);
344 elmex 1.11
345 elmex 1.4 } elsif ($node->eq (client => 'message')) {
346 elmex 1.6 $self->event (message_xml => $node);
347 elmex 1.11
348 elmex 1.4 } elsif ($node->eq (client => 'presence')) {
349 elmex 1.6 $self->event (presence_xml => $node);
350 elmex 1.11
351 elmex 1.1 } elsif ($node->eq (stream => 'error')) {
352     $self->handle_error ($node);
353     }
354     }
355    
356 elmex 1.20 =item B<init ()>
357 elmex 1.1
358     Initiate the XML stream.
359    
360     =cut
361    
362     sub init {
363     my ($self) = @_;
364 elmex 1.34 $self->{writer}->send_init_stream ($self->{language}, $self->{domain}, $self->{stream_namespace});
365 elmex 1.1 }
366    
367 elmex 1.20 =item B<is_connected ()>
368 elmex 1.10
369     Returns true if the connection is still connected and stanzas can be
370     sent.
371    
372     =cut
373    
374     sub is_connected {
375     my ($self) = @_;
376     $self->{authenticated}
377     }
378    
379 elmex 1.20 =item B<set_default_iq_timeout ($seconds)>
380 elmex 1.15
381     This sets the default timeout for IQ requests. If the timeout runs out
382     the request will be aborted and the callback called with a L<Net::XMPP2::Error::IQ> object
383 elmex 1.22 where the C<condition> method returns a special value (see also C<condition> method of L<Net::XMPP2::Error::IQ>).
384 elmex 1.15
385     The default timeout for IQ is 60 seconds.
386    
387     =cut
388    
389     sub set_default_iq_timeout {
390     my ($self, $sec) = @_;
391     $self->{default_iq_timeout} = $sec;
392     }
393    
394 elmex 1.20 =item B<send_iq ($type, $create_cb, $result_cb, %attrs)>
395 elmex 1.1
396     This method sends an IQ XMPP request.
397    
398     Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
399 elmex 1.15 about the meaning of C<$type>, C<$create_cb> and C<%attrs> (with the exception
400     of the 'timeout' key of C<%attrs>, see below).
401 elmex 1.1
402 elmex 1.15 C<$result_cb> will be called when a result was received or the timeout reached.
403     The first argument to C<$result_cb> will be a Net::XMPP2::Node instance
404     containing the IQ result stanza contents.
405 elmex 1.1
406     If the IQ resulted in a stanza error the second argument to C<$result_cb> will
407     be C<undef> (if the error type was not 'continue') and the third argument will
408 elmex 1.10 be a L<Net::XMPP2::Error::IQ> object.
409 elmex 1.1
410 elmex 1.15 The timeout can be set by C<set_default_iq_timeout> or passed seperatly
411     in the C<%attrs> array as the value for the key C<timeout> (timeout in seconds btw.).
412    
413 elmex 1.4 This method returns the newly generated id for this iq request.
414    
415 elmex 1.1 =cut
416    
417     sub send_iq {
418     my ($self, $type, $create_cb, $result_cb, %attrs) = @_;
419     my $id = $self->{iq_id}++;
420     $self->{iqs}->{$id} = $result_cb;
421 elmex 1.15
422     my $timeout = delete $attrs{timeout} || $self->{default_iq_timeout};
423     if ($timeout) {
424     $self->{iq_timers}->{$id} =
425 elmex 1.25 AnyEvent->timer (after => $timeout, cb => sub {
426 elmex 1.16 delete $self->{iq_timers}->{$id};
427 elmex 1.15 my $cb = delete $self->{iqs}->{$id};
428 elmex 1.16 $cb->(undef, Net::XMPP2::Error::IQ->new)
429 elmex 1.15 });
430     }
431    
432 elmex 1.1 $self->{writer}->send_iq ($id, $type, $create_cb, %attrs);
433 elmex 1.4 $id
434     }
435    
436 elmex 1.20 =item B<reply_iq_result ($req_iq_node, $create_cb, %attrs)>
437 elmex 1.4
438     This method will generate a result reply to the iq request C<Net::XMPP2::Node>
439     in C<$req_iq_node>.
440    
441     Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
442     about the meaning C<$create_cb> and C<%attrs>.
443    
444 elmex 1.6 Use C<$create_cb> to create the XML for the result.
445    
446 elmex 1.4 The type for this iq reply is 'result'.
447    
448     =cut
449    
450     sub reply_iq_result {
451     my ($self, $iqnode, $create_cb, %attrs) = @_;
452     $self->{writer}->send_iq ($iqnode->attr ('id'), 'result', $create_cb, %attrs);
453     }
454    
455 elmex 1.20 =item B<reply_iq_error ($req_iq_node, $error_type, $error, %attrs)>
456 elmex 1.4
457     This method will generate an error reply to the iq request C<Net::XMPP2::Node>
458     in C<$req_iq_node>.
459    
460     C<$error_type> is one of 'cancel', 'continue', 'modify', 'auth' and 'wait'.
461     C<$error> is one of the defined error conditions described in
462 elmex 1.22 C<write_error_tag> method of L<Net::XMPP2::Writer>.
463 elmex 1.4
464     Please take a look at the documentation for C<send_iq> in Net::XMPP2::Writer
465 elmex 1.6 about the meaning of C<%attrs>.
466 elmex 1.4
467     The type for this iq reply is 'error'.
468    
469     =cut
470    
471     sub reply_iq_error {
472     my ($self, $iqnode, $errtype, $error, %attrs) = @_;
473    
474     $self->{writer}->send_iq (
475     $iqnode->attr ('id'), 'error',
476     sub { $self->{writer}->write_error_tag ($iqnode, $errtype, $error) },
477     %attrs
478     );
479 elmex 1.1 }
480    
481     sub handle_iq {
482     my ($self, $node) = @_;
483    
484 elmex 1.4 my $type = $node->attr ('type');
485    
486 elmex 1.15 my $id = $node->attr ('id');
487     delete $self->{iq_timers}->{$id} if defined $id;
488    
489 elmex 1.4 if ($type eq 'result') {
490 elmex 1.15 if (my $cb = delete $self->{iqs}->{$id}) {
491 elmex 1.27 eval {
492     $cb->($node);
493     };
494     if ($@) { $self->event (iq_result_cb_exception => $@) }
495 elmex 1.1 }
496 elmex 1.9
497 elmex 1.4 } elsif ($type eq 'error') {
498 elmex 1.15 if (my $cb = delete $self->{iqs}->{$id}) {
499 elmex 1.1
500 elmex 1.10 my $error = Net::XMPP2::Error::IQ->new (node => $node);
501     $cb->(($error->type eq 'continue' ? $node : undef), $error);
502 elmex 1.1 }
503 elmex 1.4
504     } else {
505 elmex 1.37 my (@r) = $self->event ("iq_${type}_request_xml" => $node);
506     @r = grep { $_ } @r;
507 elmex 1.4
508     my @from;
509     push @from, (to => $node->attr ('from')) if $node->attr ('from');
510    
511 elmex 1.37 unless (@r) {
512 elmex 1.21 $self->reply_iq_error ($node, undef, 'service-unavailable', @from);
513 elmex 1.4 }
514 elmex 1.1 }
515     }
516    
517 elmex 1.12 sub send_sasl_auth {
518     my ($self, @mechs) = @_;
519 elmex 1.34
520     for (qw/username password domain/) {
521     die "No '$_' argument given to new, but '$_' is required\n"
522     unless $self->{$_};
523     }
524    
525 elmex 1.12 $self->{writer}->send_sasl_auth (
526     (join ' ', map { $_->text } @mechs),
527     $self->{username}, $self->{domain}, $self->{password}
528     );
529     }
530    
531 elmex 1.1 sub handle_stream_features {
532     my ($self, $node) = @_;
533     my @bind = $node->find_all ([qw/bind bind/]);
534 elmex 1.2 my @tls = $node->find_all ([qw/tls starttls/]);
535 elmex 1.13
536     # and yet another weird thingie: in XEP-0077 it's said that
537     # the register feature MAY be advertised by the server. That means:
538     # it MAY not be advertised even if it is available... so we don't
539     # care about it...
540     # my @reg = $node->find_all ([qw/register register/]);
541 elmex 1.1
542 elmex 1.5 if (not ($self->{disable_ssl}) && not ($self->{ssl_enabled}) && @tls) {
543 elmex 1.2 $self->{writer}->send_starttls;
544    
545 elmex 1.12 } elsif (not $self->{authenticated}) {
546 elmex 1.28 my $continue = 1;
547 elmex 1.36 my (@ret) = $self->event (stream_pre_authentication => \$continue);
548     $continue = pop @ret if @ret;
549 elmex 1.28 if ($continue) {
550     $self->authenticate;
551 elmex 1.12 }
552 elmex 1.1
553     } elsif (@bind) {
554     $self->do_rebind ($self->{resource});
555     }
556     }
557    
558 elmex 1.28 =item B<authenticate>
559    
560     This method should be called after the C<stream_pre_authentication> event
561     was emitted to continue authentication of the stream.
562    
563     Usually this method only has to be called when you want to register before
564     you authenticate. See also the documentation of the C<stream_pre_authentication>
565     event below.
566    
567     =cut
568    
569     sub authenticate {
570     my ($self) = @_;
571     my $node = $self->{features};
572     my @mechs = $node->find_all ([qw/sasl mechanisms/], [qw/sasl mechanism/]);
573     my @iqa = $node->find_all ([qw/iqauth auth/]);
574    
575     if (@mechs) {
576     $self->send_sasl_auth (@mechs)
577     } elsif (@iqa) {
578     $self->do_iq_auth;
579     }
580     }
581    
582 elmex 1.1 sub handle_sasl_challenge {
583     my ($self, $node) = @_;
584     $self->{writer}->send_sasl_response ($node->text);
585     }
586    
587     sub handle_sasl_success {
588     my ($self, $node) = @_;
589     $self->{authenticated} = 1;
590     $self->{parser}->init;
591     $self->{writer}->init;
592 elmex 1.34 $self->{writer}->send_init_stream ($self->{language}, $self->{domain}, $self->{stream_namespace});
593 elmex 1.1 }
594    
595     sub handle_error {
596     my ($self, $node) = @_;
597 elmex 1.10 my $error = Net::XMPP2::Error::Stream->new (node => $node);
598    
599 elmex 1.18 $self->event (stream_error => $error);
600 elmex 1.1 $self->{writer}->send_end_of_stream;
601     }
602    
603 elmex 1.18 sub do_iq_auth {
604     my ($self) = @_;
605     # TODO
606     }
607    
608 elmex 1.20 =item B<send_presence ($type, $create_cb, %attrs)>
609 elmex 1.4
610     This method sends a presence stanza, for the meanings
611     of C<$type>, C<$create_cb> and C<%attrs> please take a look
612 elmex 1.22 at the documentation for C<send_presence> method of L<Net::XMPP2::Writer>.
613 elmex 1.4
614     This methods does attach an id attribute to the message stanza and
615     will return the id that was used (so you can react on possible replies).
616    
617     =cut
618    
619     sub send_presence {
620     my ($self, $type, $create_cb, %attrs) = @_;
621     my $id = $self->{iq_id}++;
622     $self->{writer}->send_presence ($id, $type, $create_cb, %attrs);
623     $id
624     }
625    
626 elmex 1.20 =item B<send_message ($to, $type, $create_cb, %attrs)>
627 elmex 1.4
628     This method sends a presence stanza, for the meanings
629     of C<$to>, C<$type>, C<$create_cb> and C<%attrs> please take a look
630 elmex 1.22 at the documentation for C<send_message> method of L<Net::XMPP2::Writer>.
631 elmex 1.4
632     This methods does attach an id attribute to the message stanza and
633     will return the id that was used (so you can react on possible replies).
634    
635     =cut
636    
637     sub send_message {
638     my ($self, $to, $type, $create_cb, %attrs) = @_;
639     my $id = $self->{iq_id}++;
640     $self->{writer}->send_message ($id, $to, $type, $create_cb, %attrs);
641     $id
642     }
643    
644 elmex 1.20 =item B<do_rebind ($resource)>
645 elmex 1.1
646     In case you got a C<bind_error> event and want to retry
647     binding you can call this function to set a new C<$resource>
648     and retry binding.
649    
650     If it fails again you can call this again. Becareful not to
651     end up in a loop!
652    
653     If binding was successful the C<stream_ready> event will be generated.
654    
655     =cut
656    
657     sub do_rebind {
658     my ($self, $resource) = @_;
659     $self->{resource} = $resource;
660     $self->send_iq (
661     set =>
662     sub {
663     my ($w) = @_;
664     if ($self->{resource}) {
665     $w->startTag ([xmpp_ns ('bind'), 'bind']);
666     $w->startTag ([xmpp_ns ('bind'), 'resource']);
667     $w->characters ($self->{resource});
668     $w->endTag;
669     $w->endTag;
670     } else {
671     $w->emptyTag ([xmpp_ns ('bind'), 'bind'])
672     }
673     },
674     sub {
675 elmex 1.13 my ($ret_iq, $error) = @_;
676 elmex 1.1
677 elmex 1.13 if ($error) {
678 elmex 1.28 # TODO: make bind error into a seperate error class?
679 elmex 1.30 if ($error->xml_node ()) {
680     my ($res) = $error->xml_node ()->find_all ([qw/bind bind/], [qw/bind resource/]);
681     $self->event (bind_error => $error, ($res ? $res : $self->{resource}));
682     } else {
683     $self->event (bind_error => $error);
684     }
685 elmex 1.1
686     } else {
687     my @jid = $ret_iq->find_all ([qw/bind bind/], [qw/bind jid/]);
688     my $jid = $jid[0]->text;
689     unless ($jid) { die "Got empty JID tag from server!\n" }
690     $self->{jid} = $jid;
691    
692     $self->event (stream_ready => $jid);
693     }
694     }
695     );
696     }
697    
698 elmex 1.36
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.36 =item stream_pre_authentication
730 elmex 1.28
731     This event is emitted after TLS/SSL was initiated (if enabled) and before any
732 elmex 1.36 authentication happened.
733    
734     The return value of the first event callback that is called decides what happens next.
735     If it is true value the authentication continues. If it is undef or a false value
736     authentication is stopped and you need to call C<authentication> later.
737     value
738 elmex 1.28
739     This event is usually used when you want to do in-band registration,
740     see also L<Net::XMPP2::Ext::Registration>.
741    
742 elmex 1.1 =item stream_ready => $jid
743    
744     This event is sent if the XML stream has been established (and
745     resources have been bound) and is ready for transmitting regular stanzas.
746    
747     C<$jid> is the bound jabber id.
748    
749 elmex 1.28 =item error => $error
750    
751     This event is generated whenever some error occured.
752     C<$error> is an instance of L<Net::XMPP2::Error>.
753     Trivial error reporting may look like this:
754    
755 elmex 1.35 $con->reg_cb (error => sub { warn "xmpp error: " . $_[1]->string . "\n" });
756 elmex 1.28
757     Basically this event is a collect event for all other error events.
758    
759 elmex 1.10 =item stream_error => $error
760 elmex 1.6
761     This event is sent if a XML stream error occured. C<$error>
762 elmex 1.10 is a L<Net::XMPP2::Error::Stream> object.
763 elmex 1.6
764 elmex 1.28 =item xml_parser_error => $error
765    
766     This event is generated whenever the parser trips over XML that it can't
767     read. C<$error> is a L<Net::XMPP2::Error::Parser> object.
768    
769 elmex 1.11 =item tls_error
770    
771     This event is emitted when a TLS error occured on TLS negotiation.
772     After this the connection will be disconnected.
773    
774     =item sasl_error => $error
775    
776     This event is emitted on SASL authentication error.
777    
778 elmex 1.10 =item bind_error => $error, $resource
779 elmex 1.6
780 elmex 1.10 This event is generated when the stream was unable to bind to
781     any or the in C<new> specified resource. C<$error> is a L<Net::XMPP2::Error::IQ>
782     object. C<$resource> is the errornous resource string or undef if none
783     was received.
784 elmex 1.6
785 elmex 1.10 The C<condition> of the C<$error> might be one of: 'bad-request',
786     'not-allowed' or 'conflict'.
787 elmex 1.1
788 elmex 1.20 Node: this is untested, I couldn't get the server to send a bind error
789 elmex 1.1 to test this.
790    
791     =item connect => $host, $port
792    
793     This event is generated when a successful connect was performed to
794     the domain passed to C<new>.
795    
796     Note: C<$host> and C<$port> might be different from the domain you passed to
797     C<new> if C<connect> performed a SRV RR lookup.
798    
799     If this connection is lost a C<disconnect> will be generated with the same
800     C<$host> and C<$port>.
801    
802     =item disconnect => $host, $port, $message
803    
804     This event is generated when the connection was lost or another error
805     occured while writing or reading from it.
806    
807     C<$message> is a humand readable error message for the failure.
808     C<$host> and C<$port> were the host and port we were connected to.
809    
810     Note: C<$host> and C<$port> might be different from the domain you passed to
811     C<new> if C<connect> performed a SRV RR lookup.
812    
813 elmex 1.31 =item recv_stanza_xml => $node
814    
815     This event is generated before any processing of a "XML" stanza happens.
816     C<$node> is the node of the stanza that is being processed, it's of
817     type L<Net::XMPP2::Node>.
818    
819     This method might not be as handy for debuggin purposes as C<debug_recv>.
820    
821     =item send_stanza_data => $data
822    
823     This event is generated shortly before data is sent to the socket.
824     C<$data> contains a complete "XML" stanza or the end of stream closing
825     tag. This method is useful for debugging purposes and I recommend
826     using XML::Twig or something like that to display it nicely.
827    
828     See also the event C<debug_send>.
829    
830     =item debug_send => $data
831    
832     This method is invoked whenever data is written out. This event
833     is mostly the same as C<send_stanza_data>.
834    
835     =item debug_recv => $data
836    
837     This method is incoked whenever a chunk of data was received.
838    
839     It works to filter C<$data> through L<XML::Twig> for debugging
840     display purposes sometimes, but as C<$data> is some arbitrary chunk
841     of bytes you might get a XML parse error (did I already mention that XMPP's
842     application of "XML" sucks?).
843    
844     So you might want to use C<recv_stanza_xml> to detect
845     complete stanzas. Unfortunately C<recv_stanza_xml> doesn't have the
846     bytes anymore and just a datastructure (L<Net::XMPP2::Node>).
847    
848 elmex 1.6 =item presence_xml => $node
849 elmex 1.4
850     This event is sent when a presence stanza is received. C<$node> is the
851     L<Net::XMPP2::Node> object that represents the <presence> tag.
852    
853 elmex 1.6 =item message_xml => $node
854 elmex 1.4
855     This event is sent when a message stanza is received. C<$node> is the
856     L<Net::XMPP2::Node> object that represents the <message> tag.
857    
858 elmex 1.32 =item iq_xml => $node
859    
860     This event is emitted when a iq stanza arrives. C<$node> is the
861     L<Net::XMPP2::Node> object that represents the <iq> tag.
862    
863 elmex 1.37 =item iq_set_request_xml => $node
864 elmex 1.4
865 elmex 1.37 =item iq_get_request_xml => $node
866 elmex 1.4
867     These events are sent when an iq request stanza of type 'get' or 'set' is received.
868     C<$type> will either be 'get' or 'set' and C<$node> will be the L<Net::XMPP2::Node>
869     object of the iq tag.
870    
871 elmex 1.37 If one of the event callbacks returns a true value the IQ request will be
872     considered as handled.
873     If no callback returned a true value or no value at all an error iq will be generated.
874 elmex 1.4
875 elmex 1.27 =item iq_result_cb_exception => $exception
876    
877     If the C<$result_cb> of a C<send_iq> operation somehow threw a exception
878     or failed this event will be generated.
879    
880 elmex 1.36 =item send_iq_hook => $id, $type, $attrs
881 elmex 1.33
882     This event lets you add any desired number of additional create callbacks
883     to a IQ stanza that is about to be sent.
884    
885 elmex 1.36 C<$id>, C<$type> are described in the documentation of C<send_iq> of
886     L<Net::XMPP2::Writer>. C<$attrs> is the hashref to the C<%attrs> hash that can
887     be passed to C<send_iq> and also has the exact same semantics as described in
888     the documentation of C<send_iq>.
889    
890     The return values of the event callbacks are interpreted as C<$create_cb> value as
891     documented for C<send_iq>. (That means you can for example return a callback
892     that fills the IQ).
893    
894     Example:
895    
896     # this appends a <test/> element to all outgoing IQs
897     # and also a <test2/> element to all outgoing IQs
898     $con->reg_cb (send_iq_hook => sub {
899     my ($id, $type, $attrs) = @_;
900     (sub {
901     my $w = shift; # $w is a XML::Writer instance
902     $w->emptyTag ('test');
903     }, {
904     node => { name => "test2" } # see also simxml() defined in Net::XMPP2::Util
905     })
906     });
907 elmex 1.33
908 elmex 1.36 =item send_message_hook => $id, $to, $type, $attrs
909 elmex 1.33
910     This event lets you add any desired number of additional create callbacks
911     to a message stanza that is about to be sent.
912    
913     C<$id>, C<$to>, C<$type> and the hashref C<$attrs> are described in the documentation
914     for C<send_message> of L<Net::XMPP2::Writer> (C<$attrs> is C<%attrs> there).
915    
916 elmex 1.36 To actually append something you need to return something, what you need to return
917     is described in the C<send_iq_hook> event above.
918 elmex 1.33
919 elmex 1.36 =item send_presence_hook => $id, $type, $attrs
920 elmex 1.33
921     This event lets you add any desired number of additional create callbacks
922     to a presence stanza that is about to be sent.
923    
924     C<$id>, C<$type> and the hashref C<$attrs> are described in the documentation
925     for C<send_presence> of L<Net::XMPP2::Writer> (C<$attrs> is C<%attrs> there).
926    
927 elmex 1.36 To actually append something you need to return something, what you need to return
928     is described in the C<send_iq_hook> event above.
929 elmex 1.33
930 elmex 1.1 =back
931    
932     =head1 AUTHOR
933    
934 elmex 1.20 Robin Redeker, C<< <elmex at ta-sa.org> >>, JID: C<< <elmex at jabber.org> >>
935 elmex 1.1
936     =head1 COPYRIGHT & LICENSE
937    
938     Copyright 2007 Robin Redeker, all rights reserved.
939    
940     This program is free software; you can redistribute it and/or modify it
941     under the same terms as Perl itself.
942    
943     =cut
944    
945     1; # End of Net::XMPP2