AnyEvent-XMPP
view release on metacpan or search on metacpan
lib/AnyEvent/XMPP/Connection.pm view on Meta::CPAN
} else {
$self->do_iq_auth_send ({ username => 1, password => 1, resource => 1 });
}
}
sub do_iq_auth_send {
my ($self, $fields) = @_;
for (qw/username password resource/) {
die "No '$_' argument given to new, but '$_' is required\n"
unless defined $self->{$_};
}
my $do_resource = $fields->{resource};
my $password = $self->{password};
if ($fields->{digest}) {
my $out_password = encode ("UTF-8", $password);
my $out = lc sha1_hex ($self->stream_id () . $out_password);
$fields = {
username => $self->{username},
digest => $out,
}
} else {
$fields = {
username => $self->{username},
password => $password
}
}
if ($do_resource && defined $self->{resource}) {
$fields->{resource} = $self->{resource}
}
$self->send_iq (set => {
defns => 'auth',
node => { ns => 'auth', name => 'query', childs => [
map { { name => $_, childs => [ $fields->{$_} ] } } reverse sort keys %$fields
]}
}, sub {
my ($n, $e) = @_;
if ($e) {
$self->event (iq_auth_error =>
AnyEvent::XMPP::Error::IQAuth->new (context => 'iq_error', iq_error => $e)
);
} else {
$self->{authenticated} = 1;
$self->{jid} = join_jid ($self->{username}, $self->{domain}, $self->{resource});
$self->event (stream_ready => $self->{jid});
}
});
}
=item B<send_presence ($type, $create_cb, %attrs)>
This method sends a presence stanza, for the meanings
of C<$type>, C<$create_cb> and C<%attrs> please take a look
at the documentation for C<send_presence> method of L<AnyEvent::XMPP::Writer>.
This methods does attach an id attribute to the presence stanza and
will return the id that was used (so you can react on possible replies).
=cut
sub send_presence {
my ($self, $type, $create_cb, %attrs) = @_;
my $id = $self->{iq_id}++;
$self->{writer}->send_presence ($id, $type, $create_cb, %attrs);
$id
}
=item B<send_message ($to, $type, $create_cb, %attrs)>
This method sends a message stanza, for the meanings
of C<$to>, C<$type>, C<$create_cb> and C<%attrs> please take a look
at the documentation for C<send_message> method of L<AnyEvent::XMPP::Writer>.
This methods does attach an id attribute to the message stanza and
will return the id that was used (so you can react on possible replies).
=cut
sub send_message {
my ($self, $to, $type, $create_cb, %attrs) = @_;
my $id = delete $attrs{id} || $self->{iq_id}++;
$self->{writer}->send_message ($id, $to, $type, $create_cb, %attrs);
$id
}
=item B<do_rebind ($resource)>
In case you got a C<bind_error> event and want to retry
binding you can call this function to set a new C<$resource>
and retry binding.
If it fails again you can call this again. Becareful not to
end up in a loop!
If binding was successful the C<stream_ready> event will be generated.
=cut
sub do_rebind {
my ($self, $resource) = @_;
$self->{resource} = $resource;
$self->send_iq (
set =>
sub {
my ($w) = @_;
if ($self->{resource}) {
simxml ($w,
defns => 'bind',
node => {
name => 'bind',
childs => [ { name => 'resource', childs => [ $self->{resource} ] } ]
}
)
} else {
simxml ($w, defns => 'bind', node => { name => 'bind' })
}
},
sub {
my ($ret_iq, $error) = @_;
if ($error) {
# TODO: make bind error into a seperate error class?
if ($error->xml_node ()) {
my ($res) = $error->xml_node ()->find_all ([qw/bind bind/], [qw/bind resource/]);
$self->event (bind_error => $error, ($res ? $res : $self->{resource}));
} else {
$self->event (bind_error => $error);
}
} else {
my @jid = $ret_iq->find_all ([qw/bind bind/], [qw/bind jid/]);
my $jid = $jid[0]->text;
unless ($jid) { die "Got empty JID tag from server!\n" }
$self->{jid} = $jid;
( run in 0.876 second using v1.01-cache-2.11-cpan-e1769b4cff6 )