ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-XMPP2/lib/Net/XMPP2/Connection.pm
Revision: 1.31
Committed: Wed Jul 11 13:34:54 2007 UTC (19 years, 3 months ago) by elmex
Branch: MAIN
Changes since 1.30: +46 -0 lines
Log Message:
added development client example

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