NuSphere Forums Forum Index
NuSphere Forums
Reply to topic
Required NuSoap feature/case missing!?


Joined: 18 Jun 2008
Posts: 7
Location: India
Reply with quote
Hello,

We have used a local WSDL file with PHP SOAP to request a web-service and got
response successfully. As our head office team uses NuSOAP, we had to migrate
the code to NuSOAP and found that it's not working like it worked with PHP-SOAP.

As I have tried to go over the nusoap.php, I observed the following:

The original wsdl file has something like:

Code:
<wsdl:message name="getXXXRequest">
    <wsdl:part element="tns1:getXXX" name="part"/>
</wsdl:message>


As the `name` for wsdl:part is given as "part", nusoap is
creating the message as:
Code:
<part>[ the message body ]</part>

However the server is failing with "internal server error" when that message is posted.

When the message is sent like:
Code:
<tns1:getXXX>[ the message body ]</tns1:getXXX>

then the server accepts it and sends the response.

This worked with PHP-SOAP as PHP-SOAP has created second type of message.
Now I do not know where lies the problem:
1) Either Sever is not accepting the message as it should be with <part>xxxxx</part>
2) Or NuSoap is missing a feature to consider the second case
3) Or PHP-SOAP is either considering both cases or sending the wrong case!?

Kind Regards,
Sanjeev


Last edited by sanjeev_any on Thu Jun 19, 2008 6:14 am; edited 1 time in total
View user's profileFind all posts by sanjeev_anySend private message
Tweaking nusoap.php


Joined: 18 Jun 2008
Posts: 7
Location: India
Reply with quote
For now, to carry on, I have made the following change to nusoap.php (version 0.7.2) in serializeType() line number: 5452
replaced:
Code:
$xml = "<$name$elementNS>$value</$name>";

with:
Code:
$xml = "<".$this->getPrefixFromNamespace($ns).":$uqType>$value</".$this->getPrefixFromNamespace($ns).":$uqType>";


I fear it might break some other calls that use nusoap.php!
Let me know what needs to be done!?

Kind Regards
Sanjeev
View user's profileFind all posts by sanjeev_anySend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8334
Reply with quote
did you check debug log created in the nusoap server object properties? it's what you run on the server.

_________________
The PHP IDE team
View user's profileFind all posts by dmitriSend private messageVisit poster's website
Not NuSoap Server


Joined: 18 Jun 2008
Posts: 7
Location: India
Reply with quote
Hello Dimitri,

Thank you very much for the update.
Unfortunately, the server is not on our side. It is a third party server where
we singed an NDA for making use of their webservices.

It uses Apache Axis server by the way.

Kind Regards,
Sanjeev
View user's profileFind all posts by sanjeev_anySend private message
Is it possible!?


Joined: 18 Jun 2008
Posts: 7
Location: India
Reply with quote
Hello Dimitri,

Kindly, can you please take time to comment on the issue.
We are stuck here with the nusoap. I wasn't sure whether
we can continue with the above said patch, or may be
we can try some other way to achieve the same.

Just for testing, I have modified the wsdl file to contain
"getXXX" in the name of wsdl:part instead of "part" while
passing its namespace as a parameter in Call method,
it worked fine. But I guess its not an elegant solution to
modify the wsdl.

I was stuck here as I need to update my superiors on why
we require a change in either nusoap.php or the wsdl file.
They say, they are using nusoap for quite some time without
any problems.

Kindly take time to advise.

Kind Regards,
Sanjeev
View user's profileFind all posts by sanjeev_anySend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8334
Reply with quote
a more or less complete example would help me understand the problem better.
and on the other side, did you specify a namespace in the soapclient object constructor and in the call()?

_________________
The PHP IDE team
View user's profileFind all posts by dmitriSend private messageVisit poster's website
Examples


Joined: 18 Jun 2008
Posts: 7
Location: India
Reply with quote
Hello Dimitri,

Thank you very much for the response. Its very kind of you.
Please find below the example (modified wherever needed
to hide the company data):

The Local WSDL File:

