AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Handle.pm view on Meta::CPAN
} else {
$_[0]{rbuf} = "";
()
}
}
};
=item cbor => $cb->($handle, $scalar)
Reads a CBOR value, decodes it and passes it to the callback. When a parse
error occurs, an C<EBADMSG> error will be raised.
If a L<CBOR::XS> object was passed to the constructor, then that will be
used for the final decode, otherwise it will create a CBOR coder without
enabling any options.
You have to provide a dependency to L<CBOR::XS> on your own: this module
will load the L<CBOR::XS> module, but AnyEvent does not depend on it
itself.
Since CBOR values are fully self-delimiting, the C<cbor> read and write
types are an ideal simple RPC protocol: just exchange CBOR datagrams. See
the C<cbor> write type description, above, for an actual example.
=cut
register_read_type cbor => sub {
my ($self, $cb) = @_;
my $cbor = $self->{cbor} ||= cbor_coder;
my $data;
sub {
my (@value) = eval { $cbor->incr_parse ($_[0]{rbuf}) };
if (@value) {
$cb->($_[0], @value);
1
} elsif ($@) {
# error case
$cbor->incr_reset;
$_[0]->_error (Errno::EBADMSG);
()
} else {
()
}
}
};
=item storable => $cb->($handle, $ref)
Deserialises a L<Storable> frozen representation as written by the
C<storable> write type (BER-encoded length prefix followed by nfreeze'd
data).
Raises C<EBADMSG> error if the data could not be decoded.
=cut
register_read_type storable => sub {
my ($self, $cb) = @_;
require Storable unless $Storable::VERSION;
sub {
# when we can use 5.10 we can use ".", but for 5.8 we use the re-pack method
defined (my $len = eval { unpack "w", $_[0]{rbuf} })
or return;
my $format = length pack "w", $len;
# bypass unshift if we already have the remaining chunk
if ($format + $len <= length $_[0]{rbuf}) {
my $data = substr $_[0]{rbuf}, $format, $len;
substr $_[0]{rbuf}, 0, $format + $len, "";
eval { $cb->($_[0], Storable::thaw ($data)); 1 }
or return $_[0]->_error (Errno::EBADMSG);
} else {
# remove prefix
substr $_[0]{rbuf}, 0, $format, "";
# read remaining chunk
$_[0]->unshift_read (chunk => $len, sub {
eval { $cb->($_[0], Storable::thaw ($_[1])); 1 }
or $_[0]->_error (Errno::EBADMSG);
});
}
1
}
};
=item tls_detect => $cb->($handle, $detect, $major, $minor)
Checks the input stream for a valid SSL or TLS handshake TLSPaintext
record without consuming anything. Only SSL version 3 or higher
is handled, up to the fictituous protocol 4.x (but both SSL3+ and
SSL2-compatible framing is supported).
If it detects that the input data is likely TLS, it calls the callback
with a true value for C<$detect> and the (on-wire) TLS version as second
and third argument (C<$major> is C<3>, and C<$minor> is 0..4 for SSL
3.0, TLS 1.0, 1.1, 1.2 and 1.3, respectively). If it detects the input
to be definitely not TLS, it calls the callback with a false value for
C<$detect>.
The callback could use this information to decide whether or not to start
TLS negotiation.
In all cases the data read so far is passed to the following read
handlers.
Usually you want to use the C<tls_autostart> read type instead.
If you want to design a protocol that works in the presence of TLS
( run in 2.366 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )