AnyEvent-Porttracker
view release on metacpan or search on metacpan
Porttracker.pm view on Meta::CPAN
It is permissible to send requests immediately after creating the object -
they will be queued until after successful login.
Possible key-value pairs are:
=over 4
=item host => $hostname [MANDATORY]
The hostname or IP address of the Porttracker box.
=item port => $service
The service (port) to use (default: C<porttracker=55>).
=item user => $string, pass => $string
These are the username and password to use when authentication is required
(which it is in almost all cases, so these keys are normally mandatory).
=item tls => $bool
Enables or disables TLS (default: disables). When enabled, then the
connection will try to handshake a TLS connection before logging in. If
unsuccessful a fatal error will be raised.
Since most Porttracker/PortIQ boxes will not have a sensible/verifiable
certificate, no attempt at verifying it will be done (which means
man-in-the-middle-attacks will be trivial). If you want some form of
verification you need to provide your own C<tls_ctx> object with C<<
verify => 1, verify_peername => [1, 1, 1] >> or whatever verification mode
you wish to use.
=item tls_ctx => $tls_ctx
The L<AnyEvent::TLS> object to use. See C<tls>, above.
=item on_XYZ => $coderef
You can specify event callbacks either by sub-classing and overriding the
respective methods or by specifying code-refs as key-value pairs when
constructing the object. You add or remove event handlers at any time with
the C<event> method.
=back
=cut
sub new {
my $class = shift;
my $self = bless {
id => "a",
ids => [],
queue => [], # initially queue everything
@_,
}, $class;
{
Scalar::Util::weaken (my $self = $self);
$self->{hdl} = new AnyEvent::Handle
connect => [$self->{host}, $self->{port} || "porttracker=55"],
on_error => sub {
$self->error ($_[2]);
},
on_connect => sub {
if ($self->{tls}) {
$self->_req (start_tls => sub {
$_[1]
or return $self->error ("TLS rejected by server");
$self->_login;
});
}
},
on_read => sub {
while ($_[0]{rbuf} =~ s/^([^\x0a]*)\x0a//) {
my $msg = JSON::decode_json $1;
my $id = shift @$msg;
if (defined $id) {
my $cb = delete $self->{cb}{$id}
or return $self->error ("received unexpected reply msg with id $id");
push @{ $self->{ids} }, $id;
$cb->($self, @$msg);
} else {
$msg->[0] = "on_$msg->[0]_notify";
call $self, @$msg;
}
}
},
;
}
$self
}
sub DESTROY {
my ($self) = @_;
$self->{hdl}->destroy
if $self->{hdl};
}
sub error {
my ($self, $msg) = @_;
call $self, on_error => $msg;
()
}
sub _req {
my $self = shift;
my $cb = pop;
my $id = (pop @{ $self->{ids} }) || $self->{id}++;
( run in 3.741 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )