--- AnyEvent/lib/AnyEvent/Handle.pm 2008/10/29 14:32:02 1.102 +++ AnyEvent/lib/AnyEvent/Handle.pm 2009/06/07 16:48:38 1.126 @@ -16,7 +16,7 @@ =cut -our $VERSION = 4.3; +our $VERSION = 4.411; =head1 SYNOPSIS @@ -29,7 +29,7 @@ AnyEvent::Handle->new ( fh => \*STDIN, on_eof => sub { - $cv->broadcast; + $cv->send; }, ); @@ -129,7 +129,9 @@ read buffer). To access (and remove data from) the read buffer, use the C<< ->rbuf >> -method or access the C<$handle->{rbuf}> member directly. +method or access the C<$handle->{rbuf}> member directly. Note that you +must not enlarge or modify the read buffer, you can only remove data at +the beginning from it. When an EOF condition is detected then AnyEvent::Handle will first try to feed all the remaining data to the queued callbacks and C before @@ -257,6 +259,11 @@ or C on it before you pass it to AnyEvent::Handle. +B 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. + See the C<< ->starttls >> method for when need to start TLS negotiation later. =item tls_ctx => $ssl_ctx @@ -376,10 +383,14 @@ =item $handle->autocork ($boolean) Enables or disables the current autocork behaviour (see C -constructor argument). +constructor argument). Changes will only take effect on the next write. =cut +sub autocork { + $_[0]{autocork} = $_[1]; +} + =item $handle->no_delay ($boolean) Enables or disables the C setting (see constructor argument of @@ -760,6 +771,10 @@ } while () { + # we need to use a separate tls read buffer, as we must not receive data while + # we are draining the buffer, and this can only happen with TLS. + $self->{rbuf} .= delete $self->{_tls_rbuf} if exists $self->{_tls_rbuf}; + my $len = length $self->{rbuf}; if (my $cb = shift @{ $self->{_queue} }) { @@ -830,8 +845,11 @@ Returns the read buffer (as a modifiable lvalue). -You can access the read buffer directly as the C<< ->{rbuf} >> member, if -you want. +You can access the read buffer directly as the C<< ->{rbuf} >> +member, if you want. However, the only operation allowed on the +read buffer (apart from looking at it) is removing data from its +beginning. Otherwise modifying or appending to it is not allowed and will +lead to hard-to-track-down bugs. NOTE: The read buffer should only be used or modified if the C, C or C methods are used. The other read methods @@ -1137,7 +1155,8 @@ =item json => $cb->($handle, $hash_or_arrayref) -Reads a JSON object or array, decodes it and passes it to the callback. +Reads a JSON object or array, decodes it and passes it to the +callback. When a parse error occurs, an C error will be raised. If a C object was passed to the constructor, then that will be used for the final decode, otherwise it will create a JSON coder expecting UTF-8. @@ -1164,7 +1183,7 @@ my $json = $self->{json} ||= JSON->new->utf8; sub { - my $ref = $json->incr_parse ($self->{rbuf}); + my $ref = eval { $json->incr_parse ($self->{rbuf}) }; if ($ref) { $self->{rbuf} = $json->incr_text; @@ -1172,8 +1191,19 @@ $cb->($self, $ref); 1 + } elsif ($@) { + # error case + $json->incr_skip; + + $self->{rbuf} = $json->incr_text; + $json->incr_text = ""; + + $self->_error (&Errno::EBADMSG); + + () } else { $self->{rbuf} = ""; + () } } @@ -1324,7 +1354,7 @@ &_freetls; } - $self->{rbuf} .= $tmp; + $self->{_tls_rbuf} .= $tmp; $self->_drain_rbuf unless $self->{_in_drain}; $self->{tls} or return; # tls session might have gone away in callback } @@ -1334,7 +1364,7 @@ if ($tmp != Net::SSLeay::ERROR_WANT_READ ()) { if ($tmp == Net::SSLeay::ERROR_SYSCALL ()) { return $self->_error ($!, 1); - } elsif ($tmp == Net::SSLeay::ERROR_SSL ()) { + } elsif ($tmp == Net::SSLeay::ERROR_SSL ()) { return $self->_error (&Errno::EIO, 1); } @@ -1445,7 +1475,7 @@ } sub DESTROY { - my $self = shift; + my ($self) = @_; &_freetls;