PHP Akamai SOAP Exception - php

I am making a SOAP request and it successfully return the function list which you can call.
I am calling PurgeRequest method and receiving following error
Exception: class com.idoox.soap.DemarshallException: Type in schema
differs from type in SOAP message - expected
string#http://www.w3.org/1999/XMLSchema; got
Map#http://xml.apache.org/xml-soap"
I tried with SOAP UI and get the successful response id. But, my PHP request is failing..Can some one tell me what this error is about and how to resolve this. one reference say it is because of passing the empty array but I am sure that parameter is not empty.
if(class_exists('SoapClient'))
{
$client = new SoapClient('https://ccuapi.akamai.com/ccuapi.wsdl',
array(
'trace' => 1,
'exceptions' => 0,
'features' => SOAP_USE_XSI_ARRAY_TYPE
)
);
echo '<pre>';
var_dump($client->__getFunctions());
try {
$purgeResult = $client->purgeRequest($username,$password,'',$opt,$url);
}
catch(SoapFault $e){
echo "Exception\n";
}
echo '<pre>';
var_dump($purgeResult);
}

It works for me, but I'm not logging in (of course). I get normal SOAP exceptions:
Exception: class com.idoox.soap.DemarshallException: Dimensions not found in array type
when I pass an empty string in $opt, or
object(stdClass)#2 (6) {
["resultCode"]=>
int(301)
["resultMsg"]=>
string(29) "Invalid username or password."
["sessionID"]=>
string(16) "17F1327329982356"
["estTime"]=>
int(-1)
["uriIndex"]=>
int(-1)
["modifiers"]=>
NULL
}
when I pass empty arrays in $opt and $url.
Anyway, your issue seems to be due to different SOAP xsd headers. The service expects http://www.w3.org/1999/XMLSchema header, your script seems to be passing http://xml.apache.org/xml-soap.
Service WSDL defines it:
<?xml version="1.0" standalone="no"?>
<definitions name="PurgeRequest"
targetNamespace="http://www.akamai.com/purge"
xmlns:tns="http://www.akamai.com/purge"
xmlns:purgedt="http://www.akamai.com/purge"
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
You need to make sure your client respects this and sets it properly.
Please post output of your
var_dump($client->__getLastRequest());
(right after
var_dump($purgeResult);
)
mine looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.akamai.com/purge"
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:purgeRequest>
<name xsi:type="xsd:string">ee</name>
<pwd xsi:type="xsd:string">rr</pwd>
<network xsi:type="xsd:string"/>
<opt SOAP-ENC:arrayType="xsd:string[1]" xsi:type="SOAP-ENC:Array">
<item xsi:type="xsd:string"/>
</opt>
<uri SOAP-ENC:arrayType="xsd:string[1]" xsi:type="SOAP-ENC:Array">
<item xsi:type="xsd:string"/>
</uri>
</ns1:purgeRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
see, this request features xmlns:xsd="http://www.w3.org/2001/XMLSchema"
Also make sure you are using right SOAP version
'soap_version' => SOAP_1_1
and your __doRequest() method in SOAP extension is not overriden to send custom headers, like here.

Related

PHP SoapServer return empty response on function without return

i have a soap with a method that return nothing
class mySoapService {
foo(){
}
}
$wsdl = ...;
$soapService = new mySoapService();
$soapServer = new \SoapServer($wsdl);
$soapServer->setObject($soapService);
$soapServer->handle(); // write nothing on call foo
some soap client raise an exception because they expect a proper xml-soap empty response, like this:
<?xml version="1.0"?>
<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/">
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
the questions are:
why PHP SoapServer return an empty response and not a xml-soap empty response?
what say the soap standard for method without return a value?
Changing
$soapServer->handle();
to
$soapServer->handle(file_get_contents("php://input"));
worked for me

unable to serialize the result error in nusoap webservice

i got the below error while inserting a new order through nusoap webservice
<SOAP-ENV:Envelope SOAP-
ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 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/">
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode xsi:type="xsd:string">SOAP-ENV:Server</faultcode>
<faultactor xsi:type="xsd:string"/>
<faultstring xsi:type="xsd:string">unable to serialize result</faultstring>
<detail xsi:type="xsd:string"/>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Please help
Error says that your response class is not serialize and it should be serialize.
Try to make serialize your response class and try again.
You should set the return type while registering your service, like the following example:
// registering login method in the wsdl
$input_array = array('username' => "xsd:string", 'password' => "xsd:string"); // login parameters
$return_array = array("return" => "xsd:string");
$this->nusoap_server->register('login', $input_array, $return_array, "urn:SOAPServerWSDL", "urn:" . $this->ns . "/login", "rpc", "encoded", "Login to server services");
In my case I set the return type to be string, I think you should do the same,

