golemwashere has asked for the wisdom of the Perl Monks concerning the following question:

Hello gurus, I'have a problem creating a client with SOAP::Lite. I need a custom header in my request:
<SOAP-ENV:Header> <Security xmlns="http://schemas.xmlsoap.org/ws/2002/xx/secext" +> <UsernameToken> <Username>myuser</Username> <Password>mypassword</Password> </UsernameToken> </Security> </SOAP-ENV:Header>
--------------------------------------------------- I'm using:
use SOAP::Lite +trace; my $client = SOAP::Lite ->readable(1) ->uri($uri) ->proxy($proxy); my $Username = SOAP::Header->name('Username' => $username); my $Password = SOAP::Header->name('Password' => $password); my $UsernameToken = SOAP::Header->name('UsernameToken') ->value(\SOAP::Header->value($Username, $Password)); my $security = SOAP::Header->name('Security') ->attr({'xmlns' => 'http://schemas.xmlsoap.org/ws/2002/xx/ +secext'}) ->value(\$UsernameToken); $elem1 = SOAP::Data->name('ELEM1' => "value1"); $elem2 = SOAP::Data->name('ELEM2' => "value2"); $response = $client->mymethod($elem1,$elem2);
but I don' get the header I need.... I tried also feeding raw xml in $envelope with:
my $client = SOAP::Lite ->readable(1) ->uri($uri) ->proxy($proxy) ->envelope($envelope);
but I don't manage to grasp the syntax (I get 2 nested <soap:Envelope> tags) Can anyone give please me some insight?

Replies are listed 'Best First'.
Re: SOAP::Lite, custom headers or raw xml ?
by gellyfish (Monsignor) on Aug 18, 2006 at 14:13 UTC

    You were almost spot on with the first attempt, you just have to pass the SOAP::Header to the method call and SOAP::Lite will Do The Right Thing, I'd also suggest setting autotype off on the soap client as that suppresses the typing on the elements which might confuse some toolkits:

    use SOAP::Lite +trace; $uri = 'urn:Foo'; $proxy = 'http://localhost/'; $username = 'username'; $password = 'password'; my $client = SOAP::Lite ->readable(1) ->uri($uri) ->proxy($proxy); $client->autotype(0); my $Username = SOAP::Header->name('Username' => $username); my $Password = SOAP::Header->name('Password' => $password); my $UsernameToken = SOAP::Header->name('UsernameToken') ->value(\SOAP::Header->value($Username, $Password)); my $security = SOAP::Header->name('Security') ->attr({'xmlns' => 'http://schemas.xmlsoap.org/ws/2002/xx/ +secext'}) ->value(\$UsernameToken); $elem1 = SOAP::Data->name('ELEM1' => "value1"); $elem2 = SOAP::Data->name('ELEM2' => "value2"); $response = $client->mymethod($elem1,$elem2, $security);
    This produces (for me anyway, let's all wait for an Anonymous Monk to turn up saying I'm lying in a bit:)
    <?xml version="1.0" encoding="UTF-8"?> <soap: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:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Header> <Security xmlns="http://schemas.xmlsoap.org/ws/2002/xx/secext"> <UsernameToken> <Username>username</Username> <Password>password</Password> </UsernameToken> </Security> </soap:Header> <soap:Body> <mymethod xmlns="urn:Foo"> <ELEM1>value1</ELEM1> <ELEM2>value2</ELEM2> </mymethod> </soap:Body> </soap:Envelope>

    /J\

      Thanks for the tip, It worked!!! I now get a very similar request in my trace as the one expected... the only problem is I get <soap:Envelope> <soap:Body> and <soap:Header> tags instead of <SOAP-ENV:Envelope> <SOAP-ENV:Body> , etc... all the rest in the requests seem the same but the web service cryies out:
      <?xml version='1.0' ?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schema +s.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultco +de>SOAP-ENV:Server</faultcode><faultstring>null</faultstring><detail> +<IBResponse type="error"><DefaultTitle>Integration Broker Response</D +efaultTitle><StatusCode>20</StatusCode><MessageSet>158</MessageSet><M +essageID>10403</MessageID><DefaultMessage>A request must supply eithe +r a RequestorNode or a DistinquishedName</DefaultMessage><MessagePara +meters><Parameter>RequestorNode or DistinquishedName</Parameter></Mes +sageParameters></IBResponse></detail></SOAP-ENV:Fault></SOAP-ENV:Body +></SOAP-ENV:Envelope>
      I tried messing up with $client->namespace but without any success. Any extra help would be greatly appreciated, sorry for beeing that newbie !!! P.S . I owe you a pint

        The namespace prefix really shouldn't matter to a well behaved toolkit.

        <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap. +org/soap/envelope/"> ...
        is effectively the same as
        <soap:Envelope xmlns:soap="http://schemas.xmlsoap. +org/soap/envelope/"> ...
        or even
        <BlahBlahWoofWoof:Envelope xmlns:BlahBlahWoofWoof="http://schemas.xmls +oap. +org/soap/envelope/"> ...
        . The prefix used can be thought of as being "preprocessed" to represent the URI associated with it by the xmlns:prefix="URL" attribute. Of course the server might be badly behaved.

        However from the fault text you are getting I think the problem actually is that your are missing something from the request. I would suggest either consulting the WSDL for the service or the documentation or asking the person who is responsible for it to see where you have to place the RequestorNode or DistinguishedName and what the content is supposed to be.

        /J\