Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

SOAP Headers, WSDL and SOAP::Lite

by rob_au (Abbot)
on Mar 11, 2004 at 06:23 UTC ( #335732=perlquestion: print w/ replies, xml ) Need Help??
rob_au has asked for the wisdom of the Perl Monks concerning the following question:

I have come across a problem with SOAP::Lite and the employ of request headers which after much searching with Google, I now turn to the Monastery - Recently in my professional capacity I have had to create a SOAP interface for some web services which the company which I work for seeks to provide. This has been successfully implemented using Apache/mod_perl and SOAP::Lite and as part of the solution, ticket-based authentication, similar to that described in the SOAP::Lite guide (http://guide.soaplite.com), was employed to restrict access to particular methods. Using SOAP::Lite, a sample test client was developed in the following fashion:

use SOAP::Lite; my $client = SOAP::Lite ->uri('http://localhost/Service') ->proxy('http://localhost/web-service'); my $auth = $client->login( 'username', 'password' ); exit 1 if $auth->fault != 0; my $header = SOAP::Header->name( 'auth' => $auth->result ); my $response = $client->private_method( $header );

So far, everything is working fine - The requirements for this project called for access from other languages and to this end a web services definition language (WSDL) file was generated. Using this WSDL file, a client has successfully been generated using PHP that can access the web service without issue. However an issue was presented when the perl test client was updated to employ the WSDL - The updated client is thus:

use SOAP::Lite; my $client = SOAP::Lite ->service('http://localhost/Service.wsdl'); my $auth = $client->login( 'username', 'password' ); exit 1 if $auth->fault != 0; my $header = SOAP::Header->name( 'auth' => $auth->result ); my $response = $client->private_method( $header );

The problem with this updated client is that the added authentication header is encoded within the SOAP body rather than the SOAP header within the SOAP envelope. For example:

<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/enc +oding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encod +ing/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmln +s:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://w +ww.w3.org/1999/XMLSchema"> <SOAP-ENV:Body> <namesp3:private_method xmlns:namesp3="Service"> <auth xsi:type="xsd:string">aeee24d36fc6107947b0d7b5af8aff41</au +th> </namesp3:private_method> </SOAP-ENV:Body> </SOAP-ENV:Envelope>

At this stage however, I am unsure whether this is an issue with my WSDL file or the limited WSDL 1.1 support offered by SOAP::Lite - Have any others come across any similar issues with WSDL support under SOAP::Lite? I would note that this problem is not present with the PHP version of the client which employs the same WSDL file.

(If there is sufficient interest, I can post the WSDL and the authentic service interfaces, however at this stage I am more interested in determining whether this is a known issue with regard to the WSDL implementation in SOAP::Lite)

 

perl -le "print unpack'N', pack'B32', '00000000000000000000001011001000'"

Comment on SOAP Headers, WSDL and SOAP::Lite
Select or Download Code
Re: SOAP Headers, WSDL and SOAP::Lite
by rob_au (Abbot) on Mar 11, 2004 at 09:56 UTC
    At this stage however, I am unsure whether this is an issue with my WSDL file or the limited WSDL 1.1 support offered by SOAP::Lite

    Following some further reading of the WSDL specification (1.1, http://www.w3.org/TR/wsdl), it appears that additional SOAP headers should be able to be specified without these headers necessarily needing to be specified within the WSDL file - "It is not necessary to exhaustively list all headers that appear in the SOAP Envelope using soap:header. For example, extensions (see section 2.1.3) to WSDL may imply specific headers should be added to the actual payload and it is not required to list those headers here.".

    To this end, I tested removing the <soap:header> definition from the private_method binding in the WSDL (in case the problem was being caused by an error in my WSDL definition) to no avail.

    Anyone else got any other ideas short of diving into the source of SOAP::Lite?

     

    perl -le "print unpack'N', pack'B32', '00000000000000000000001011001001'"

      This is actually not a bug. Rather it is an undeveloped feature. Apparently, Paul Kulchenko, author of SOAP::Lite, incorporated the foundation of many features that he simply did not have time to finish. In this case, two packages/subroutines need to be updated. SOAP::Schema::WSDL::parse SOAP::Schema::stub
        Here are the updated sections of code.

        SOAP::Schema::WSDL::parse

        foreach ($_->operation) { my $opername = $_->name; my $soapaction = $_->operation->soapAction; my $namespace = $_->input->body->namespace; my (@parts, @headers); foreach ($s->portType) { next unless $_->name eq $porttype; foreach ($_->operation) { next unless $_->name eq $opername; my $inputmessage = SOAP::Utils::disqualify($_->input->me +ssage); my $inputheader = $_->input->header ? SOAP::Utils::disqualify($_->input->header) : ''; foreach ($s->message) { if ($_->name eq $inputmessage) { @parts = $_->part; } elsif ($_->name eq $inputheader) { @headers = $_->part; } } } } $services{$opername} = {}; for ($services{$opername}) { $_->{endpoint} = $endpoint; $_->{soapaction} = $soapaction; $_->{uri} = $namespace; $_->{parameters} = [@parts]; $_->{header} = [@headers] if @headers; . } . }
        SOAP::Schema::stub
        join("\n", "package $package;\n", "# -- generated by SOAP::Lite (v$SOAP::Lite::VERSION) for Perl -- soaplite.com -- Copyright (C) 2000-2001 Paul Kulchenko --",<br> ($schema ? "# -- generated from $schema [@{[scalar localtime]}]\n" + : "\n"), 'my %methods = (', (map { my $service = $_; join("\n", " $_ => {", map(" $_ => '$services->{$service}{$_}',", qw/endpo +int soapaction uri/), " header => [", map(" SOAP::Header->new(name => '" . $_->name . "', type => '" . $_->type . "', attr => {" . do{ my %attr = %{$_->attr} +; join , ', map {"'$_' => '$attr{$_}'"} grep {/^xmlns:(?!-)/} keys %attr} . "}),", @{$services->{$service}{header}}), " ],", " parameters => [", map(" SOAP::Data->new(name => '" . $_->name . "', type => '" . $_->type . "', attr => {" . do{ my %attr = %{$_->attr} +; join ', ', map {"'$_' => '$attr{$_}'"} grep {/^xmlns:(?!-)/} keys %attr} . "}),", @{$services->{$service}{parameters}}), " ],\n },", ), } keys %$services), ");", <<'EOP'); . . . my @templates = (@{$method{header}}, @{$method{parameters}}); my $som = $self -> endpoint($method{endpoint}) -> uri($method{uri}) -> on_action(sub{qq!"$method{soapaction}"!}) -> call($method => map {@templates ? shift(@templates)->value($_ +) : $_} @_); UNIVERSAL::isa($som => 'SOAP::SOM') ? wantarray ? $som->paramsall +: $som->result : $som;

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://335732]
Approved by kvale
Front-paged by ehdonhon
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (14)
As of 2014-08-27 11:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (237 votes), past polls