Net-ACME2
view release on metacpan or search on metacpan
lib/Net/ACME2/Curl.pm view on Meta::CPAN
sub set_easy_callback {
my ($self, $cb) = @_;
$self->{'_easy_cb'} = $cb;
return $self;
}
sub _get_ua_string {
my ($self) = @_;
return ref($self) . " $Net::ACME2::VERSION";
}
# Not documented because itâs part of the required interface.
sub request {
my ($self, $method, $url, $args_hr) = @_;
my $easy = $self->_xlate_http_tiny_request_to_net_curl_easy($method, $url, $args_hr);
$_ = q<> for @{$easy}{ qw( _head _body ) };
$easy->setopt( Net::Curl::Easy::CURLOPT_HEADERDATA(), \$easy->{'_head'} );
$easy->setopt( Net::Curl::Easy::CURLOPT_FILE(), \$easy->{'_body'} );
my $p1 = $self->{'_promiser'}->add_handle($easy)->then(
sub {
my ($easy) = @_;
return _imitate_http_tiny( shift(), @{$easy}{'_head', '_body'} );
},
sub {
return {
success => 0,
url => $easy->getinfo( Net::Curl::Easy::CURLINFO_EFFECTIVE_URL() ),
status => 599,
reason => _HTTP_TINY_INTERNAL_EXCEPTION_REASON,
content => q<> . shift(),
headers => {},
};
},
);
return $p1->then( sub {
my ($resp) = @_;
return Net::ACME2::HTTP::Convert::http_tiny_to_net_acme2($method, $resp);
} );
}
# curl response -> HTTP::Tiny response
sub _imitate_http_tiny {
my ($easy, $head, $body) = @_;
my $status_code = $easy->getinfo( Net::Curl::Easy::CURLINFO_RESPONSE_CODE() );
my $reason;
my %headers;
for my $line ( split m<\x0d?\x0a>, $head ) {
next if !length $line;
if (defined $reason) {
my ($name, $value) = split m<\s*:\s*>, $line, 2;
$name =~ tr<A-Z><a-z>;
if (exists $headers{$name}) {
if (ref $headers{$name}) {
push @{$headers{$name}}, $value;
}
else {
$headers{$name} = [ $headers{$name}, $value ];
}
}
else {
$headers{$name} = $value;
}
}
else {
if ( $line =~ m<.+? \s+ .+? \s+ (.*)>x ) {
$reason = $1;
}
else {
die Net::ACME2::X->create('Generic', "Unparsable first header line: [$line]");
}
}
}
my %resp = (
success => ($status_code >= 200) && ($status_code <= 299),
url => $easy->getinfo( Net::Curl::Easy::CURLINFO_EFFECTIVE_URL() ),
status => $status_code,
reason => $reason,
content => $body,
headers => \%headers,
);
return \%resp;
}
# HTTP::Tiny request -> curl request
sub _xlate_http_tiny_request_to_net_curl_easy {
my ($self, $method, $url, $args_hr) = @_;
my $easy = Net::Curl::Easy->new();
# By setting this here we allow the callback to overwrite it.
$easy->setopt( Net::Curl::Easy::CURLOPT_USERAGENT(), $self->_get_ua_string() );
$self->{'_easy_cb'}->($easy) if $self->{'_easy_cb'};
# $easy->setopt( Net::Curl::Easy::CURLOPT_VERBOSE(), 1 );
$easy->setopt( Net::Curl::Easy::CURLOPT_URL(), $url );
_assign_headers( $args_hr->{'headers'}, $easy );
if ($method eq 'POST') {
$easy->setopt( Net::Curl::Easy::CURLOPT_POST(), 1 );
if (defined $args_hr->{'content'} && length $args_hr->{'content'}) {
$easy->setopt(
Net::Curl::Easy::CURLOPT_POSTFIELDSIZE(),
length $args_hr->{'content'},
( run in 0.444 second using v1.01-cache-2.11-cpan-71847e10f99 )