Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SOAP::Lite Perl Module Sends Wrong SOAP Envelope Namespace

I am having problems writing a SOAP/XML client to talk to an API provided by a company called Domainbox. I am writing the client in Perl using the SOAP::Lite Module/Library. I am getting the following error message:

Possible SOAP version mismatch: Envelope namespace http://schemas.xmlsoap.org/soap/envelope/ was unexpected. Expecting http://www.w3.org/2003/05/soap-envelope.

This is because the library is sending the SOAP Envelope using a SOAP 1.1 Namespace and the server expects SOAP 1.2.

But I cannot come up with a solution, I've tried explicitly setting $soap->soapversion('1.2'); in the SOAP::Lite object but this only affects the Envelope received in the response message, not the Envelope sent by the client.

The server is running ASP.net and doesn't seem to want to accept SOAP version 1.1 messages.

Querying the soapversion() method by default it returns version 1.1 and when I change it to 1.2 it returns 1.2 but internally it is clearly ignoring this somewhere.

The WSDL doesn't seem to define xmlns:soap or xmlns:soap12 properly but SOAP::Lite isn't using those Namespaces either. I would provide a link but I am not allowed to post more than two on here.

I tried also using the service() method of SOAP::Lite but that made no difference at all.

Here's the code I'm using:

#!/usr/bin/perl -w
use strict;
use SOAP::Lite;
use Data::Dumper;

### API Info
my $reseller = 'Removed';
my $username = 'Removed';
my $password  = 'Removed';

my $soap = SOAP::Lite->new(proxy => 'https://sandbox.domainbox.net/');
$soap->default_ns('https://sandbox.domainbox.net/');
$soap->soapversion('1.2');

my $header = SOAP::Header->new->attr({xmlns => 'https://sandbox.domainbox.net/'});

my $body = SOAP::Data->name('CheckDomainAvailability' => \SOAP::Data->value(
            SOAP::Data->name('AuthenticationParameters' => \SOAP::Data->value(
                SOAP::Data->name('Reseller' => $reseller),
                SOAP::Data->name('Username' => $username),
                SOAP::Data->name('Password' => $password),
            )
        )
    )
);

$soap->on_action( sub { "https://sandbox.domainbox.net/" });
my $som = $soap->call('',
$header,
$body
);

die $som->faultstring if ($som->fault);
print $som->result, "\n";

#print Dumper($som);

Additional:

The xmlns:soap attribute in the envelope is set to http://schemas.xmlsoap.org/soap/envelope regardless of the soapversion setting in the class. I am thinking it's a bug in the Perl module or something strange about the WSDL that is causing it. Here's the WSDL: http://sandbox.domainbox.net/?WSDL

XML Request Message:

<?xml version="1.0" encoding="UTF-8"?><Envelope 
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org
/2001/XMLSchema-instance"><Header><c-gensym3 
xmlns="https://sandbox.domainbox.net/" /></Header><Body><DomainboxAPI 
xmlns="https://sandbox.domainbox.net/"><CheckDomainAvailability>
<AuthenticationParameters><Reseller 
xsi:type="xsd:string">Removed</Reseller><Username 
xsi:type="xsd:string">Removed</Username><Password 
xsi:type="xsd:string">Removed</Password></AuthenticationParameters>
</CheckDomainAvailability></DomainboxAPI></Body></Envelope>

XML Response Message:

<?xml version="1.0" encoding="utf-8"?><soap:Envelope 
xmlns:soap="http://www.w3.org/2003/05/soap-envelope" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Header>
<soap12:Upgrade xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:SupportedEnvelope qname="soap12:Envelope" 
xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"/></soap12:Upgrade>
</soap:Header><soap:Body><soap:Fault><soap:Code>
<soap:Value>soap:VersionMismatch</soap:Value></soap:Code><soap:Reason>
<soap:Text xml:lang="en">Possible SOAP version mismatch: Envelope 
namespace  was unexpected. Expecting http://www.w3.org/2003/05/soap-
envelope.</soap:Text></soap:Reason><soap:Detail /></soap:Fault>
</soap:Body></soap:Envelope>

Update:

Thanks Borodin, you were spot on. The SOAP::Lite module doesn't seem to pass the soapversion parameter on to the SOAP::Lite::Serializer object. I now use the following code to initialize the SOAP object and it works perfectly.

my $soap = SOAP::Lite->new(proxy => 'https://sandbox.domainbox.net/');
$soap->default_ns('https://sandbox.domainbox.net/');
$soap->soapversion('1.2');
$soap->serializer->soapversion('1.2');

I should point out that I had to also adjust my code to suit the XML format required by Domainbox but I am now getting a valid response.

My only issue now is how to deal with the Hash reference that the SOAP::Lite::SOM returns as the result of the message. I think that requires a separate question though.

like image 534
Ed Gray Avatar asked Nov 09 '22 07:11

Ed Gray


1 Answers

The answer to my question was provided by Borodin. The correct code is to use the soapversion method both on the SOAP::Lite object and the SOAP::Lite::Serializer object. Here is a working example:

my $soap = SOAP::Lite->new(proxy => 'https://sandbox.domainbox.net/');
$soap->default_ns('https://sandbox.domainbox.net/');
$soap->soapversion('1.2');
$soap->serializer->soapversion('1.2');
like image 145
Ed Gray Avatar answered Nov 15 '22 05:11

Ed Gray