SOAP::WSDL::Manual::Cookbook (3)
Leading comments
Automatically generated by Pod::Man 2.28 (Pod::Simple 3.29) Standard preamble: ========================================================================
NAME
SOAP::WSDL::Manual::Cookbook - SOAP::WSDL recipesAccessing HTTPS webservices
You need Crypt::SSLeay installed to access Accessing protected web services
Passing a username and password, or a client certificate and key, to the transport layer is highly dependent on the transport backend. The descriptions below are forAccessing
When using SOAP::WSDL::Transport::HTTP (SOAP::Lite not installed), add a method called ``get_basic_credentials'' to SOAP::WSDL::Transport::HTTP:
*SOAP::WSDL::Transport::HTTP::get_basic_credentials = sub { return ($user, $password); };
When using SOAP::Transport::HTTP (SOAP::Lite is installed), do the same to this backend:
*SOAP::Transport::HTTP::Client::get_basic_credentials = sub { return ($user, $password); };
Accessing
If you want to connect to a windows server using some Windows Domain Login, please consider using Kerberos instead of the (older)
Kerberos and
You need the
Your user credentials usually need to include the windows domain or the windows hostname like this:
testdomain\testuser
or
\\testhost\testuser
Besides passing user credentials as when accessing a web service protected by basic or digest authentication, you also need to enforce connection keep_alive on the transport backens.
To do so, pass a proxy argument to the new() method of the generated class. This unfortunately means that you have to set the endpoint
my $interface = MyInterfaces::SERVICE_NAME::PORT_NAME->new({ proxy => [ $url, keep_alive => 1 ] });
You may, of course, decide to just hack the generated class. Be advised that subclassing might be a more appropriate solution - re-generating overwrites changes in interface classes.
Accessing
There are different variants of
Request POST Response 401 Unauthorized WWW-Authenticate: NTLM Request Authorization: NTLM <base64-encoded type-1-message> Response 401 Unauthorized WWW-Authenticate: NTLM <base64-encoded type-2-message> Request Authorization: NTLM <base64-encoded type-3-message> Response 200 Ok
If you try to access a NTLMv2 protected web service and switch on LWP::Debug by saying
use LWP::Debug qw(+);
you should see at least two lines containing something like
Authorization NTLM TlRMTVNTUAABAAAAB7IAAAAAAAAAAAAAAwADACAAAABmb28= ... Authorization NTLM TlRMTVNTUAABAAAAB7IAAAAAAAAAAAAAAw ... much longer ... ADACAAAABmb28=
If you're talking to a Server using NTLMv2 exclusively, you will only the first line in the debug output, and then an error.
To explicitly enable NTLMv2, do the following in your client:
use Authen::NTLM; ntlmv2(1);
This globally enables the use of NTLMv2. Note that this is a global setting: All clients running in the same perl interpreter will be affected. This can cause unexpected issues when running under mod_perl.
Accessing webservices protected by
Use the LWP::Authen::Negotiate plugin from
(Newer) Windows Web Services usually allow one to use both the Negotiate (Kerberos) and
Accessing
You need Crypt::SSLeay installed to access
See Crypt::SSLeay on how to configure client certificate authentication.
XML OUTPUT
Outputting namespaces as prefixes
Q: I need to interface with a
<SOAP-ENV:Envelope xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="schemas.xmlsoap.org/soap/envelope"> <SOAP-ENV:Body> <getElement xmlns="services.company.com"> <elementId>12345</elementId> </getElement> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Instead, it requires this:
<SOAP-ENV:Envelope xmlns:xsi="www.w3.org/2001/XMLSchema-instance" xmlns:ns2="services.company.com" xmlns:SOAP-ENV="schemas.xmlsoap.org/soap/envelope"> <SOAP-ENV:Body> <ns2:getElement> <ns2:elementId>12345</ns2:elementId> </ns2:getElement> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
How do I do this using
A: The following steps are necessary to achieve this result:
First, you would need to write a new serializer, which is quite easy, as it just creates the envelope and calls ->serialize_qualified() on $header and $body to fill them in. The new serializer has to declare all namespace prefixes used, the rest is just the same as the original
Second, you'd need to overwrite the start_tag method in SOAP::WSDL::XSD::Typelib::Element to use the appropriate prefixes for the body elements.
In contrast to the original method, it would probably look up the appropriate prefix from some data set in the serializer class, so this could be the appropriate place to load SOAP::WSDL::XSD::Typelib::Element and override the method.
Something like this should do (without the handling of specialties like empty or nil elements):
%PREFIX_OF = { 'services.company.com => 'ns2' }; *SOAP::WSDL::XSD::Typelib::Element::start_tag = sub { # use prefix instead of xmlns attribute and copy the rest from # SOAP::WSDL::XSD::Typelib::Element::start_tag my $prefix = $PREFIX_OF{ $_[0]->get_xmlns() }; my $name = $_[1]->{ name } || $self->__get_name(); return "<$prefix:$name>"; }
Skipping unknown XML elements - lax XML processing
SOAP::WSDL::Deserializer::XSD allows switching off the stric
Disabling strict XML processing in a Client
Pass the following as "deserializer_args":
{ strict => 0 }
Example: The generated
use MyInterface::Test; my $soap = MyInterface::Test->new({ deserializer_args => { strict => 0 } }); my $result = $soap->SomeMethod();
Disabling strict XML processing in a CGI based server
You have to set the deserializer in the transport class explicitly to
a SOAP::WSDL::Deserializer object with the
"strict" option set to 0.
Example: The generated
use strict; use MyServer::Test; use SOAP::WSDL::Deserializer::XSD; my $soap = MyServer::Test->new({ transport_class => 'SOAP::WSDL::Server::CGI', dispatch_to => 'main', }); $soap->get_transport()->set_deserializer( SOAP::WSDL::Deserializer::XSD->new({ strict => 0 }) ); $soap->handle();
Disabling strict XML processing in a mod_perl based server
Sorry, this is not implemented yet - you'll have to write your own handler
class based on SOAP::WSDL::Server::Mod_Perl2.
Changing the encoding of a SOAP request
However, you can change the encoding the transport layer announces by calling "set_encoding($encoding)" on a client object.
You probably have to write your own serializer class too, because the default serializer has the utf-8 encoding hardcoded in the envelope.
Just look into SOAP::WSDL::Serializer on how to do that.
Don't forget to register your serializer at the serializer factory SOAP::WSDL::Factory::Serializer.
LICENSE AND COPYRIGHT
Copyright 2008, 2009 Martin Kutter.This file is part of SOAP-WSDL. You may distribute/modify it under the same terms as perl itself.
AUTHOR
Martin Kutter <martin.kutter fen-net.de>REPOSITORY INFORMATION
$Rev: 583 $ $LastChangedBy: kutterma $ $Id: $ $HeadURL: $