libwww-perl / libwww-perl/Net-HTTP

Net-HTTP 6.06 intermittent death in Net::HTTP::Methods sub my_readline() (solved) [rt.cpan.org #86448]

Open
#28 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Perl
Stars
20
Forks
27
PR merge metrics
No merged PRs in 30d

Description

Migrated from rt.cpan.org#86448 (status was 'new')

Requestors:

  • Ray.Ferguson@cdw.com

From ray.ferguson@cdw.com on 2013-06-26 15:46:52:

Description:

Net::HTTP::Methods from Net-HTTP 6.06 dies intermittently with:

Status read failed: No such file or directory at …/perl/vendor/lib/Net/HTTP/Methods.pm line 265.


Cause:

IO::Socket::SSL object can reject the read request with an error of either "SSL wants a read first" or "SSL wants a write first."  This is apparently some overhead of SSL where it wants a read/write before allowing you to read/write in some cases.  It's described somewhat (but not much) better under errstr() in the latest IO::Socket::SSL perldoc.


Reproducing:

I'm not sure how hard this is to reproduce since triggers are unknown.  I'm accessing cloud based SOAP via SOAP::WSDL over https from a busy server and it occurs maybe one out of a dozen times.  It seems to correlate with SSL taking an extra bit of time to setup the connection when something in the chain is busier or has a little latency.  Thus far, I've only seen SSL_WANT_READ, and it clears immediately on the next redo READ, but there seems to be no harm in preparing for SSL_WANT_WRITE in the patch as well.


Patch:

--- broken/Net/HTTP/Methods.pm    2013-03-10 23:35:42.000000000 -0500
+++ fixed/Net/HTTP/Methods.pm 2013-06-26 10:12:37.205639200 -0500
@@ -243,40 +243,41 @@
 sub my_readline {
     my $self = shift;
     my $what = shift;
     for (${*$self}{'http_buf'}) {
        my $max_line_length = ${*$self}{'http_max_line_length'};
        my $pos;
        while (1) {
            # find line ending
            $pos = index($_, "\012");
            last if $pos >= 0;
            die "$what line too long (limit is $max_line_length)"
                if $max_line_length && length($_) > $max_line_length;

            # need to read more data to find a line ending
           READ:
             {
                 die "read timeout" unless $self->can_read;
                 my $n = $self->sysread($_, 1024, length);
                 unless (defined $n) {
                     redo READ if $!{EINTR} || $!{EAGAIN};
+                    redo READ if ( $self->isa('IO::Socket::SSL') && $self->errstr() =~ /^SSL wants a (?:read|write) first$/ );
                     # if we have already accumulated some data let's at least
                     # return that as a line
                     die "$what read failed: $!" unless length;
                 }
                 unless ($n) {
                     return undef unless length;
                     return substr($_, 0, length, "");
                 }
             }
        }
        die "$what line too long ($pos; limit is $max_line_length)"
            if $max_line_length && $pos > $max_line_length;

        my $line = substr($_, 0, $pos+1, "");
        $line =~ s/(\015?\012)\z// || die "Assert";
        return wantarray ? ($line, $1) : $line;
     }
 }


Thanks for your time and your code.

--

Raymond Ferguson

Integrated Applications Engineer  | CDW

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Review Net/HTTP/Methods.pm, focusing on the my_readline() entry point and the reported failure at line 265. Compare the supplied patch with the SSL_WANT_READ and SSL_WANT_WRITE behavior described in the issue. Done means intermittent HTTPS reads no longer die when IO::Socket::SSL requests another read or write first.

Written by the indexing model from the issue text.

Assessment

Tech stack
perl
Domain
networking
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.