Wrong SOAP Tags in PHP SOAP Request

I'm trying to send an SOAP request.
My request looks like this
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="someurl">
<SOAP-ENV:Body>
<RequestIndBApplication>
But my customer told me it has to look like this
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<process xmlns="someurl">
<RequestIndBApplication>
I'm using an WSDL file i got from my customer. But i don't know how i can change the soap tag. is there a way to do this?
Here is my php code
$client = new SoapClient('urlofwsdlfile',array('trace' => true, 'exceptions' => true)); $params = new \SoapVar($xmlstr), \XSD_ANYXML);
$result = $client->__SoapCall('process', array($params));
$xmlstr contains the data as xml

PHP SoapServer formatting

I am new to SOAP and trying to format a SOAP response using PHP's SoapServer class.
It might be useful to know that this is for an EWS Push Subscription callback service and that I am using the php-ews library. I have managed to subscribe to the EWS Push Subscription but am having trouble formatting the reply which EWS is expecting from my callback service.
I need the following SOAP response returned by my PHP SOAP service:
<s:Envelope xmlns:s= "http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<SendNotificationResult xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
<SubscriptionStatus>OK</SubscriptionStatus>
</SendNotificationResult>
</s:Body>
</s:Envelope>
Instead I am getting the following output:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/ioc/ebooking_v4/services/ews/notification.php" 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:SendNotificationResponse>
<return xsi:type="SOAP-ENC:Struct">
<SubscriptionStatus xsi:type="xsd:string">OK</SubscriptionStatus>
</return>
</ns1:SendNotificationResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
My PHP service code:
class ewsService {
public function SendNotification( $arg ) {
$result = new EWSType_SendNotificationResultType();
$result->SubscriptionStatus = 'OK';
return $result;
}
}
$server = new soapServer( null, array(
'uri' => $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'],
));
$server->setObject( new ewsService() );
$server->handle();
The SOAP call to my service is as follows:
<soap11:Envelope xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/">
<soap11:Header>
<t:RequestServerVersion xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" Version="Exchange2010_SP2" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" />
</soap11:Header>
<soap11:Body>
<m:SendNotification xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
<m:ResponseMessages>
<m:SendNotificationResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Notification>
<t:SubscriptionId>GQBjaGNpb2ExODEuY2lvLm9seW1waWMub3JnEAAAAFgvEpJcS3JDkpvHOMgnX60FhmhpPInRCA==</t:SubscriptionId>
<t:PreviousWatermark>AQAAAIiCiXu/q1ZPvYPyvRVVh5cajSoKAAAAAAA=</t:PreviousWatermark>
<t:MoreEvents>false</t:MoreEvents>
<t:StatusEvent>
<t:Watermark>AQAAAIiCiXu/q1ZPvYPyvRVVh5cajSoKAAAAAAA=</t:Watermark>
</t:StatusEvent>
</m:Notification>
</m:SendNotificationResponseMessage>
</m:ResponseMessages>
</m:SendNotification>
</soap11:Body>
</soap11:Envelope>
So I suppose my question is how do I to change the formatting of the SOAP response, using the PHP SoapServer class? Do I need to add a WSDL or pass a classmap to the SoapServer constructor?
If there is no way to do this using the SoapServer class, is there any other way to do this other than creating a string buffer and passing that back manually?
Any help would be greatly appreciated.
I figured this out and posted the solution on a more generic question of this problem here
For completeness I have included the answer here as well...
It would seem that I was close but needed to include the NotificationService.wsdl when instantiating the SoapServer class. The WSDL then allows that SoapServer class to format the response accordingly.
$server = new SoapServer( PHPEWS_PATH.'/wsdl/NotificationService.wsdl', array(
The WSDL was not included in the php-ews library download, however it is included with the Exchange Server installation. If like me you don't have access to the Exchange Server installation you can find the file here. I also had to add the following to the end of the WSDL because I was storing the WSDLs locally and not using autodiscovery:
<wsdl:service name="NotificationServices">
<wsdl:port name="NotificationServicePort" binding="tns:NotificationServiceBinding">
<soap:address location="" />
</wsdl:port>
</wsdl:service>
So the full working PHP code is as follows:
class ewsService {
public function SendNotification( $arg ) {
$result = new EWSType_SendNotificationResultType();
$result->SubscriptionStatus = 'OK';
//$result->SubscriptionStatus = 'Unsubscribe';
return $result;
}
}
$server = new SoapServer( PHPEWS_PATH.'/wsdl/NotificationService.wsdl', array(
'uri' => $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'],
));
$server->setObject( $service = new ewsService() );
$server->handle();
Which gives the following output:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.microsoft.com/exchange/services/2006/messages">
<SOAP-ENV:Body>
<ns1:SendNotificationResult>
<ns1:SubscriptionStatus>OK</ns1:SubscriptionStatus>
</ns1:SendNotificationResult>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Hope that helps someone else because that took me a while to figure out!

PHP SoapClient: Action mismatch

I am trying to use the PHP SoapClient extension to communicate with an external SOAP server.
This is my code:
$this->_client = new SoapClient(SOAP_TAGGING_URL, array(
'trace' => 1,
'soap_version' => SOAP_1_2,
'cache_wsdl' => WSDL_CACHE_NONE,
'exceptions' => true,
'uri' => SOAP_URI,
));
try {
$actionHdr = array();
$actionHdr[] = new SoapHeader(SOAP_TAGGING_URL, 'Action', 'GetMessagesByTagsByGroup');
$this->_client->__setSoapHeaders($actionHdr);
$info = $this->_client->GetMessagesByTagsByGroup(
new SoapParam($this->params['mPID'], 'ParentMessageID'),
new SoapParam($gid, 'GroupId'),
new SoapParam(REQUEST_TOKEN, 'RequestToken'),
new SoapParam(ACCESS_TOKEN, 'AccessToken'),
new SoapParam(ACCESS_TOKEN_SECRET, 'AccessTokenSecret')
);
} catch (SoapFault $fault) {
print("\n<br/>SOAP server returned the following ERROR: ".$fault->faultcode."-".$fault->faultstring);
}
echo "\n<br/>SOAP request: ". htmlentities($this->_client->__getLastRequest());
echo "\n<br/>SOAP response: ". htmlentities($this->_client->__getLastResponse());
This is the response I get (formatting added):
SOAP server returned the following ERROR: s:Sender-The SOAP action specified on the message, '', does not match the HTTP SOAP Action, 'http://tempuri.org/ITagging/GetMessagesByTagsByGroup'.
SOAP request:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://tempuri.org/" xmlns:ns2="https://mywebserver.com/myWSDL.svc/ws?wsdl">
<env:Header>
<ns2:Action>GetMessagesByTagsByGroup</ns2:Action>
</env:Header>
<env:Body>
<ns1:GetMessagesByTagsByGroup/>
<GroupId>2178</GroupId>
<RequestToken>odwedwo09i0jACqbbjsw6KnlCA=</RequestToken>
<AccessToken>OlVbHurPJrNrEFR54Y0hV9kI/TZs=</AccessToken>
<AccessTokenSecret>js1kerfe453FLuaXpL 892DY o=</AccessTokenSecret>
</env:Body>
</env:Envelope>
SOAP response:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/fault</a:Action>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
<s:Subcode>
<s:Value>a:ActionMismatch</s:Value>
</s:Subcode>
</s:Code>
<s:Reason>
<s:Text xml:lang="en-US">The SOAP action specified on the message, '', does not match the HTTP SOAP Action, 'http://tempuri.org/ITagging/GetMessagesByTagsByGroup'. </s:Text>
</s:Reason>
<s:Detail>
<a:ProblemHeaderQName>a:Action</a:ProblemHeaderQName>
</s:Detail>
</s:Fault>
</s:Body>
</s:Envelope>
I thought I added the 'Action' parameter in the header, but clearly that is not the place to put it. Or am I doing something else wrong?
Unfortunately I cannot try NuSoap because I have no control over the server.
Thank you,
gm
It means meant that not only you must specify the HTTP header SOAPAction: "http://www.bla.com:MyAction"
but you need to specify also in the SOAP Envelope the header:
Check these links for some ref:
SOAP ACTION
You're passing it as SoapHeader, but actually it is HTTP header.
The way I found to do it is: http://lt.php.net/manual/en/soapclient.dorequest.php by setting $action parameter.
You'll probably need to extend SoapClient class to do it using less lines of code.

Categories