-
Couldn't load subscription status.
- Fork 35
Description
When making HTTPS requests, there are some types of error that do not get reported in a way that allows for proper troubleshooting. For example:
500 Can't connect to localhost:8888
At a glance, this looks like some sort of networking issue--perhaps the service is not running. The problem in this example case, however, is that the CA certificate file is invalid; there's no way to know that from the error.
The error message is formed in LWP::Protocol::http, which calls the socket class new method and checks for errors. Error messages are expected to be in $@.
https://github.com/libwww-perl/libwww-perl/blob/1c1f28d/lib/LWP/Protocol/http.pm#L26-L49
I can tell that the errors are formed in IO::Socket::SSL, though, which exports and sets $SSL_ERROR instead of $@. I don't know the best way to fix this; either LWP should check $SSL_ERROR or something should set $@ instead. There are some levels of abstraction between LWP::Protocol::http and IO::Socket::SSL, but I got mixed up understanding the inheritance and I'm not exactly sure what is in the middle. I will provide an example program and a stack trace below.
#!/usr/bin/perl
use strict;
use warnings;
use HTTP::Request;
use LWP::UserAgent;
use IO::Socket::SSL;
my $ua = LWP::UserAgent->new;
my %ssl_opts = (
# /etc/hostname is obviously not a CA cert; we use this to induce an
# error from IO::Socket::SSL.
SSL_ca_file => '/etc/hostname',
);
$ua->ssl_opts(%ssl_opts);
# There need not be a service on this port--we never get far enough to use it.
my $req = HTTP::Request->new(GET => 'https://localhost:8888');
my $resp = $ua->request($req);
print "\n\n";
print "error from LWP::UserAgent: ", $resp->status_line, "\n";
print "error from IO::Socket::SSL: ", $SSL_ERROR, "\n";
# Monkey-patch this method so we can get a stack trace.
sub IO::Socket::SSL::error {
my ($self, $error) = @_;
# The following line is new vs. the original IO::Socket::SSL::error.
use Carp; Carp::cluck($error);
my @err;
while ( my $err = Net::SSLeay::ERR_get_error()) {
push @err, Net::SSLeay::ERR_error_string($err);
# The following line is modified to fully scope the DEBUG variable.
$IO::Socket::SSL::DEBUG>=2 && DEBUG( $error."\n".$self->get_ssleay_error());
}
$error .= ' '.join(' ',@err) if @err;
return $self->_internal_error($error,4) if $error;
return;
}
The output is:
$ /tmp/test.pl
Subroutine IO::Socket::SSL::error redefined at /tmp/test.pl line 31.
Invalid certificate authority locations at /tmp/test.pl line 34.
IO::Socket::SSL::error("IO::Socket::SSL", "Invalid certificate authority locations") called at /usr/share/perl5/IO/Socket/SSL.pm line 2648
IO::Socket::SSL::SSL_Context::new("IO::Socket::SSL::SSL_Context", HASH(0x55657cff6830)) called at /usr/share/perl5/IO/Socket/SSL.pm line 675
IO::Socket::SSL::configure_SSL(LWP::Protocol::https::Socket=GLOB(0x55657d6d4e40), HASH(0x55657cff6830)) called at /usr/share/perl5/IO/Socket/SSL.pm line 641
IO::Socket::SSL::configure(LWP::Protocol::https::Socket=GLOB(0x55657d6d4e40), HASH(0x55657cff6830)) called at /usr/share/perl5/Net/HTTPS.pm line 67
Net::HTTPS::http_connect(LWP::Protocol::https::Socket=GLOB(0x55657d6d4e40), HASH(0x55657cff6830)) called at /usr/share/perl5/Net/HTTP/Methods.pm line 89
Net::HTTP::Methods::http_configure(LWP::Protocol::https::Socket=GLOB(0x55657d6d4e40), HASH(0x55657cff6830)) called at /usr/share/perl5/Net/HTTPS.pm line 48
Net::HTTPS::configure(LWP::Protocol::https::Socket=GLOB(0x55657d6d4e40), HASH(0x55657cff6830)) called at /usr/lib/x86_64-linux-gnu/perl-base/IO/Socket.pm line 49
IO::Socket::new("LWP::Protocol::https::Socket", "SSL_verifycn_scheme", "www", "SSL_ca_file", "/etc/hostname", "Timeout", 180, "SSL_verify_mode", ...) called at /usr/lib/x86_64-linux-gnu/perl-base/IO/Socket/IP.pm line 121
IO::Socket::IP::new("LWP::Protocol::https::Socket", "PeerAddr", "localhost", "PeerPort", 8888, "LocalAddr", undef, "Proto", ...) called at /usr/share/perl5/LWP/Protocol/http.pm line 33
LWP::Protocol::http::_new_socket(LWP::Protocol::https=HASH(0x55657d61b350), "localhost", 8888, 180) called at /usr/share/perl5/LWP/Protocol/http.pm line 216
LWP::Protocol::http::request(LWP::Protocol::https=HASH(0x55657d61b350), HTTP::Request=HASH(0x55657d424e18), undef, undef, undef, 180) called at /usr/share/perl5/LWP/UserAgent.pm line 214
LWP::UserAgent::try {...} () called at /usr/share/perl5/Try/Tiny.pm line 102
eval {...} called at /usr/share/perl5/Try/Tiny.pm line 93
Try::Tiny::try(CODE(0x55657d5a9f00), Try::Tiny::Catch=REF(0x55657d61b458)) called at /usr/share/perl5/LWP/UserAgent.pm line 229
LWP::UserAgent::send_request(LWP::UserAgent=HASH(0x55657ca700f0), HTTP::Request=HASH(0x55657d424e18), undef, undef) called at /usr/share/perl5/LWP/UserAgent.pm line 301
LWP::UserAgent::simple_request(LWP::UserAgent=HASH(0x55657ca700f0), HTTP::Request=HASH(0x55657d424e18), undef, undef) called at /usr/share/perl5/LWP/UserAgent.pm line 308
LWP::UserAgent::request(LWP::UserAgent=HASH(0x55657ca700f0), HTTP::Request=HASH(0x55657d424e18)) called at /tmp/test.pl line 23
error from LWP::UserAgent: 500 Can't connect to localhost:8888
error from IO::Socket::SSL: Invalid certificate authority locations error:05800088:x509 certificate routines::no certificate or crl found
This is on a Debian system. Versions of relevant packages are:
$ dpkg -l libwww-perl liblwp-protocol-https-perl libio-socket-ssl-perl libnet-http-perl perl
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==========================-============-============-=================================================================
ii libio-socket-ssl-perl 2.088-1 all Perl module implementing object oriented interface to SSL sockets
ii liblwp-protocol-https-perl 6.14-1 all HTTPS driver for LWP::UserAgent
ii libnet-http-perl 6.23-1 all module providing low-level HTTP connection client
ii libwww-perl 6.77-1 all simple and consistent interface to the world-wide web
ii perl 5.38.2-5 amd64 Larry Wall's Practical Extraction and Report Language
Thanks,
Corey