Hi connoisseurs pearl!
I write the simplest script for http get. I tried to use HTTP::Tiny and LWP but for some reason, they do not have a timeout. I look through the strace using my script, it comes to connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("1.1.1.1")}, 16) and silence ... after a few minutes the timeout of course It works, but it does not suit me, I ask it in 1 second.
I had to use IO::Socket::INET
my @test = ('1.1.1.1'); foreach $i (@test) { my $sock = new IO::Socket::INET (PeerAddr => $i, PeerPort => "http(80)", Timeout => 1); next unless $sock; $sock->autoflush(1); $sock->print("GET /index.htm http/1.1\n\n"); my $dock = join("", $sock->getlines()); print "$dock\n"; } This is how it works without problems. Why?
PS I run the script in docker in the perl image: 5.20
Examples of what doesn't work ...
use HTTP::Tiny; my $tiny = HTTP::Tiny->new( agent => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)', timeout => 1, ); my $response = $tiny->get('http://1.1.1.1/'); die "Failed!\n" unless $response->{success}; print "$response->{status} $response->{reason}\n"; while (my ($k, $v) = each %{$response->{headers}}) { for (ref $v eq 'ARRAY' ? @$v : $v) { print "$k: $_\n"; } } and
use IO::Socket; my $t = time; my $sock = IO::Socket::Socks->new( ConnectAddr => '1.1.1.1', ConnectPort => 80, Timeout => 1 ) or print "connection failed or timed out\n"; print "time: " . (time - $t) . "\n"; and before the heap
use LWP::UserAgent my $ua = LWP::UserAgent->new; $ua->timeout(1); my $response = $ua->get('http://1.1.1.1/'); if ($response->is_error) { printf "[%d] %s\n", $response->code, $response->message; # record the timeout if ($response->code == HTTP::Status::HTTP_REQUEST_TIMEOUT) { print "hello \n"; } }
docker run --rm -it perl:5.20 bash? FACEPALM - user245874