CWebServiceAction problems

Hi All,

I’ve been trying to implement SOAP services with my app and I’m running out of ideas to fix a problem. I have my controller set up as follows;




<?php


class SoapController extends CController

{

    public function actions()

    {

        return array(

            'quote'=>array(

                'class'=>'CWebServiceAction',

            ),

        );

    }

	

	

	/**

     * @param string the symbol of the stock

     * @return float the stock price

     * @soap

     */

    public function getPrice($symbol)

    {

	$prices=array('IBM'=>100, 'GOOGLE'=>350);

        return isset($prices[$symbol])?$prices[$symbol]:0;

        //...return stock price for $symbol

    }


}


?>



In a different controller I have the following method




public function actionApiTest()

{

	$client = new SoapClient('http://www.mydomain.com/soap/quote');

	return;

}



and I keep running into this error;




SoapFault

Description


SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.mydomain.com/soap/quote' : Premature end of data in tag html line 2

Source File


/var/www/vhosts/mydomain.com/httpdocs/protected/controllers/AjaxController.php(147)


00135:             if($poll->is_rating == 'true') {

00136:                 $ret['image'] = Yii::app()->request->baseUrl . $poll->Style->image_file;

00137:             }

00138:             

00139:             echo CJSON::encode($ret);

00140:             return true;

00141:         }

00142:     }

00143:     

00144:     

00145:     public function actionApiTest()

00146:     {

00147:        $client = new SoapClient('http://www.mydomain.com/soap/quote');

00148:         return;

00149:     }

00150: }

00151: 

00152: ?>


Stack Trace


#0 /var/www/vhosts/mydomain.com/httpdocs/protected/controllers/AjaxController.php(147): SoapClient->SoapClient('http://www.simp...')

#1 /var/frameworks/yii-1.1.1/framework/web/actions/CInlineAction.php(32): AjaxController->actionApiTest()

#2 /var/frameworks/yii-1.1.1/framework/web/CController.php(300): CInlineAction->run()

#3 /var/frameworks/yii-1.1.1/framework/web/CController.php(278): CController->runAction(Object(CInlineAction))

#4 /var/frameworks/yii-1.1.1/framework/web/CController.php(257): CController->runActionWithFilters(Object(CInlineAction), Array)

#5 /var/frameworks/yii-1.1.1/framework/web/CWebApplication.php(320): CController->run('apitest')

#6 /var/frameworks/yii-1.1.1/framework/web/CWebApplication.php(120): CWebApplication->runController('ajax/apitest')

#7 /var/frameworks/yii-1.1.1/framework/base/CApplication.php(135): CWebApplication->processRequest()

#8 /var/www/vhosts/simpoll.biz/httpdocs/index.php(16): CApplication->run()

#9 {main}



Any suggestions would be really helpful.

Thanks.

Check the url.

