With #30, the way LWP::Protocol::https and LWP::Protocol::https::Socket have their parents defined changed from using the @ISA list to use base. However, use base apart from defining the parent(s) of packages also tries loading the classes in question. When using SOAP::Lite and LWP::Protocol::https as an implementor for LWP::Protocol, trying to send an HTTPS request leads to a failure, and the IO::Socket::SSL::SSL_ERROR scalar which technically is meant to contain SSL failure messages contains the following error instead: Can't locate object method "new" via package "LWP::Protocol::https::Socket" at SOAP/Client.pm. The final error is the following:
Cannot load LWP::Protocol::https: Can't locate LWP/Protocol/http/SocketMethods.pm in <inc_paths>) at base.pm line 105
...propagated at base.pm line 159, <STDIN> line 5.
I am using a custom perl + modules distribution, but I have the latest LWP::Protocol::http in @INC and there is no way it doesn't contain the LWP::Protocol::http::SocketMethods package.
This is an excerpt from the code that performs the SOAP::Lite requests (I did my best to keep the code as runnable as possible while getting rid of custom things):
My/Custom/SOAP/Schema.pm:
package SOAP::Schema;
package My::Custom::SOAP::Schema;
use strict;
#
# override access() to get wsdl from a buffer
#
our @ISA = qw (SOAP::Schema);
sub setWsdlBuf{
$_[0]->{_wsdlbuf} = $_[1];
}
sub access{
my $self = shift;
if ($self->{_wsdlbuf}){
return $self->{_wsdlbuf};
}
return $self->SUPER::access (@_);
}
1;
driver script:
use My::Custom:::SOAP::Schema;
use SOAP::Lite;
our ($wsdlDefinition, $baseUrl, $keepAlive, $timeout, $host, $port, $user, $realm, $password); # imported from elsewhere
require LWP::Protocol::https;
LWP::Protocol::implementor( 'https' => 'LWP::Protocol::https');
my $schema = My::Custom:::SOAP::Schema->new();
$schema->setWsdlBuf($wsdlDefinition);
my $soapLiteObj = SOAP::Lite->new();
$soapLiteObj->schema($schema);
local $SIG{__WARN__} = sub {};
my $soapLiteService = $soapLiteObj->service($baseUrl);
my $ssl_opts = {
# some properties like cert file path and hostname verification
};
my $credentials = [
"$host:$port",
$realm,
$user,
$password
];
my $service = $soapLiteService->proxy(
$baseUrl,
'keep_alive' => $keepAlive,
'timeout'=> $timeout,
'credentials' => $credentials,
'ssl_opts' => [%$ssl_opts]
);
$service->on_fault (
sub {
my $soap = shift;
my $res = shift;
if(!ref($res)) {
my $error = $soap->transport ()->status ();
if (defined $IO::Socket::SSL::SSL_ERROR){
$error .= ": $IO::Socket::SSL::SSL_ERROR";
}
say STDERR "SOAP::Lite error: $error"; # this is where the LWP::Protocol::https error in question is observed
return;
}
return $res->fault();
}
);
$service->someMethod();
Apart from resolving SOAP::Lite failures for people that have code similar to mine (I'm not sure if there are many because #30 is 7 years old), this change also has the following benefits:
use base is technically a backwards incompatible change for LWP::Protocol::https::Socket, previously its parent was never loaded unless needed with our @ISA and this restores the backwards compatibility;
As per https://perldoc.perl.org/base, "Unless you are using the fields pragma, consider this module discouraged in favor of the lighter-weight parent." - LWP::Protocol::https will be using the modern, supported way of inheriting packages;
Last but not least, it will match its parent, LWP::Protocol::http's way of inheriting classes.
I've been testing this over the course of a month and it seems fairly stable. Feel free to share feedback as well.
With #30, the way LWP::Protocol::https and LWP::Protocol::https::Socket have their parents defined changed from using the
@ISA
list touse base
. However,use base
apart from defining the parent(s) of packages also tries loading the classes in question. When using SOAP::Lite and LWP::Protocol::https as an implementor for LWP::Protocol, trying to send an HTTPS request leads to a failure, and the IO::Socket::SSL::SSL_ERROR scalar which technically is meant to contain SSL failure messages contains the following error instead:Can't locate object method "new" via package "LWP::Protocol::https::Socket" at SOAP/Client.pm
. The final error is the following:I am using a custom perl + modules distribution, but I have the latest LWP::Protocol::http in
@INC
and there is no way it doesn't contain the LWP::Protocol::http::SocketMethods package.This is an excerpt from the code that performs the SOAP::Lite requests (I did my best to keep the code as runnable as possible while getting rid of custom things):
My/Custom/SOAP/Schema.pm:
driver script:
Apart from resolving SOAP::Lite failures for people that have code similar to mine (I'm not sure if there are many because #30 is 7 years old), this change also has the following benefits:
use base
is technically a backwards incompatible change for LWP::Protocol::https::Socket, previously its parent was never loaded unless needed withour @ISA
and this restores the backwards compatibility;I've been testing this over the course of a month and it seems fairly stable. Feel free to share feedback as well.