WWW--Curl icon indicating copy to clipboard operation
WWW--Curl copied to clipboard

CURLOPT_RESOLV crashes perl

Open davehayes opened this issue 10 years ago • 2 comments

#!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 ()

davehayes avatar Jan 04 '15 23:01 davehayes

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.

seabadger avatar Jan 04 '17 16:01 seabadger

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.

agibson2 avatar Oct 20 '23 22:10 agibson2