Skip Menu |

This queue is for tickets about the IO-Socket-SSL CPAN distribution.

Report information
The Basics
Id: 19705
Status: resolved
Priority: 0/
Queue: IO-Socket-SSL

People
Owner: Nobody in particular
Requestors: s.zagrodzki [...] net.icm.edu.pl
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.97
Fixed in: (no value)



Subject: read() problem
IO::Socket::SSL::read() uses ssl_read_all() for reading data when $blocking is set. In previous versions it used read(), which has different semantics: ssl_read_all() reads data until EOF, while Net:: SSLeay:read() returned after first EOL. This causes problems for example with HTTP::Daemon:SSL, that uses sysread() on a request. It can't do anything until read() returns, and read() returns only when client closes connection, and in this case processing the request makes no sense... Using ssl_read_CRLF instead of ssl_read_all solves the problem.
From: Steffen_Ullrich [...] genua.de
if the socket is blocking sysread can block, if you don't want this use nonblocking sockets (whcih got better support with version 0.98). But it shouldn't block too much, e.g if yousaid sysread that you need only 512 bytes it will not wait until EOF but only until it got 512 bytes (assuming that there are more then 512 bytes to read). So in my opinion the code is not broken. But could you please send an example program which shows the problem so that I could have a closer look at it? On Mo. 05. Jun. 2006, 08:04:53, guest wrote: Show quoted text
> IO::Socket::SSL::read() uses ssl_read_all() for reading data when > $blocking is set. In previous versions it used read(), which has > different semantics: ssl_read_all() reads data until EOF, while Net:: > SSLeay:read() returned after first EOL. > > This causes problems for example with HTTP::Daemon:SSL, that uses > sysread() on a request. It can't do anything until read() returns, and > read() returns only when client closes connection, and in this case > processing the request makes no sense... > > Using ssl_read_CRLF instead of ssl_read_all solves the problem.
On Pon. 12 Cze. 2006, 19:06:58, guest wrote: Show quoted text
> if the socket is blocking sysread can block, if you don't want > this use nonblocking sockets (whcih got better support with version > 0.98). But it shouldn't block too much, e.g if yousaid sysread > that you need only 512 bytes it will not wait until EOF but only > until it got 512 bytes (assuming that there are more then 512 > bytes to read).
What if I don't know how many bytes should I read before sending some response? Note that you shouldn't have to wait for EOF, because you may want to read something, send some response, and then read again. Currently, with blocking read that doesn't break at CR/LF (like system read() does), it's impossible to implement such behavior, you would have to use non-blocking operations and idle loops, or use read(1) to get first line of received text. This will cause problems when implementing i.e. POP, IMAP or whatever text-oriented protocol over SSL using IO::Socket::SSL, where you have to read one line, and then send something in response, before you get any other input. Show quoted text
> But could you please send an example program which shows the problem > so that I could have a closer look at it?
$httpserver = HTTP::Daemon::SSL->new( Reuse => 1, LocalAddr => $ip, LocalPort => $port, ($SSLKey ? (SSL_key_file => $SSLKey) : ()), ($SSLCert ? (SSL_cert_file => $SSLCert) : ()) ); my $c = $httpserver->accept; my $r = $c->get_request; print "Method: ".$r->method."\n"; In HTTP::Daemon::SSL get_request() uses _need_more(), which has the line: my $n = sysread($self, $_[0], 2048, length($_[0])); sysread is from IO::Socket:SSL, and uses IO::Socket::SSL::read. HTTP request is usually shorter than 2kB, so this read() waits indefinitely.
I see your argument. The problem is that IO::Socket::SSL::read and IO::Socket::SSL::sysread are the same which they should not be, because the semantic of read is to block until all bytes are read (or EOF) while the semantics of sysread are to block only until something is read (if socket is blocking) and to return even if not all requested bytes are read. Show quoted text
> In HTTP::Daemon::SSL get_request() uses _need_more(), which has the > line: > > my $n = sysread($self, $_[0], 2048, length($_[0])); > > sysread is from IO::Socket:SSL, and uses IO::Socket::SSL::read. > HTTP request is usually shorter than 2kB, so this read() waits > indefinitely.
CC: s.zagrodzki [...] net.icm.edu.pl, BEHROOZI [...] cpan.org
Subject: Re: [rt.cpan.org #19705] read() problem
Date: Tue, 18 Jul 2006 10:22:15 +0200
To: Steffen Ullrich via RT <bug-IO-Socket-SSL [...] rt.cpan.org>
From: Sebastian Zagrodzki <s.zagrodzki [...] net.icm.edu.pl>
On Tue, Jul 18, 2006 at 02:31:30AM -0400, Steffen Ullrich via RT wrote: Show quoted text
> The problem is that IO::Socket::SSL::read and IO::Socket::SSL::sysread > are the same which they should not be, because the semantic of read is > to block until all bytes are read (or EOF) while the semantics of > sysread are to block only until something is read (if socket is > blocking) and to return even if not all requested bytes are read.
Ok, if I got it right, I assume this should or will be changed. Should I prepare the patch myself, or will you do it? This should be easy, as read() is simply a call to generic_read. I suppose using: sub sysread { my $self = shift; return $self->generic_read($self->blocking ? \&Net::SSLeay::ssl_read_CRLF : \&Net::SSLeay::read, @_); } instead of calling read() will do it? -- Sebastian Zagrodzki DziaƂ Sieciowy ICM, Uniwersytet Warszawski s.zagrodzki@net.icm.edu.pl (+48-22) 5520527, 8268009, fax. 8284195 http://www.net.icm.edu.pl/
I have a patch already and it is fairly simple (just call generic_read with Net::SSLeay::read no matter if blocking or not). But nevertheless it needs testing. So the next version will be uploaded in the next days. But I don't know where you get the idea that sysread should read until the next CRLF? This would be contrary to the usual behavior of sysread. Usually sysread just tries to read and returns what it got, no matter if this ends with CRLF or not. Maybe you assumed CRLF because the HTTP header ends with CRLF, so the final packet of the header will end in CRLF. But this is not a property of sysread, it's a property of the data you read. Steffen Show quoted text
> Ok, if I got it right, I assume this should or will be changed. Should > I prepare the patch myself, or will you do it? This should be easy, as > read() is simply a call to generic_read. I suppose using: > > sub sysread { > my $self = shift; > return $self->generic_read($self->blocking ? > \&Net::SSLeay::ssl_read_CRLF : \&Net::SSLeay::read, @_); > } > > instead of calling read() will do it? >
fixed in version 0.991 by using Net::SSLeay::read instead of ssl_read_all