Subject: | SOAP::Serializer::envelope: Client Denied access to method |
Date: | Sat, 24 Nov 2007 01:41:42 +0100 |
To: | bug-SOAP-Lite [...] rt.cpan.org |
From: | Pierre GIRARD <pierre.girard [...] in2p3.fr> |
Hello,
I'm using SOAP::Lite 0.69.
Show quoted text
> [pierre@localhost SOAP]$ perl -MSOAP::Lite -e 'print
> $SOAP::Lite::VERSION."\n";'
> 0.69
I noticed a problem when SOAP::Transport::HTTP::Daemon is dynamically
binding for the first time a perl module that has already been imported
by the perl program. In such a case, if you request the call at any
method of this imported module, you will get a "Client Denied access to
method" error.
- Problem
That comes from a bad test at line 2500 of SOAP/Lite.pm within
find_target method:
Show quoted text> 2493 # TODO - sort this mess out:
> 2494 # SOAP::Lite 0.60:
> 2495 # unless (defined %{"${class}::"}) {
> 2496 # Patch to SOAP::Lite 0.60:
> 2497 # The following patch does not work for packages defined
> within a BEGIN block
> 2498 # unless (exists($INC{join '/', split /::/, $class.'.pm'})) {
> 2499 # Combination of 0.60 and patch:
> 2500 unless (defined(%{"*${class}::"}) || exists($INC{join '/',
> split /::/, $class.'.pm'})) {
> 2501 # allow all for static and only specified path for dynamic
> bindings
> 2502 local @INC = (($static ? @INC : ()), grep {!ref &&
> m![/\\.]!} $self->dispatch_to);
> 2503 eval 'local $^W; ' . "require $class";
> 2504 die "Failed to access class ($class): $@" if $@;
> 2505 $self->dispatched($class) unless $static;
> 2506 }
Indeed, if $class was already used before executing this code, the above
block is never performed and so, $class is never "dispatched".
- Fix:
I think that you should dispatch the class after the block:
Show quoted text> 2500 unless (defined(%{"*${class}::"}) || exists($INC{join '/',
> split /::/, $class.'.pm'})) {
> 2501 # allow all for static and only specified path for dynamic
> bindings
> 2502 local @INC = (($static ? @INC : ()), grep {!ref &&
> m![/\\.]!} $self->dispatch_to);
> 2503 eval 'local $^W; ' . "require $class";
> 2504 die "Failed to access class ($class): $@" if $@;
> 2505 }
> 2506 $self->dispatched($class) unless($static || grep
> {/^$class$/} $self->dispatched) ;
And then remove the useless test
Show quoted text> 2508 die "Denied access to method ($method_name) in class ($class)"
> 2509 unless $static || grep {/^$class$/} $self->dispatched;
- Reproducing the problem
************ ./Modules/Hello.pm
package Hello;
sub new {
my $class = shift;
my $self = {};
bless ($self, $class);
return $self;
}
sub hello {
my $self = shift;
my $name = shift;
return "Hello $name";
}
1;
************ server code
use SOAP::Transport::HTTP;
my $daemon = SOAP::Transport::HTTP::Daemon
-> new (LocalAddr => 'localhost', LocalPort => 80)
-> dispatch_to('./Mdules');
print "Contact to SOAP server at ", $daemon->url, "\n";
$daemon->handle;
************ Emulate Hello->new()->hello("pierre") by using curl to send
a SOAP message
curl --stderr /dev/null \
-H "Content-Type: text/xml; charset=utf-8" \
-H "SOAPAction: \"urn:Hello#hello\"" \
-d "<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"
xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"
xmlns:namesp1=\"http://namespaces.soaplite.com/perl\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\">
<SOAP-ENV:Header>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<hello xmlns=\"urn:Hello\">
<!-- FAILURE COMES FROM THERE:
The first argument is a Hello instance.
So, in order to evaluate the hello method arguments, SOAP server
will prematurely
require Hello.pm module without declaring it as a dispatched
module of the server.
the hello call will then fail because Hello module is already
used but it is not part of the dispatched module.
-->
<Hello xsi:type=\"namesp1:Hello\"/>
<c-gensym3 xsi:type=\"xsd:string\">Herong</c-gensym3>
</hello>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>" http://localhost:80
************ Result
<?xml version="1.0" encoding="UTF-8"?><soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>Denied
access to method (hello) in class (Hello) at
/usr/local/lib/perl5/site_perl/5.8.8/SOAP/Lite.pm line 2509.
</faultstring><faultactor>http://localhost.localdomain:1981/</faultactor></soap:Fault></soap:Body></soap:Envelope>
Hope that helps,
Pierre