Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inherit with 'use parent' instead of 'use base' #78

Merged
merged 1 commit into from
Mar 11, 2024

Conversation

mtsanovv
Copy link
Contributor

@mtsanovv mtsanovv commented Mar 8, 2024

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.

Copy link
Member

@oalders oalders left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much for all of your detective work. That was a subtle change 7 years ago!

@mtsanovv
Copy link
Contributor Author

mtsanovv commented Mar 9, 2024

Hi @oalders, thanks for the PR approval! Are there any concerns preventing its merge?

@oalders
Copy link
Member

oalders commented Mar 10, 2024

No concerns here. I just wanted to see if anyone else had an opinion. I plan to merge and release in the next couple of days.

@oalders oalders merged commit c84f9c8 into libwww-perl:master Mar 11, 2024
41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants