Subject: | Delayed response results in 500 error |
The changes made in 6.07 cause spurious problems with systems which have a high connection latency to the internet. The error returned is:
A connect request was made on an already connected socket. at C:/Strawberry/perl/vendor/lib/LWP/Protocol/http.pm line 49.
Four files are attached: TestW.pl always works (for comparison), TestF.pl always fails (see below), Error.txt is the full text of the error message, and Diff.txt is the diff between the working version (6.06) and non-working version (6.07) of HTTP.pm.
Specifically, a NAT system directly connected to the internet never sees the error, a system using a hard-line ethernet to the NAT sees the error 20% of the time, and a system using a WiFi dongle to the NAT sees the error 100% of the time.
This is not in any way a problem with the systems, the internet connections, or configurations thereof. I have included a test case that always works; additionally, version 6.06 of HTTP.pm always works, while 6.07 fails on the same system.
This is using the Strawberry perl Win32 ZIP version, on a fresh install of WinXP service pack 3 known to have no viruses.
The module HTTP.pm is used indirectly by CPAN, so this bug breaks CPAN, which is how I initially found it. A laptop connecting via WiFi to a home NAT system will be unable to run CPAN.
For comparison, note that bug #98306 refers to other problems caused by the same paragraph of code in HTTP.pm V6.07.
This problem may be difficult for to debug and test. I have machines on a NAT setup as described - if the authors/maintainers need an external test bed please contact me.
Subject: | Diff.txt |
8,18c8,9
< # Try several, in order of capability and preference
< if (eval { require IO::Socket::IP }) {
< $SOCKET_CLASS = "IO::Socket::IP"; # IPv4+IPv6
< } elsif (eval { require IO::Socket::INET6 }) {
< $SOCKET_CLASS = "IO::Socket::INET6"; # IPv4+IPv6
< } elsif (eval { require IO::Socket::INET }) {
< $SOCKET_CLASS = "IO::Socket::INET"; # IPv4 only
< } else {
< require IO::Socket;
< $SOCKET_CLASS = "IO::Socket::INET";
< }
---
> eval { require IO::Socket::INET } || require IO::Socket;
> $SOCKET_CLASS = "IO::Socket::INET";
Subject: | Error.txt |
500 Can't connect to www.google.com:80
Content-Type: text/plain
Client-Date: Sun, 21 Dec 2014 19:43:03 GMT
Client-Warning: Internal response
Can't connect to www.google.com:80
A connect request was made on an already connected socket. at C:/Strawberry/perl/vendor/lib/LWP/Protocol/http.pm line 49.
500 Can't connect to www.google.com:80
Subject: | TestF.pl |
# Early in your program:
use strict;
use warnings;
use Carp;
use HTTP::Request;
use LWP;
my $request = HTTP::Request->new(GET => 'http://www.google.com/');
my $ua = LWP::UserAgent->new;
my $response = $ua->request($request);
unless( $response->is_success ) {
print $response->as_string . "\n";
print $response->status_line . "\n";
}
Subject: | TestW.pl |
# Early in your program:
use strict;
use warnings;
use Carp;
use IO::Socket::IP;
#
# This example works. See other file for example that doesn't work
#
my $sock = IO::Socket::IP->new(
PeerHost => "www.google.com",
PeerPort => "http",
Type => SOCK_STREAM,
) or die "Cannot construct socket - $@";