[Xml-compile] possible problem with soapAction header?

Robin V. robinsp at gmail.com
Sun Jan 23 19:30:18 GMT 2011


Thanks to Mak's help, I managed to solve the problem. My code was kind
of broken (though it worked before :-/ ) and trying to correct it, I
found some problems with wsdl->compile parameters (at least it wasn't
working as I expected).

Here are some explanations on my problem and how it was solved, it
could be helpful to somebody...

I was trying to use a proxy with an x:c:s client. My older code was

		my $ua = LWP::UserAgent->new(keep_alive => 1);
		$ua->timeout(10);
		if( $proxyUrl ) {
			#$ua->env_proxy;
			$ua->proxy('http', $proxyUrl);
		}
		my $http   = XML::Compile::Transport::SOAPHTTP->new(user_agent => $ua,
			address=>'http://'.$self->hostPort.'/xxx');
		$sender = $http->compileClient();
		$self->wsdl ( XML::Compile::WSDL11->new($self->wsdlFile) );
		$self->getLinesCall ($self->wsdl->compileClient(
					transport => $sender,
					operation => 'getLines',
					port => WSPORT,
					server => $self->hostPort,
					service => WSSERVICE,
				)

The problem was partially that calling SOAPHTTP->compileClient result
in a SOAPHTTP without any knowledge of the service to be called (and
it didn't know about its soapAction header.

To solve the problem, I passed a user_agent parameter in the call to
wsdl->compile:

		my $ua = LWP::UserAgent->new(keep_alive => 1);
		$ua->timeout(10);
		if( $proxyUrl ) {
			#$ua->env_proxy;
			$ua->proxy('http', $proxyUrl);
		}

		$self->wsdl ( XML::Compile::WSDL11->new($self->wsdlFile) );
		
		$self->getLinesCall ($self->wsdl->compileClient(
					user_agent => $ua,
					address=>'http://'.$self->hostPort.'/xxx',
					operation => 'getLines',
					port => WSPORT,
					server => $self->wsivHostPort,
					service => WSSERVICE,
				)
			);

I still had to modify function compileTransporter in
XML::Compile::SOAP::Operation to permit args to be passed to the
transporter constructor:

-    my $transport = $self->{transp_cache}{$proto}{$id}
-                  = $transp->new(address => \@endpoints);

+    my $transport = $self->{transp_cache}{$proto}{$id}
+                 = $transp->new(address => \@endpoints, %args);


Everything works nice now.

Thanks for your help Mark.

Robin

On Sun, Jan 23, 2011 at 1:18 AM, Robin V. <robinsp at gmail.com> wrote:
> On Sat, Jan 22, 2011 at 11:02 PM, Mark Overmeer <mark at overmeer.net> wrote:
>> * Robin V. (robinsp at gmail.com) [110122 19:50]:
>>> Before this, I updated to last version of xml::compile, it may be the
>>> reason of the problem (or maybe the service I call has changed since
>>> the last time).
>>
>> Any idea what your previous version was?  Years ago, month ago?
>> Maybe something to do with
>>
>>  2.18  - promote soapAction() from ::SOAP11::Operation into
>>          ::SOAP::Operation
>
>
> It could be... Last time I used this program sucessfully was in
> july/august 2010 there's a lot of sqlite log files around this time...
> so I think it was about six months ago.
>
>>> <faultstring>The endpoint reference (EPR) for the Operation not found
>>> is http://www.ratp.fr/wsiv/services/Wsiv and the WSA Action =
>>> null</faultstring>
>>>
>>> Is this expected behavior ? I tried to force custom http header, but I
>>> didn't manage to do it cleanly.
>>
>> I do not have a schema with soapAction at hand. Maybe you can help me.
>> Tracing the $action parameter is not too hard: start at the end at
>>  XML::Compile::Transport::SOAPHTTP::_prepare_call($)
>
> I tried to follow the parameter, but I was a bit lost between
> classes...(it seems to be called at compile time? even before the wsdl
> is parsed...)  it looks like the operation "action" is correctly set
> by wsdl->compileClient.
> In SOAPHTTP.PM, I tried to dump the args parameter, but it was empty:
>
> # SUPER::compileClient() calls this method to do the real work
> sub _prepare_call($)
> {   my ($self, $args) = @_;
>
> use Data::Dumper;
> print Dumper($args);
>
> === returns: ===
> trace: loading extension XML::Compile::Transport::SOAPHTTP
> $VAR1 = {};
> ============
> $args seems to be empty. I tried to put action parameter in the
> operation but it seems useless as it's already correctly set by the
> wsdl compilation. And I don't really know how to track correctly calls
> to _prepare_call from the compiles operation->call. I also tried to
> use addHeader, but it looks like it adds headers to the soap payload.
>
>> It seems that your server also supports WSA. Is that present in
>> your schema?  Then load the "new" XML::Compile::SOAP::WSA.
>
> I'm not really aware of "WSA", all I know is that there's three soap
> ports in the WSDL:
> HTTP Port
> SOAP1.1 Port
> SOAP1.2 Port
> The server is a usual axis2 server.
>
> I use the SOAP 1.1 port which uses "action" (it looks like the wsa
> action is related to soap 1.2):
> Port declares:
>    <wsdl:operation name="getLines">
>      <wsdl:input message="ns1:getLinesRequest" wsaw:Action="urn:getLines">
>    </wsdl:input>
>      <wsdl:output message="ns1:getLinesResponse"
> wsaw:Action="urn:getLinesResponse">
>
> soap 1.1  binding declares:
>    <wsdl:operation name="getLines">
>      <soap:operation soapAction="urn:getLines" style="document"/>
> soap 1.2  binding declares:
>    <wsdl:operation name="getLines">
>      <soap12:operation soapAction="urn:getLines" style="document"/>
>
> I send you the wsdl in another private message.
>
> Any hint is welcome.
>
> Best regards,
> Robin
> PS: I don't know if it can be the source of the problem, but I
> manually set the user agent to define a proxy:
>                my $ua = LWP::UserAgent->new(keep_alive => 1);
>                $ua->timeout(10);
>                if( $proxyUrl ) {
>                        #$ua->env_proxy;
>                        $ua->proxy('http', $proxyUrl);
>                }
>
>                my $http   = XML::Compile::Transport::SOAPHTTP->new(user_agent => $ua,
>                        address=>'http://'.$self->xxxHostPort.'xxxxxx');
>                $sender = $http->compileClient();
>                $self->wsdl ( XML::Compile::WSDL11->new($self->wsdlFile) );
>                $self->getLinesCall ($self->wsdl->compileClient(
>                                        transport => $sender,
>                                        operation => 'getLines',
>                                        action => 'Pouet',  ## this is a test
>                                        port => WSPORT,
>                                        server => $self->xxxHostPort,
>                                        service => WSSERVICE,
>                                )
>



More information about the Xml-compile mailing list