AnyEvent
view release on metacpan or search on metacpan
lib/AnyEvent/Handle.pm view on Meta::CPAN
You can also provide your own TLS connection object, but you have
to make sure that you call either C<Net::SSLeay::set_connect_state>
or C<Net::SSLeay::set_accept_state> on it before you pass it to
AnyEvent::Handle. Also, this module will take ownership of this connection
object.
At some future point, AnyEvent::Handle might switch to another TLS
implementation, then the option to use your own session object will go
away.
B<IMPORTANT:> since Net::SSLeay "objects" are really only integers,
passing in the wrong integer will lead to certain crash. This most often
happens when one uses a stylish C<< tls => 1 >> and is surprised about the
segmentation fault.
Use the C<< ->starttls >> method if you need to start TLS negotiation later.
=item tls_ctx => $anyevent_tls
Use the given C<AnyEvent::TLS> object to create the new TLS connection
(unless a connection object was specified directly). If this
parameter is missing (or C<undef>), then AnyEvent::Handle will use
C<AnyEvent::Handle::TLS_CTX>.
Instead of an object, you can also specify a hash reference with C<< key
=> value >> pairs. Those will be passed to L<AnyEvent::TLS> to create a
new TLS context object.
=item on_starttls => $cb->($handle, $success[, $error_message])
This callback will be invoked when the TLS/SSL handshake has finished. If
C<$success> is true, then the TLS handshake succeeded, otherwise it failed
(C<on_stoptls> will not be called in this case).
The session in C<< $handle->{tls} >> can still be examined in this
callback, even when the handshake was not successful.
TLS handshake failures will not cause C<on_error> to be invoked when this
callback is in effect, instead, the error message will be passed to C<on_starttls>.
Without this callback, handshake failures lead to C<on_error> being
called as usual.
Note that you cannot just call C<starttls> again in this callback. If you
need to do that, start an zero-second timer instead whose callback can
then call C<< ->starttls >> again.
=item on_stoptls => $cb->($handle)
When a SSLv3/TLS shutdown/close notify/EOF is detected and this callback is
set, then it will be invoked after freeing the TLS session. If it is not,
then a TLS shutdown condition will be treated like a normal EOF condition
on the handle.
The session in C<< $handle->{tls} >> can still be examined in this
callback.
This callback will only be called on TLS shutdowns, not when the
underlying handle signals EOF.
=item json => L<JSON>, L<JSON::PP> or L<JSON::XS> object
This is the json coder object used by the C<json> read and write types.
If you don't supply it, then AnyEvent::Handle will create and use a
suitable one (on demand), which will write and expect UTF-8 encoded
JSON texts (either using L<JSON::XS> or L<JSON>). The written texts are
guaranteed not to contain any newline character.
For security reasons, this encoder will likely I<not> handle numbers and
strings, only arrays and objects/hashes. The reason is that originally
JSON was self-delimited, but Dougles Crockford thought it was a splendid
idea to redefine JSON incompatibly, so this is no longer true.
For protocols that used back-to-back JSON texts, this might lead to
run-ins, where two or more JSON texts will be interpreted as one JSON
text.
For this reason, if the default encoder uses L<JSON::XS>, it will default
to not allowing anything but arrays and objects/hashes, at least for the
forseeable future (it will change at some point). This might or might not
be true for the L<JSON> module, so this might cause a security issue.
If you depend on either behaviour, you should create your own json object
and pass it in explicitly.
=item cbor => L<CBOR::XS> object
This is the cbor coder object used by the C<cbor> read and write types.
If you don't supply it, then AnyEvent::Handle will create and use a
suitable one (on demand), which will write CBOR without using extensions,
if possible.
Note that you are responsible to depend on the L<CBOR::XS> module if you
want to use this functionality, as AnyEvent does not have a dependency on
it itself.
=back
=cut
sub new {
my $class = shift;
my $self = bless { @_ }, $class;
if ($self->{fh}) {
$self->_start;
return unless $self->{fh}; # could be gone by now
} elsif ($self->{connect}) {
require AnyEvent::Socket;
$self->{peername} = $self->{connect}[0]
unless exists $self->{peername};
$self->{_skip_drain_rbuf} = 1;
{
Scalar::Util::weaken (my $self = $self);
$self->{_connect} =
AnyEvent::Socket::tcp_connect (
$self->{connect}[0],
$self->{connect}[1],
sub {
my ($fh, $host, $port, $retry) = @_;
delete $self->{_connect}; # no longer needed
if ($fh) {
$self->{fh} = $fh;
delete $self->{_skip_drain_rbuf};
$self->_start;
$self->{on_connect}
and $self->{on_connect}($self, $host, $port, sub {
delete @$self{qw(fh _tw _rtw _wtw _ww _rw _eof _queue rbuf _wbuf tls _tls_rbuf _tls_wbuf)};
lib/AnyEvent/Handle.pm view on Meta::CPAN
};
=item json => $array_or_hashref
Encodes the given hash or array reference into a JSON object. Unless you
provide your own JSON object, this means it will be encoded to JSON text
in UTF-8.
The default encoder might or might not handle every type of JSON value -
it might be limited to arrays and objects for security reasons. See the
C<json> constructor attribute for more details.
JSON objects (and arrays) are self-delimiting, so if you only use arrays
and hashes, you can write JSON at one end of a handle and read them at the
other end without using any additional framing.
The JSON text generated by the default encoder is guaranteed not to
contain any newlines: While this module doesn't need delimiters after or
between JSON texts to be able to read them, many other languages depend on
them.
A simple RPC protocol that interoperates easily with other languages is
to send JSON arrays (or objects, although arrays are usually the better
choice as they mimic how function argument passing works) and a newline
after each JSON text:
$handle->push_write (json => ["method", "arg1", "arg2"]); # whatever
$handle->push_write ("\012");
An AnyEvent::Handle receiver would simply use the C<json> read type and
rely on the fact that the newline will be skipped as leading whitespace:
$handle->push_read (json => sub { my $array = $_[1]; ... });
Other languages could read single lines terminated by a newline and pass
this line into their JSON decoder of choice.
=item cbor => $perl_scalar
Encodes the given scalar into a CBOR value. Unless you provide your own
L<CBOR::XS> object, this means it will be encoded to a CBOR string not
using any extensions, if possible.
CBOR values are self-delimiting, so you can write CBOR at one end of
a handle and read them at the other end without using any additional
framing.
A simple nd very very fast RPC protocol that interoperates with
other languages is to send CBOR and receive CBOR values (arrays are
recommended):
$handle->push_write (cbor => ["method", "arg1", "arg2"]); # whatever
An AnyEvent::Handle receiver would simply use the C<cbor> read type:
$handle->push_read (cbor => sub { my $array = $_[1]; ... });
=cut
sub json_coder() {
eval { require JSON::XS; JSON::XS->new->utf8 }
|| do { require JSON::PP; JSON::PP->new->utf8 }
}
register_write_type json => sub {
my ($self, $ref) = @_;
($self->{json} ||= json_coder)
->encode ($ref)
};
sub cbor_coder() {
require CBOR::XS;
CBOR::XS->new
}
register_write_type cbor => sub {
my ($self, $scalar) = @_;
($self->{cbor} ||= cbor_coder)
->encode ($scalar)
};
=item storable => $reference
Freezes the given reference using L<Storable> and writes it to the
handle. Uses the C<nfreeze> format.
=cut
register_write_type storable => sub {
my ($self, $ref) = @_;
require Storable unless $Storable::VERSION;
pack "w/a*", Storable::nfreeze ($ref)
};
=back
=item $handle->push_shutdown
Sometimes you know you want to close the socket after writing your data
before it was actually written. One way to do that is to replace your
C<on_drain> handler by a callback that shuts down the socket (and set
C<low_water_mark> to C<0>). This method is a shorthand for just that, and
replaces the C<on_drain> callback with:
sub { shutdown $_[0]{fh}, 1 }
This simply shuts down the write side and signals an EOF condition to the
the peer.
You can rely on the normal read queue and C<on_eof> handling
afterwards. This is the cleanest way to close a connection.
This method may invoke callbacks (and therefore the handle might be
destroyed after it returns).
=cut
lib/AnyEvent/Handle.pm view on Meta::CPAN
}
});
});
1
}
};
=item packstring => $format, $cb->($handle, $string)
An octet string prefixed with an encoded length. The encoding C<$format>
uses the same format as a Perl C<pack> format, but must specify a single
integer only (only one of C<cCsSlLqQiInNvVjJw> is allowed, plus an
optional C<!>, C<< < >> or C<< > >> modifier).
For example, DNS over TCP uses a prefix of C<n> (2 octet network order),
EPP uses a prefix of C<N> (4 octtes).
Example: read a block of data prefixed by its length in BER-encoded
format (very efficient).
$handle->push_read (packstring => "w", sub {
my ($handle, $data) = @_;
});
=cut
register_read_type packstring => sub {
my ($self, $cb, $format) = @_;
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 $format, $_[0]{rbuf} })
or return;
$format = length pack $format, $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, "";
$cb->($_[0], $data);
} else {
# remove prefix
substr $_[0]{rbuf}, 0, $format, "";
# read remaining chunk
$_[0]->unshift_read (chunk => $len, $cb);
}
1
}
};
=item json => $cb->($handle, $hash_or_arrayref)
Reads a JSON object or array, decodes it and passes it to the
callback. When a parse error occurs, an C<EBADMSG> error will be raised.
If a C<json> object was passed to the constructor, then that will be
used for the final decode, otherwise it will create a L<JSON::XS> or
L<JSON::PP> coder object expecting UTF-8.
This read type uses the incremental parser available with JSON version
2.09 (and JSON::XS version 2.2) and above.
Since JSON texts are fully self-delimiting, the C<json> read and write
types are an ideal simple RPC protocol: just exchange JSON datagrams. See
the C<json> write type description, above, for an actual example.
=cut
register_read_type json => sub {
my ($self, $cb) = @_;
my $json = $self->{json} ||= json_coder;
my $data;
sub {
my $ref = eval { $json->incr_parse ($_[0]{rbuf}) };
if ($ref) {
$_[0]{rbuf} = $json->incr_text;
$json->incr_text = "";
$cb->($_[0], $ref);
1
} elsif ($@) {
# error case
$json->incr_skip;
$_[0]{rbuf} = $json->incr_text;
$json->incr_text = "";
$_[0]->_error (Errno::EBADMSG);
()
} 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
( run in 0.991 second using v1.01-cache-2.11-cpan-39bf76dae61 )