XML::Compile::WSDL11 - accessing the transport layer

Toby Corkindale tjc at wintrmute.net
Mon Apr 14 08:30:58 BST 2008

On Fri, Apr 11, 2008 at 10:37:17AM +0200, Mark Overmeer wrote:
> * Toby Corkindale (tjc at wintrmute.net) [080411 05:02]:
> > On Fri, Apr 11, 2008 at 12:08:39PM +1000, Toby Corkindale wrote:
> > > I'm using XML::Compile::WSDL11 to generate some SOAP services, but I
> > > want to get access to the LWP::UserAgent object..
> > > 
> > > Can anyone help me with the missing step here?
> > 
> > I never did figure out the right way to get to the transport layer, and
> > eventually decided that X-C-T-SOAPHTTP just didn't export the package-wide
> > %transporters hash via any means.
> > 
> > I created a work-around, see below if you ever need to do this yourself:
> > 
> > > my $wsdl = slurp('service.wsdl');
> > > my $service = XML::Compile::WSDL11->new($wsdl);
> You can also do:
>     my $service = XML::Compile::WSDL11->new('service.wsdl');

Ah, I'd forgotten. In my real-life case I'm actually pulling the WSDL out via a
configuration stage so as to allow for testing vs production versions, and
replaced it all with slurp() to simplify the example :)

> > my $transport = XML::Compile::Transport::SOAPHTTP->new(
> >     address => $server_uri
> > );
> The problem is that a WSDL can declare multiple protocols, which may
> not be support by one transport implementation, like LWP.  For instance,
> I already got sucj report about XMPP (Jabber)... not supported by LWP,
> but used in WSDL.
> So, there cannot be a $service->userAgent method, even though there
> may be a global variable which contains it...

Hmm. I understand your point.

It might be nice if there was an intermediate stage between the WSDL11() call
and the $wsdl->compileClient() call, where one could adjust options. I say this
because it is a pity that compileClient()'s result is a function pointer and
thus rather immutable.

ie. This would be useful to me.. and possibly no-one else :)

my $service = XML::Compile::WSDL11->new($wsdl);
my $callObj = $service->prepareClient('stock_price');
my $transport = $callObj->transport;
if ($transport->can('userAgent')) {
    my $ua = $transport->userAgent;
    $ua->proxy('http', 'http://example.com:3128');
    # etc
my $call = $callobj->compile;

$call->(ticker => 'PERL');

> The only way to get your hands on the LWP::UserAgent used for one or
> more WSDL operations, is by avoiding the auto-generated internal
> objects, but specify them explicitly.  So, you approach is sane.
> You could also do:
>    my $ua    = LWP::UserAgent->new;   # get it somewhere, SSL setup>
>    my $transporter = XML::Compile::Transport::SOAPHTTP->new(user_agent => $ua);
>    my $http  = $transporter->compileClient(soap => 'SOAP11', ...);
>    my $call  = $wsdl->compileClient('myport', transport => $http);
>    $call->($data);
> You can leave-out steps 1, 2, and/or 3 in various combinations, to still
> get something working.  Each step has its own responsibilities, so may
> require configuration.  This traject is not documented as a whole yet.

AH, thanks for the alternates; I'll try those out too, although it seems
confusing that you're calling compileClient twice in the chain.

I found it tricky to determine that I was allowed to pass the transport object
through, or that it was even a good idea.
Might I suggest that XML::Compile::WSDL11's document is modified to mention
how to pass through transport options, as an example, like the transport_hook

Thanks for the library by the way - in general it's all worked well and been
easy to use.


More information about the london.pm mailing list