Code:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://www.testbooks.com/schemas/2005/06/messages" xmlns:intf="http://www.testbooks.com/schemas/2005/06/messages" xmlns:tns1="http://axis.frontend.bsi.testbooks.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.testbooks.com/schemas/2005/06/messages">
        <wsdl:types>
                <schema targetNamespace="http://axis.frontend.bsi.testbooks.com" xmlns="http://www.w3.org/2001/XMLSchema">
                        <element name="getBSIBooksList" type="xsd:anyType"/>
                </schema>
                <schema targetNamespace="http://www.testbooks.com/schemas/2005/06/messages" xmlns="http://www.w3.org/2001/XMLSchema">
                        <element name="getBSIBooksListReturn" type="xsd:anyType"/>
                </schema>
        </wsdl:types>
        <wsdl:message name="getBSIBooksListResponse">
                <wsdl:part name="getBSIBooksListReturn" element="impl:getBSIBooksListReturn"/>
        </wsdl:message>
        <wsdl:message name="getBSIBooksListRequest">
                <wsdl:part name="part" element="tns1:getBSIBooksList"/>
        </wsdl:message>
        <wsdl:portType name="BSI">
                <wsdl:operation name="getBSIBooksList">
                        <wsdl:input name="getBSIBooksListRequest" message="impl:getBSIBooksListRequest"/>
                        <wsdl:output name="getBSIBooksListResponse" message="impl:getBSIBooksListResponse"/>
                </wsdl:operation>
        </wsdl:portType>
        <wsdl:binding name="BSISoapBinding" type="impl:BSI">
                <wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
                <wsdl:operation name="getBSIBooksList">
                        <wsdlsoap:operation/>
                        <wsdl:input>
                                <wsdlsoap:body use="literal"/>
                        </wsdl:input>
                        <wsdl:output>
                                <wsdlsoap:body use="literal"/>
                        </wsdl:output>
                </wsdl:operation>
        </wsdl:binding>
        <wsdl:service name="BSIService">
                <wsdl:port name="BSI" binding="impl:BSISoapBinding">
                    <wsdlsoap:address location="http://000.000.000.00/cratos/ws/BSI"/>
                </wsdl:port>
        </wsdl:service>
</wsdl:definitions>


The Php Code:


Code:

require_once('nusoap.php');^M
$wsdlfile = dirname(__FILE__)."/bsi.wsdl";
ini_set("soap.wsdl_cache_enabled", "0");
$BoosRQ= '<BSI_BooksListRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" echoToken="0123"><Language>EN</Language><Credentials><User>'.$user.'</User><Password>'.$passwd.'</Password></Credentials></BSI_BooksListRQ>';
if(($client = new SoapClient($wsdlfile,true,"BSI"))) {
    $rs1=$client->Call("getBSIBooksList",array($BooksRQ),"http://axis.frontend.bsi.testbooks.com");
    //$rs1=$client->Call("getBSIBooksList",array($methodName=>$requestXML),"http://axis.frontend.bsi.testbooks.com");

    if(@array_key_exists('faultcode', $rs1))  {
        echo $rs1;
    } else {
        echo "Success";
    }
}


The following is the request nusoap creates:
Code:

<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="http://axis.frontend.bsi.testbooks.com"><SOAP-ENV:Body><part><BSI_BooksListRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" echoToken="0123"><Language>EN</Language><Credentials><User>test</User><Password>test</Password></Credentials></BSI_BooksListRQ></part></SOAP-ENV:Body></SOAP-ENV:Envelope>


For the above request server responds with a 501 error.
The following is the request that server accepts:

Code:

<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="http://axis.frontend.bsi.testbooks.com"><SOAP-ENV:Body><tns1:getBSIBooksList><BSI_BooksListRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" echoToken="0123"><Language>EN</Language><Credentials><User>test</User><Password>test</Password></Credentials></BSI_BooksListRQ></tns1:getBSIBooksList></SOAP-ENV:Body></SOAP-ENV:Envelope>


Hope the above this help.