SoapClient(‘http://www.mydomain.com/soap/quote’);

/Tommy

The URL is fine. If I cut and paste it into the browser I get the XML output…

This looked confusing to me




#0 /var/www/vhosts/mydomain.com/httpdocs ... SoapClient->SoapClient('http://www.simp...')



You use two different Yii apps for this, right?

(I haven’t tried Yii on the client side.)

What if you try to put the SoapClient call only in a PHP script?

/Tommy

My apologies, the url is correct, I editied the domain before posting it on this forum.

I have tried setting up a simple script in PHP that is nothing to do with the Yii install using the following code




<?php

ini_set('display_errors','on');

$client = new SoapClient('http://www.mydomain.com');

echo $client->getPrice('GOOGLE');

?>






The resulting PHP error code follows...

Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://www.mydomain.com' : Premature end of data in tag html line 2 in /var/www/vhosts/mydomain.com/httpdocs/soaptest.php:3 Stack trace: #0 /var/www/vhosts/mydomain.com/httpdocs/soaptest.php(3): SoapClient->SoapClient('http://www.mydo...') #1 {main} thrown in /var/www/vhosts/mydomain.com/httpdocs/soaptest.php on line 3



You need to turn off web logging if you enabled it in your config script. This might already been taken care of in recent Yii versions.

/Tommy

Web logging in the Yii config script is not enabled and this error still persists. The Yii version I ma using is 1.1.1.

Not sure where else to debug?

On the server side you can enable file logging and look for hints in the log file (less probable).

Consider temporarily adding trace calls to the web service classes of the framework.

My own code seems to run fine on 1.1.1 (svn) but I noticed a similar error if I used the wrong url format (path instead of get). In your case something like this: <yourserver>/soap/quote vs <yourserver>/index.php?r=soap/quote.

Personally I use to capture and analyze some network packets in cases like this, then decide what to do next.

/Tommy

For anyone experiencing this problem I have found the cure.

The issue was resolving the domain name. I develop on a virtual machine using my hosts file on my windows machine handle the resolving to the VM’s. This is where the problem was found. The Soap client was obviously not using my windows hosts file to resolve the domain but its internal hosts file (/etc/hosts on linux), so, once I added the entry there, the problem went away.

Hope someone else finds this useful.

Just when I thought I got somewhere!..

when trying to access any method CWebServiceAction fails with a CHttpException.




SoapFault Object

(

    [message:protected] => CHttpException

    [string:Exception:private] => 

    [code:protected] => 0

    [file:protected] => /var/www/vhosts/mydomain.com/httpdocs/protected/controllers/SiteController.php

    [line:protected] => 277

    [trace:Exception:private] => Array

        (

            [0] => Array

                (

                    [function] => __doRequest

                    [class] => SoapClient

                    [type] => ->

                    [args] => Array

                        (

                            [0] => <?xml version="1.0" encoding="UTF-8"?>

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:ApiControllerwsdl" 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/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getPrice><symbol xsi:type="xsd:string">GOOGLE</symbol></ns1:getPrice></SOAP-ENV:Body></SOAP-ENV:Envelope>


                            [1] => http://www.mydomain.com/api/action

                            [2] => urn:ApiControllerwsdl#getPrice

                            [3] => 1

                            [4] => 0

                        )


                )


            [1] => Array

                (

                    [function] => __call

                    [class] => SoapClient

                    [type] => ->

                    [args] => Array

                        (

                            [0] => getPrice

                            [1] => Array

                                (

                                    [0] => GOOGLE

                                )


                        )


                )


            [2] => Array

                (

                    [file] => /var/www/vhosts/mydomain.com/httpdocs/protected/controllers/SiteController.php

                    [line] => 277

                    [function] => getPrice

                    [class] => SoapClient

                    [type] => ->

                    [args] => Array

                        (

                            [0] => GOOGLE

                        )


                )


            [3] => Array

                (

                    [file] => /var/frameworks/yii-1.1.1/framework/web/actions/CInlineAction.php

                    [line] => 32

                    [function] => actionTest

                    [class] => SiteController

                    [type] => ->

                    [args] => Array

                        (

                        )


                )


            [4] => Array

                (

                    [file] => /var/frameworks/yii-1.1.1/framework/web/CController.php

                    [line] => 300

                    [function] => run

                    [class] => CInlineAction

                    [type] => ->

                    [args] => Array

                        (

                        )


                )


            [5] => Array

                (

                    [file] => /var/frameworks/yii-1.1.1/framework/web/CController.php

                    [line] => 278

                    [function] => runAction

                    [class] => CController

                    [type] => ->

                    [args] => Array

                        (

                            [0] => CInlineAction Object

                                (

                                    [_id:CAction:private] => test

                                    [_controller:CAction:private] => SiteController Object

                                        (

                                            [breadcrumbs] => Array

                                                (

                                                )


                                            [user] => 

                                            [JUI] => 

                                            [layout] => 

                                            [defaultAction] => index

                                            [_id:CController:private] => site

                                            [_action:CController:private] => CInlineAction Object

 *RECURSION*

                                            [_pageTitle:CController:private] => 

                                            [_cachingStack:CController:private] => 

                                            [_clips:CController:private] => 

                                            [_dynamicOutput:CController:private] => 

                                            [_pageStates:CController:private] => 

                                            [_module:CController:private] => 

                                            [_widgetStack:CBaseController:private] => Array

                                                (

                                                )


                                            [_e:CComponent:private] => 

                                            [_m:CComponent:private] => 

                                        )


                                    [_e:CComponent:private] => 

                                    [_m:CComponent:private] => 

                                )


                        )


                )


            [6] => Array

                (

                    [file] => /var/frameworks/yii-1.1.1/framework/web/CController.php

                    [line] => 257

                    [function] => runActionWithFilters

                    [class] => CController

                    [type] => ->

                    [args] => Array

                        (

                            [0] => CInlineAction Object

                                (

                                    [_id:CAction:private] => test

                                    [_controller:CAction:private] => SiteController Object

                                        (

                                            [breadcrumbs] => Array

                                                (

                                                )


                                            [user] => 

                                            [JUI] => 

                                            [layout] => 

                                            [defaultAction] => index

                                            [_id:CController:private] => site

                                            [_action:CController:private] => CInlineAction Object

 *RECURSION*

                                            [_pageTitle:CController:private] => 

                                            [_cachingStack:CController:private] => 

                                            [_clips:CController:private] => 

                                            [_dynamicOutput:CController:private] => 

                                            [_pageStates:CController:private] => 

                                            [_module:CController:private] => 

                                            [_widgetStack:CBaseController:private] => Array

                                                (

                                                )


                                            [_e:CComponent:private] => 

                                            [_m:CComponent:private] => 

                                        )


                                    [_e:CComponent:private] => 

                                    [_m:CComponent:private] => 

                                )


                            [1] => Array

                                (

                                )


                        )


                )


            [7] => Array

                (

                    [file] => /var/frameworks/yii-1.1.1/framework/web/CWebApplication.php

                    [line] => 320

                    [function] => run

                    [class] => CController

                    [type] => ->

                    [args] => Array

                        (

                            [0] => test

                        )


                )


            [8] => Array

                (

                    [file] => /var/frameworks/yii-1.1.1/framework/web/CWebApplication.php

                    [line] => 120

                    [function] => runController

                    [class] => CWebApplication

                    [type] => ->

                    [args] => Array

                        (

                            [0] => site/test

                        )


                )


            [9] => Array

                (

                    [file] => /var/frameworks/yii-1.1.1/framework/base/CApplication.php

                    [line] => 135

                    [function] => processRequest

                    [class] => CWebApplication

                    [type] => ->

                    [args] => Array

                        (

                        )


                )


            [10] => Array

                (

                    [file] => /var/www/vhosts/mydomain.com/httpdocs/index.php

                    [line] => 16

                    [function] => run

                    [class] => CApplication

                    [type] => ->

                    [args] => Array

                        (

                        )


                )


        )


    [previous:Exception:private] => 

    [faultstring] => CHttpException

    [faultcode] => HTTP

)



The log suggests CSRF validation failed so I turned it off and now I got ‘Wrong Version’ error…




SoapFault Object

(

    [message:protected] => Wrong Version

    [string:Exception:private] => 

    [code:protected] => 0

    [file:protected] => C:\xampp\htdocs\index.php

    [line:protected] => 4

    [trace:Exception:private] => Array

        (

            [0] => Array

                (

                    [function] => __call

                    [class] => SoapClient

                    [type] => ->

                    [args] => Array

                        (

                            [0] => getPrice

                            [1] => Array

                                (

                                    [0] => GOOGLE

                                )


                        )


                )


            [1] => Array

                (

                    [file] => C:\xampp\htdocs\index.php

                    [line] => 4

                    [function] => getPrice

                    [class] => SoapClient

                    [type] => ->

                    [args] => Array

                        (

                            [0] => GOOGLE

                        )


                )


        )


    [previous:Exception:private] => 

    [faultstring] => Wrong Version

    [faultcode] => VersionMismatch

    [faultcodens] => http://schemas.xmlsoap.org/soap/envelope/

)



Not sure where to go from here?

Right, I have uploaded the basic Soap app to my server. Can someone please try…

The url is http://yii.kevinbradwick.co.uk/index.php?r=site/quote

I’ve tried this from my local vm running PHP 5.3.2 using




<?php


ini_set('display_errors','on');


try {

$client = new SoapClient('http://yii.kevinbradwick.co.uk/index.php?r=site/quote?wsdl');

echo $client->getPrice('GOOGLE');

} catch (SoapFault $e) {

	print_r($e);

}


?>



and get




SoapFault Object

(

    [message:protected] => SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://yii.kevinbradwick.co.uk/index.php?r=site/quote?wsdl' : failed to load external entity "http://yii.kevinbradwick.co.uk/index.php?r=site/quote?wsdl"


    [string:Exception:private] => 

    [code:protected] => 0

    [file:protected] => /var/www/vhosts/mydomain.biz/httpdocs/soap.php

    [line:protected] => 6

    [trace:Exception:private] => Array

        (

            [0] => Array

                (

                    [file] => /var/www/vhosts/mydomain.biz/httpdocs/soap.php

                    [line] => 6

                    [function] => SoapClient

                    [class] => SoapClient

                    [type] => ->

                    [args] => Array

                        (

                            [0] => http://yii.kevinbradwick.co.uk/index.php?r=site/quote?wsdl

                        )


                )


        )


    [previous:Exception:private] => 

    [faultstring] => SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://yii.kevinbradwick.co.uk/index.php?r=site/quote?wsdl' : failed to load external entity "http://yii.kevinbradwick.co.uk/index.php?r=site/quote?wsdl"


    [faultcode] => WSDL

)



I’ve also tried it without the ?wsdl and get




SoapFault Object

(

    [message:protected] => DTD are not supported by SOAP

    [string:Exception:private] => 

    [code:protected] => 0

    [file:protected] => /var/www/vhosts/mydomain.biz/httpdocs/soap.php

    [line:protected] => 7

    [trace:Exception:private] => Array

        (

            [0] => Array

                (

                    [function] => __call

                    [class] => SoapClient

                    [type] => ->

                    [args] => Array

                        (

                            [0] => getPrice

                            [1] => Array

                                (

                                    [0] => GOOGLE

                                )


                        )


                )


            [1] => Array

                (

                    [file] => /var/www/vhosts/mydomain.biz/httpdocs/soap.php

                    [line] => 7

                    [function] => getPrice

                    [class] => SoapClient

                    [type] => ->

                    [args] => Array

                        (

                            [0] => GOOGLE

                        )


                )


        )


    [previous:Exception:private] => 

    [faultstring] => DTD are not supported by SOAP

    [faultcode] => Client

    [faultcodens] => http://schemas.xmlsoap.org/soap/envelope/

)



I’m running Yii version 1.1.1 on a webserver that has PHP 5.1.6.

Is this a Yii bug or am I doing something wrong?

I looks as though this is a Yii/PHP 5.3+ thing as creating the simple script on my server running 5.1.6 works.

try http://yii.kevinbradwick.co.uk/soap.php




<?php


ini_set('display_errors','on');


try {

$client = new SoapClient('http://yii.kevinbradwick.co.uk/index.php?r=site/quote');

echo $client->getPrice('GOOGLE');

} catch (SoapFault $e) {

	print_r($e);

}


?>



output




350



I tried your script above. Works on both 5.3.1 (openSuse) and 5.2.4 (Ubuntu). It seems like you have some problem in your VM box. Since you are only using SoapClient it’s not Yii related at all.

Edit: On second thought it might be Yii related if there’s - according to your error message - some newer “DTD” Yii doesn’t support. (I don’t know the exact meaning of “DTD” in this context.)

BTW While testing, you should change the wsdl cache ttl.

Update: ini_set(soap.wsdl_cache_enabled, ‘0’) in your script did not work for me. Had to change php.ini, then the wsdl was fetched again.

/Tommy

I have finally uncovered the problem causing this to fail.

The problem is threefold. Firstly, my htaccess appeared to be causing an issue so I now have




Options +FollowSymLinks

IndexIgnore */*

RewriteEngine on


# if a directory or a file exists, use it directly

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d


# otherwise forward it to index.php

RewriteRule . index.php



Secondly, I had a ‘baseUrl’ paramater set in the request component of my main.php config file that caused a conflict.

The final obstacle I came across was again with the request component. If I enable csrf validation then the service runs into a CHttpException - where the log states ‘The CSRF token could not be verified’.

Is there a way to get around this and disabled CSRF validation for the controller running the Soap service?

This problem occur sometimes is due to the server could not retrieve the WSDL document.

Some router configuration does not allow client in the network to use the external ip to connect back to itself

especially for port 80 where the webserver is hosting.

As a result, CWebServiceAction will instantiate SoapServer based on the domain name which

resolve to external ip would result unreachable situation.

The solution to this problem is : add an entry to your local machine (Server) DNS to resolve your

domain name into 127.0.0.1.

For Linux :

edit your /etc/hosts

add an entry:

127.0.0.1 yourdomain.com