WWW--Curl
WWW--Curl copied to clipboard
CURLOPT_RESOLV crashes perl
#!perl
use strict;
use WWW::Curl::Easy;
use HTTP::Headers;
use HTTP::Request;
use HTTP::Response;
my $host = $ARGV[0] || 'www.google.com';
my $req = HTTP::Request->new( GET => 'http://'. $host .'/' );
my $curl = WWW::Curl::Easy->new();
my $url = $req->uri->as_string;
$curl->setopt(CURLOPT_URL, $url);
$curl->setopt(CURLOPT_CUSTOMREQUEST, $req->method);
my @headers;
foreach my $h (+$req->headers->header_field_names) {
push(@headers, "$h: " . $req->header($h));
}
$curl->setopt(CURLOPT_HTTPHEADER, \@headers) if ($#headers >= 0);
my $dns = [ $host.':80:127.0.0.1' ];
$curl->setopt(CURLOPT_RESOLVE, $dns);
my ($body, $head);
open (my $fileb, ">", \$body);
$curl->setopt(CURLOPT_WRITEDATA,$fileb);
open (my $fileh, ">", \$head);
$curl->setopt(CURLOPT_WRITEHEADER,$fileh);
my $retcode = $curl->perform;
my $response;
if ($retcode == 0) {
$response = HTTP::Response->parse($head . "\r" . $body);
$response->request($req);
$response->content($body);
} else {
die "An error happened: ".$curl->strerror($retcode)." ($retcode)\n";
}
warn "----\nGot response: ".$response->as_string()."\n";
This causes a core dump when you do a "perform".
Here's a stack trace in case this helps:
> gdb `which perl` perl.core
...
(gdb) bt
#0 0x0000000804e1bde9 in ?? () from /usr/local/lib/libcurl.so.7
#1 0x0000000804e3a64e in curl_mvsnprintf () from /usr/local/lib/libcurl.so.7
#2 0x0000000804e4377c in curl_multi_fdset () from /usr/local/lib/libcurl.so.7
#3 0x0000000804e44b7b in curl_multi_perform () from /usr/local/lib/libcurl.so.7
#4 0x0000000804e3c3ef in curl_easy_perform () from /usr/local/lib/libcurl.so.7
#5 0x0000000804c0a3df in XS_WWW__Curl__Easy_perform () from /usr/local/lib/perl5/site_perl/5.16/mach/auto/WWW/Curl/Curl.so
#6 0x00000008008d75b0 in Perl_pp_entersub () from /usr/local/lib/perl5/5.16/mach/CORE/libperl.so
#7 0x00000008008d5b6e in Perl_runops_standard () from /usr/local/lib/perl5/5.16/mach/CORE/libperl.so
#8 0x000000080086a4cc in perl_run () from /usr/local/lib/perl5/5.16/mach/CORE/libperl.so
#9 0x0000000000400f3b in main ()
The issue only appears in 4.17; 4.16 is OK.
It was introduced by commit 499baf9c3689c23dfc49196570fb230076c935de, which adds preprocessor conditionals based on whether CURLOPT_RESOLVE is defined:
+#ifdef CURLOPT_RESOLVE SLIST_RESOLVE, SLIST_RESOLVE, +#endif
Unfortunately, CURLOPT_RESOLVE is an enum, and NOT a preprocessor macro, so in effect this commit removed support for CURLOPT_RESOLVE, and results in a perl crash if the option is used.
I don't know if anyone is maintaining this, but I found the cause of this particular issue, documenting it here.
I just stumbled onto this on RHEL 9. I need to test links using the hostname to multiple websites (clusters) bypassing DNS to use specific IPs and compare the output. I am hopeful someone reverts that commit so that EL distros can get the change.