Subject: | peerhost() and friends may cause croak() |
If we'll call peerhost() method on IO::Socket::IP object when remote side closed connection it will croak() with message "addr is not a string". Looks like peerhostname() and others has same problem. In fact in such situation this method should return undef and set $! to ENOTCONN
Test:
use strict;
use IO::Socket::INET;
use IO::Socket::IP;
use Test::More;
use Errno;
for my $impl ('INET', 'IP') {
my ($pid, $host, $port) = make_srv();
my $s = "IO::Socket::$impl"->new("$host:$port") or die $@;
$s->syswrite(rand());
sleep 1;
my $peerhost = eval { $s->peerhost };
ok($! == Errno::ENOTCONN, "$impl: \$! properly set");
ok(!$@, "$impl: without exceptions") or diag $@;
ok(!$peerhost, "$impl: no peerhost");
kill 15, $pid;
}
done_testing;
sub make_srv {
my $srv = IO::Socket::INET->new(Listen => 10);
my $child = fork;
if ($child == 0) {
while (1) {
my $cli = $srv->accept() or die $!;
$cli->sysread(my $buf, 10);
$cli->close();
}
exit;
}
return ($child, $srv->sockhost eq "0.0.0.0" ? "127.0.0.1" : $srv->sockhost, $srv->sockport);
}
__END__
Output:
ok 1 - INET: $! properly set
ok 2 - INET: without exceptions
ok 3 - INET: no peerhost
ok 4 - IP: $! properly set
not ok 5 - IP: without exceptions
# Failed test 'IP: without exceptions'
# at /tmp/srv.pl line 17.
# addr is not a string at /tmp/IO-Socket-IP-0.31/lib/IO/Socket/IP.pm line 694.
ok 6 - IP: no peerhost
1..6
# Looks like you failed 1 test of 6.
And this may be the initiator of croak(): https://metacpan.org/source/RJBS/perl-5.20.0/cpan/Socket/Socket.xs#L542
And here is where I faced out with this problem: http://www.cpantesters.org/distro/W/WebService-Antigate.html?oncpan=1&distmat=1&version=0.05
Last LWP uses IO::Socket::IP if available. And I got 10 fail reports at one day.