Kind Regards,
Sanjeev
View user's profileFind all posts by sanjeev_anySend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8334
Reply with quote
Could you please try to change "document" in the following wsdl's line to "rpc"?

<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>

_________________
The PHP IDE team
View user's profileFind all posts by dmitriSend private messageVisit poster's website
Working.


Joined: 18 Jun 2008
Posts: 7
Location: India
Reply with quote
Hello Dimitri,

Yes that fixed the problem. Thank you very much.

As modifying the wsdl file is not the right option and it'd be better to give the user
an extra flexibility, I have patched the nusoap.php which doesn't affect any existing
usages of nusoap.php.

I have added two variables to nusoap_base
$style='rpc' and $forceStyle=false
and updated the client->call method to
have an extra argument $forceStyle

One can use either of them to force the use of specified style overriding the wsdl
default style. One have to pass the namespace as the third parameter.
Code:

$client->style = 'rpc' (or document)
$client->forceStyle = true.
$client->call($method, $array, "namespace");


or

Code:
$client->call($method, $array, "namespace", '', false, null, 'rpc', 'literal', true);


As I didn't find a way to attach any files to this thread, please find below the
patch:
Code:

--- nusoap-orig/nusoap.php      2008-06-24 15:04:32.000000000 +0530
+++ nusoap.php  2008-06-24 15:32:53.000000000 +0530
@@ -197,6 +197,24 @@
        var $xmlEntities = array('quot' => '"','amp' => '&',
                'lt' => '<','gt' => '>','apos' => "'");

+
+        /**
+        * Style to use for SOAP document
+        *
+        * @var      string (can be one of rpc or document)
+        * @access   public
+        */
+        var $style = "rpc";
+       
+        /**
+        * Force the specified style or use the WSDL specified style
+        *
+        * @var      boolean (true:  forces the above given style.
+        *                    false: takes the one specified in WSDL)
+        * @access   public
+        */
+        var $forceStyle = false;
+       
        /**
        * constructor
        *
@@ -6539,7 +6557,7 @@
        * @return       mixed   response from SOAP call
        * @access   public
        */
-       function call($operation,$params=array(),$namespace='http://tempuri_org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
+       function call($operation,$params=array(),$namespace='http://tempuri_org',$soapAction='',$headers=false,$rpcParams=null,$style='',$use='encoded', $forceStyle=false){
                $this->operation = $operation;
                $this->fault = false;
                $this->setError('');
@@ -6571,7 +6589,14 @@
                                $this->endpoint = $this->forceEndpoint;
                        }
                        $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] :     $namespace;
-                       $style = $opData['style'];
+
+                        if($forceStyle || $this->forceStyle) {
+                            $style = (empty($style))? $this->style : $style;
+                        } else {
+                            $style = $opData['style'];
+                        }
+                        if(empty($style)) $style = 'rpc';
+
                        $use = $opData['input']['use'];
                        // add ns to ns array
                        if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){


May be we have to do something similar to give flexibility for user to override the wsdl defaults.

Hope this will be helpful for someone who is following this thread.
Thank you very much once again for taking time to update me on this thread.

Kind Regards,
Sanjeev
View user's profileFind all posts by sanjeev_anySend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8334
Reply with quote
Thanks for your efforts. The key question is whether the patched library still conforms the related SOAP standards.
Feel free to publish your patch there https://lists.sourceforge.net/lists/listinfo/nusoap-general
http://sourceforge.net/projects/nusoap/

_________________
The PHP IDE team
View user's profileFind all posts by dmitriSend private messageVisit poster's website
SOAP Standards


Joined: 18 Jun 2008
Posts: 7
Location: India
Reply with quote
Hello Dmitri,

Thank you for the update.
It might not conform to the standards, but might give
an extra flexibility to those users who might have to
deal with faulty implementations of the server Sad. I will
submit the patch on the mailing list.

Kind Regards,
Sanjeev
View user's profileFind all posts by sanjeev_anySend private message
Required NuSoap feature/case missing!?
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
All times are GMT - 5 Hours  
Page 1 of 1  

  
  
 Reply to topic