SoapFault handling refactored: client now returns server fault codes + more details in message
This commit is contained in:
parent
f669c18c7f
commit
8db9b374e4
@ -152,10 +152,11 @@ class Curl
|
|||||||
preg_match('/HTTP\/(1\.[0-1]+) ([0-9]{3}) (.*)/', $executeSoapCallResponse, $httpResponseMessages);
|
preg_match('/HTTP\/(1\.[0-1]+) ([0-9]{3}) (.*)/', $executeSoapCallResponse, $httpResponseMessages);
|
||||||
$httpResponseMessage = trim(array_pop($httpResponseMessages));
|
$httpResponseMessage = trim(array_pop($httpResponseMessages));
|
||||||
$curlErrorMessage = sprintf(
|
$curlErrorMessage = sprintf(
|
||||||
'Curl error "%s" with message: %s occurred while connecting to %s',
|
'Curl error "%s" with message: %s occurred while connecting to %s with HTTP response code %s',
|
||||||
curl_errno($curlSession),
|
curl_errno($curlSession),
|
||||||
curl_error($curlSession),
|
curl_error($curlSession),
|
||||||
$location
|
$location,
|
||||||
|
$httpResponseCode
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!is_integer($httpResponseCode) || $httpResponseCode >= 400 || $httpResponseCode === 0) {
|
if (!is_integer($httpResponseCode) || $httpResponseCode >= 400 || $httpResponseCode === 0) {
|
||||||
|
@ -19,6 +19,7 @@ use BeSimple\SoapClient\Curl\CurlOptionsBuilder;
|
|||||||
use BeSimple\SoapClient\Curl\CurlResponse;
|
use BeSimple\SoapClient\Curl\CurlResponse;
|
||||||
use BeSimple\SoapClient\SoapOptions\SoapClientOptions;
|
use BeSimple\SoapClient\SoapOptions\SoapClientOptions;
|
||||||
use BeSimple\SoapCommon\Fault\SoapFaultEnum;
|
use BeSimple\SoapCommon\Fault\SoapFaultEnum;
|
||||||
|
use BeSimple\SoapCommon\Fault\SoapFaultParser;
|
||||||
use BeSimple\SoapCommon\Fault\SoapFaultPrefixEnum;
|
use BeSimple\SoapCommon\Fault\SoapFaultPrefixEnum;
|
||||||
use BeSimple\SoapCommon\Fault\SoapFaultSourceGetter;
|
use BeSimple\SoapCommon\Fault\SoapFaultSourceGetter;
|
||||||
use BeSimple\SoapCommon\Mime\PartFactory;
|
use BeSimple\SoapCommon\Mime\PartFactory;
|
||||||
@ -40,16 +41,14 @@ use SoapFault;
|
|||||||
*/
|
*/
|
||||||
class SoapClient extends \SoapClient
|
class SoapClient extends \SoapClient
|
||||||
{
|
{
|
||||||
|
use SoapClientNativeMethodsTrait;
|
||||||
|
|
||||||
/** @var SoapClientOptions */
|
/** @var SoapClientOptions */
|
||||||
protected $soapClientOptions;
|
protected $soapClientOptions;
|
||||||
/** @var SoapOptions */
|
/** @var SoapOptions */
|
||||||
protected $soapOptions;
|
protected $soapOptions;
|
||||||
/** @var Curl */
|
/** @var Curl */
|
||||||
private $curl;
|
private $curl;
|
||||||
/** @var SoapAttachment[] */
|
|
||||||
private $soapAttachmentsOnRequestStorage;
|
|
||||||
/** @var SoapResponse */
|
|
||||||
private $soapResponseStorage;
|
|
||||||
|
|
||||||
public function __construct(SoapClientOptions $soapClientOptions, SoapOptions $soapOptions)
|
public function __construct(SoapClientOptions $soapClientOptions, SoapOptions $soapOptions)
|
||||||
{
|
{
|
||||||
@ -76,33 +75,6 @@ class SoapClient extends \SoapClient
|
|||||||
@parent::__construct($wsdlPath, $soapClientOptions->toArray() + $soapOptions->toArray());
|
@parent::__construct($wsdlPath, $soapClientOptions->toArray() + $soapOptions->toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Avoid using __call directly, it's deprecated even in \SoapClient.
|
|
||||||
*
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
public function __call($function_name, $arguments)
|
|
||||||
{
|
|
||||||
throw new Exception(
|
|
||||||
'The __call method is deprecated. Use __soapCall/soapCall instead.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Using __soapCall returns only response string, use soapCall instead.
|
|
||||||
*
|
|
||||||
* @param string $function_name
|
|
||||||
* @param array $arguments
|
|
||||||
* @param array|null $options
|
|
||||||
* @param null $input_headers
|
|
||||||
* @param array|null $output_headers
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __soapCall($function_name, $arguments, $options = null, $input_headers = null, &$output_headers = null)
|
|
||||||
{
|
|
||||||
return $this->soapCall($function_name, $arguments, $options, $input_headers, $output_headers)->getResponseContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $functionName
|
* @param string $functionName
|
||||||
* @param array $arguments
|
* @param array $arguments
|
||||||
@ -125,95 +97,13 @@ class SoapClient extends \SoapClient
|
|||||||
|
|
||||||
} catch (SoapFault $soapFault) {
|
} catch (SoapFault $soapFault) {
|
||||||
if (SoapFaultSourceGetter::isNativeSoapFault($soapFault)) {
|
if (SoapFaultSourceGetter::isNativeSoapFault($soapFault)) {
|
||||||
$soapResponse = $this->getSoapResponseFromStorage();
|
$soapFault = $this->decorateNativeSoapFault($soapFault);
|
||||||
if ($soapResponse instanceof SoapResponse) {
|
|
||||||
$soapFault = $this->throwSoapFaultByTracing(
|
|
||||||
SoapFaultPrefixEnum::PREFIX_PHP . '-' . $soapFault->getCode(),
|
|
||||||
$soapFault->getMessage(),
|
|
||||||
new SoapResponseTracingData(
|
|
||||||
'Content-Type: ' . $soapResponse->getRequest()->getContentType(),
|
|
||||||
$soapResponse->getRequest()->getContent(),
|
|
||||||
'Content-Type: ' . $soapResponse->getContentType(),
|
|
||||||
$soapResponse->getResponseContent()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$soapFault = new SoapFault(
|
|
||||||
SoapFaultPrefixEnum::PREFIX_PHP . '-unresolved',
|
|
||||||
'Got SoapFault message with no response: '.$soapFault->getMessage()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw $soapFault;
|
throw $soapFault;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This is not performing any HTTP requests, but it is getting data from SoapClient that are needed for this Client
|
|
||||||
*
|
|
||||||
* @param string $request Request string
|
|
||||||
* @param string $location Location
|
|
||||||
* @param string $action SOAP action
|
|
||||||
* @param int $version SOAP version
|
|
||||||
* @param int $oneWay 0|1
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __doRequest($request, $location, $action, $version, $oneWay = 0)
|
|
||||||
{
|
|
||||||
$soapResponse = $this->performSoapRequest(
|
|
||||||
$request,
|
|
||||||
$location,
|
|
||||||
$action,
|
|
||||||
$version,
|
|
||||||
$this->getSoapAttachmentsOnRequestFromStorage()
|
|
||||||
);
|
|
||||||
$this->setSoapResponseToStorage($soapResponse);
|
|
||||||
|
|
||||||
return $soapResponse->getResponseContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
public function __getLastRequestHeaders()
|
|
||||||
{
|
|
||||||
$this->checkTracing();
|
|
||||||
|
|
||||||
throw new Exception(
|
|
||||||
'The __getLastRequestHeaders method is now deprecated. Use callSoapRequest instead and get the tracing information from SoapResponseTracingData.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
public function __getLastRequest()
|
|
||||||
{
|
|
||||||
$this->checkTracing();
|
|
||||||
|
|
||||||
throw new Exception(
|
|
||||||
'The __getLastRequest method is now deprecated. Use callSoapRequest instead and get the tracing information from SoapResponseTracingData.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
public function __getLastResponseHeaders()
|
|
||||||
{
|
|
||||||
$this->checkTracing();
|
|
||||||
|
|
||||||
throw new Exception(
|
|
||||||
'The __getLastResponseHeaders method is now deprecated. Use callSoapRequest instead and get the tracing information from SoapResponseTracingData.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @deprecated */
|
|
||||||
public function __getLastResponse()
|
|
||||||
{
|
|
||||||
$this->checkTracing();
|
|
||||||
|
|
||||||
throw new Exception(
|
|
||||||
'The __getLastResponse method is now deprecated. Use callSoapRequest instead and get the tracing information from SoapResponseTracingData.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom request method to be able to modify the SOAP messages.
|
* Custom request method to be able to modify the SOAP messages.
|
||||||
* $oneWay parameter is not used at the moment.
|
* $oneWay parameter is not used at the moment.
|
||||||
@ -226,7 +116,7 @@ class SoapClient extends \SoapClient
|
|||||||
*
|
*
|
||||||
* @return SoapResponse
|
* @return SoapResponse
|
||||||
*/
|
*/
|
||||||
private function performSoapRequest($request, $location, $action, $version, array $soapAttachments = [])
|
protected function performSoapRequest($request, $location, $action, $version, array $soapAttachments = [])
|
||||||
{
|
{
|
||||||
$soapRequest = $this->createSoapRequest($location, $action, $version, $request, $soapAttachments);
|
$soapRequest = $this->createSoapRequest($location, $action, $version, $request, $soapAttachments);
|
||||||
|
|
||||||
@ -273,22 +163,10 @@ class SoapClient extends \SoapClient
|
|||||||
*/
|
*/
|
||||||
private function performHttpSoapRequest(SoapRequest $soapRequest)
|
private function performHttpSoapRequest(SoapRequest $soapRequest)
|
||||||
{
|
{
|
||||||
if ($soapRequest->getVersion() === SOAP_1_1) {
|
|
||||||
$headers = [
|
|
||||||
'Content-Type: ' . $soapRequest->getContentType(),
|
|
||||||
'SOAPAction: "' . $soapRequest->getAction() . '"',
|
|
||||||
'Connection: ' . ($this->soapOptions->isConnectionKeepAlive() ? 'Keep-Alive' : 'close'),
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$headers = [
|
|
||||||
'Content-Type: ' . $soapRequest->getContentType() . '; action="' . $soapRequest->getAction() . '"',
|
|
||||||
'Connection: ' . ($this->soapOptions->isConnectionKeepAlive() ? 'Keep-Alive' : 'close'),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
$curlResponse = $this->curl->executeCurlWithCachedSession(
|
$curlResponse = $this->curl->executeCurlWithCachedSession(
|
||||||
$soapRequest->getLocation(),
|
$soapRequest->getLocation(),
|
||||||
$soapRequest->getContent(),
|
$soapRequest->getContent(),
|
||||||
$headers
|
$this->getHttpHeadersBySoapVersion($soapRequest)
|
||||||
);
|
);
|
||||||
$soapResponseTracingData = new SoapResponseTracingData(
|
$soapResponseTracingData = new SoapResponseTracingData(
|
||||||
$curlResponse->getHttpRequestHeaders(),
|
$curlResponse->getHttpRequestHeaders(),
|
||||||
@ -310,26 +188,42 @@ class SoapClient extends \SoapClient
|
|||||||
$this->getAttachmentFilters(),
|
$this->getAttachmentFilters(),
|
||||||
$this->soapOptions->getAttachmentType()
|
$this->soapOptions->getAttachmentType()
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return $soapResponse;
|
|
||||||
}
|
}
|
||||||
} else if ($curlResponse->curlStatusFailed()) {
|
|
||||||
|
return $soapResponse;
|
||||||
|
|
||||||
|
}
|
||||||
|
if ($curlResponse->curlStatusFailed()) {
|
||||||
|
|
||||||
|
if ($curlResponse->getHttpResponseStatusCode() >= 500) {
|
||||||
|
$soapFault = SoapFaultParser::parseSoapFault(
|
||||||
|
$curlResponse->getResponseBody()
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->throwSoapFaultByTracing(
|
||||||
|
$soapFault->faultcode,
|
||||||
|
sprintf(
|
||||||
|
'SOAP HTTP call failed: %s with Message: %s and Code: %s',
|
||||||
|
$curlResponse->getCurlErrorMessage(),
|
||||||
|
$soapFault->getMessage(),
|
||||||
|
$soapFault->faultcode
|
||||||
|
),
|
||||||
|
$soapResponseTracingData
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->throwSoapFaultByTracing(
|
return $this->throwSoapFaultByTracing(
|
||||||
SoapFaultEnum::SOAP_FAULT_HTTP.'-'.$curlResponse->getHttpResponseStatusCode(),
|
SoapFaultEnum::SOAP_FAULT_HTTP.'-'.$curlResponse->getHttpResponseStatusCode(),
|
||||||
$curlResponse->getCurlErrorMessage(),
|
$curlResponse->getCurlErrorMessage(),
|
||||||
$soapResponseTracingData
|
$soapResponseTracingData
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
|
|
||||||
return $this->throwSoapFaultByTracing(
|
|
||||||
SoapFaultEnum::SOAP_FAULT_SOAP_CLIENT_ERROR,
|
|
||||||
'Cannot process curl response with unresolved status: ' . $curlResponse->getCurlStatus(),
|
|
||||||
$soapResponseTracingData
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this->throwSoapFaultByTracing(
|
||||||
|
SoapFaultEnum::SOAP_FAULT_SOAP_CLIENT_ERROR,
|
||||||
|
'Cannot process curl response with unresolved status: ' . $curlResponse->getCurlStatus(),
|
||||||
|
$soapResponseTracingData
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -383,18 +277,16 @@ class SoapClient extends \SoapClient
|
|||||||
$soapResponseTracingData,
|
$soapResponseTracingData,
|
||||||
$soapAttachments
|
$soapAttachments
|
||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
return SoapResponseFactory::create(
|
|
||||||
$curlResponse->getResponseBody(),
|
|
||||||
$soapRequest->getLocation(),
|
|
||||||
$soapRequest->getAction(),
|
|
||||||
$soapRequest->getVersion(),
|
|
||||||
$curlResponse->getHttpResponseContentType(),
|
|
||||||
$soapAttachments
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SoapResponseFactory::create(
|
||||||
|
$curlResponse->getResponseBody(),
|
||||||
|
$soapRequest->getLocation(),
|
||||||
|
$soapRequest->getAction(),
|
||||||
|
$soapRequest->getVersion(),
|
||||||
|
$curlResponse->getHttpResponseContentType(),
|
||||||
|
$soapAttachments
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -412,49 +304,59 @@ class SoapClient extends \SoapClient
|
|||||||
$soapFaultMessage,
|
$soapFaultMessage,
|
||||||
$soapResponseTracingData
|
$soapResponseTracingData
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new SoapFault(
|
||||||
|
$soapFaultCode,
|
||||||
|
$soapFaultMessage
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function decorateNativeSoapFault(SoapFault $nativePhpSoapFault)
|
||||||
|
{
|
||||||
|
$soapResponse = $this->getSoapResponseFromStorage();
|
||||||
|
if ($soapResponse instanceof SoapResponse) {
|
||||||
|
$tracingData = new SoapResponseTracingData(
|
||||||
|
'Content-Type: ' . $soapResponse->getRequest()->getContentType(),
|
||||||
|
$soapResponse->getRequest()->getContent(),
|
||||||
|
'Content-Type: ' . $soapResponse->getContentType(),
|
||||||
|
$soapResponse->getResponseContent()
|
||||||
|
);
|
||||||
|
$soapFault = $this->throwSoapFaultByTracing(
|
||||||
|
SoapFaultPrefixEnum::PREFIX_PHP . '-' . $nativePhpSoapFault->getCode(),
|
||||||
|
$nativePhpSoapFault->getMessage(),
|
||||||
|
$tracingData
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
|
$soapFault = $this->throwSoapFaultByTracing(
|
||||||
throw new SoapFault(
|
$nativePhpSoapFault->faultcode,
|
||||||
$soapFaultCode,
|
$nativePhpSoapFault->getMessage(),
|
||||||
$soapFaultMessage
|
new SoapResponseTracingData(
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $soapFault;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkTracing()
|
private function getHttpHeadersBySoapVersion(SoapRequest $soapRequest)
|
||||||
{
|
{
|
||||||
if ($this->soapClientOptions->getTrace() === false) {
|
if ($soapRequest->getVersion() === SOAP_1_1) {
|
||||||
throw new Exception('SoapClientOptions tracing disabled, turn on trace attribute');
|
|
||||||
|
return [
|
||||||
|
'Content-Type: ' . $soapRequest->getContentType(),
|
||||||
|
'SOAPAction: "' . $soapRequest->getAction() . '"',
|
||||||
|
'Connection: ' . ($this->soapOptions->isConnectionKeepAlive() ? 'Keep-Alive' : 'close'),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private function setSoapResponseToStorage(SoapResponse $soapResponseStorage)
|
return [
|
||||||
{
|
'Content-Type: ' . $soapRequest->getContentType() . '; action="' . $soapRequest->getAction() . '"',
|
||||||
$this->soapResponseStorage = $soapResponseStorage;
|
'Connection: ' . ($this->soapOptions->isConnectionKeepAlive() ? 'Keep-Alive' : 'close'),
|
||||||
}
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* @param SoapAttachment[] $soapAttachments
|
|
||||||
*/
|
|
||||||
private function setSoapAttachmentsOnRequestToStorage(array $soapAttachments)
|
|
||||||
{
|
|
||||||
$this->soapAttachmentsOnRequestStorage = $soapAttachments;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getSoapAttachmentsOnRequestFromStorage()
|
|
||||||
{
|
|
||||||
$soapAttachmentsOnRequest = $this->soapAttachmentsOnRequestStorage;
|
|
||||||
$this->soapAttachmentsOnRequestStorage = null;
|
|
||||||
|
|
||||||
return $soapAttachmentsOnRequest;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getSoapResponseFromStorage()
|
|
||||||
{
|
|
||||||
$soapResponse = $this->soapResponseStorage;
|
|
||||||
$this->soapResponseStorage = null;
|
|
||||||
|
|
||||||
return $soapResponse;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
166
src/BeSimple/SoapClient/SoapClientNativeMethodsTrait.php
Normal file
166
src/BeSimple/SoapClient/SoapClientNativeMethodsTrait.php
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BeSimple\SoapClient;
|
||||||
|
|
||||||
|
use BeSimple\SoapBundle\Soap\SoapAttachment;
|
||||||
|
use BeSimple\SoapClient\SoapOptions\SoapClientOptions;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
trait SoapClientNativeMethodsTrait
|
||||||
|
{
|
||||||
|
/** @var SoapClientOptions */
|
||||||
|
protected $soapClientOptions;
|
||||||
|
/** @var SoapAttachment[] */
|
||||||
|
private $soapAttachmentsOnRequestStorage;
|
||||||
|
/** @var SoapResponse */
|
||||||
|
private $soapResponseStorage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $functionName
|
||||||
|
* @param array $arguments
|
||||||
|
* @param array|null $options
|
||||||
|
* @param SoapAttachment[] $soapAttachments
|
||||||
|
* @param null $inputHeaders
|
||||||
|
* @param array|null $outputHeaders
|
||||||
|
* @return SoapResponse
|
||||||
|
*/
|
||||||
|
abstract public function soapCall($functionName, array $arguments, array $soapAttachments = [], array $options = null, $inputHeaders = null, array &$outputHeaders = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $request Request object
|
||||||
|
* @param string $location Location
|
||||||
|
* @param string $action SOAP action
|
||||||
|
* @param int $version SOAP version
|
||||||
|
* @param SoapAttachment[] $soapAttachments SOAP attachments array
|
||||||
|
* @return SoapResponse
|
||||||
|
*/
|
||||||
|
abstract protected function performSoapRequest($request, $location, $action, $version, array $soapAttachments = []);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avoid using __call directly, it's deprecated even in \SoapClient.
|
||||||
|
*
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
public function __call($function_name, $arguments)
|
||||||
|
{
|
||||||
|
throw new Exception(
|
||||||
|
'The __call method is deprecated. Use __soapCall/soapCall instead.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Using __soapCall returns only response string, use soapCall instead.
|
||||||
|
*
|
||||||
|
* @param string $function_name
|
||||||
|
* @param array $arguments
|
||||||
|
* @param array|null $options
|
||||||
|
* @param null $input_headers
|
||||||
|
* @param array|null $output_headers
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __soapCall($function_name, $arguments, $options = null, $input_headers = null, &$output_headers = null)
|
||||||
|
{
|
||||||
|
return $this->soapCall($function_name, $arguments, $options, $input_headers, $output_headers)->getResponseContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is not performing any HTTP requests, but it is getting data from SoapClient that are needed for this Client
|
||||||
|
*
|
||||||
|
* @param string $request Request string
|
||||||
|
* @param string $location Location
|
||||||
|
* @param string $action SOAP action
|
||||||
|
* @param int $version SOAP version
|
||||||
|
* @param int $oneWay 0|1
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function __doRequest($request, $location, $action, $version, $oneWay = 0)
|
||||||
|
{
|
||||||
|
$soapResponse = $this->performSoapRequest(
|
||||||
|
$request,
|
||||||
|
$location,
|
||||||
|
$action,
|
||||||
|
$version,
|
||||||
|
$this->getSoapAttachmentsOnRequestFromStorage()
|
||||||
|
);
|
||||||
|
$this->setSoapResponseToStorage($soapResponse);
|
||||||
|
|
||||||
|
return $soapResponse->getResponseContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated */
|
||||||
|
public function __getLastRequestHeaders()
|
||||||
|
{
|
||||||
|
$this->checkTracing();
|
||||||
|
|
||||||
|
throw new Exception(
|
||||||
|
'The __getLastRequestHeaders method is now deprecated. Use callSoapRequest instead and get the tracing information from SoapResponseTracingData.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated */
|
||||||
|
public function __getLastRequest()
|
||||||
|
{
|
||||||
|
$this->checkTracing();
|
||||||
|
|
||||||
|
throw new Exception(
|
||||||
|
'The __getLastRequest method is now deprecated. Use callSoapRequest instead and get the tracing information from SoapResponseTracingData.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated */
|
||||||
|
public function __getLastResponseHeaders()
|
||||||
|
{
|
||||||
|
$this->checkTracing();
|
||||||
|
|
||||||
|
throw new Exception(
|
||||||
|
'The __getLastResponseHeaders method is now deprecated. Use callSoapRequest instead and get the tracing information from SoapResponseTracingData.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @deprecated */
|
||||||
|
public function __getLastResponse()
|
||||||
|
{
|
||||||
|
$this->checkTracing();
|
||||||
|
|
||||||
|
throw new Exception(
|
||||||
|
'The __getLastResponse method is now deprecated. Use callSoapRequest instead and get the tracing information from SoapResponseTracingData.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function checkTracing()
|
||||||
|
{
|
||||||
|
if ($this->soapClientOptions->getTrace() === false) {
|
||||||
|
throw new Exception('SoapClientOptions tracing disabled, turn on trace attribute');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setSoapResponseToStorage(SoapResponse $soapResponseStorage)
|
||||||
|
{
|
||||||
|
$this->soapResponseStorage = $soapResponseStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param SoapAttachment[] $soapAttachments
|
||||||
|
*/
|
||||||
|
private function setSoapAttachmentsOnRequestToStorage(array $soapAttachments)
|
||||||
|
{
|
||||||
|
$this->soapAttachmentsOnRequestStorage = $soapAttachments;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSoapAttachmentsOnRequestFromStorage()
|
||||||
|
{
|
||||||
|
$soapAttachmentsOnRequest = $this->soapAttachmentsOnRequestStorage;
|
||||||
|
$this->soapAttachmentsOnRequestStorage = null;
|
||||||
|
|
||||||
|
return $soapAttachmentsOnRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSoapResponseFromStorage()
|
||||||
|
{
|
||||||
|
$soapResponse = $this->soapResponseStorage;
|
||||||
|
$this->soapResponseStorage = null;
|
||||||
|
|
||||||
|
return $soapResponse;
|
||||||
|
}
|
||||||
|
}
|
31
src/BeSimple/SoapCommon/Fault/SoapFaultParser.php
Normal file
31
src/BeSimple/SoapCommon/Fault/SoapFaultParser.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BeSimple\SoapCommon\Fault;
|
||||||
|
|
||||||
|
use SimpleXMLElement;
|
||||||
|
use SoapFault;
|
||||||
|
|
||||||
|
class SoapFaultParser
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $soapFaultXmlSource
|
||||||
|
* @return SoapFault
|
||||||
|
*/
|
||||||
|
public static function parseSoapFault($soapFaultXmlSource)
|
||||||
|
{
|
||||||
|
$simpleXMLElement = new SimpleXMLElement($soapFaultXmlSource);
|
||||||
|
$faultCode = $simpleXMLElement->xpath('//faultcode');
|
||||||
|
if ($faultCode === false || count($faultCode) === 0) {
|
||||||
|
$faultCode = 'Unable to parse faultCode';
|
||||||
|
}
|
||||||
|
$faultString = $simpleXMLElement->xpath('//faultstring');
|
||||||
|
if ($faultString === false || count($faultString) === 0) {
|
||||||
|
$faultString = 'Unable to parse faultString';
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SoapFault(
|
||||||
|
(string)$faultCode[0],
|
||||||
|
(string)$faultString[0]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
25
tests/BeSimple/SoapCommon/Fault/SoapFaultParserTest.php
Normal file
25
tests/BeSimple/SoapCommon/Fault/SoapFaultParserTest.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace BeSimple\SoapCommon\Fault;
|
||||||
|
|
||||||
|
use PHPUnit_Framework_TestCase;
|
||||||
|
use SoapFault;
|
||||||
|
|
||||||
|
class SoapFaultParserTest extends PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
public function testParse()
|
||||||
|
{
|
||||||
|
$soapFaultXml = '<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>911</faultcode><faultstring>This is a dummy SoapFault.</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>';
|
||||||
|
$soapFault = SoapFaultParser::parseSoapFault($soapFaultXml);
|
||||||
|
|
||||||
|
self::assertInstanceOf(SoapFault::class, $soapFault);
|
||||||
|
self::assertEquals(
|
||||||
|
'911',
|
||||||
|
$soapFault->faultcode
|
||||||
|
);
|
||||||
|
self::assertEquals(
|
||||||
|
'This is a dummy SoapFault.',
|
||||||
|
$soapFault->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@ use Fixtures\DummyServiceMethodWithIncomingLargeSwaRequest;
|
|||||||
use Fixtures\DummyServiceMethodWithOutgoingLargeSwaRequest;
|
use Fixtures\DummyServiceMethodWithOutgoingLargeSwaRequest;
|
||||||
use Fixtures\GenerateTestRequest;
|
use Fixtures\GenerateTestRequest;
|
||||||
use PHPUnit_Framework_TestCase;
|
use PHPUnit_Framework_TestCase;
|
||||||
|
use SoapFault;
|
||||||
use SoapHeader;
|
use SoapHeader;
|
||||||
|
|
||||||
class SoapServerAndSoapClientCommunicationTest extends PHPUnit_Framework_TestCase
|
class SoapServerAndSoapClientCommunicationTest extends PHPUnit_Framework_TestCase
|
||||||
@ -124,6 +125,44 @@ class SoapServerAndSoapClientCommunicationTest extends PHPUnit_Framework_TestCas
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSoapCallSwaWithLargeSwaResponseWithSoapFault()
|
||||||
|
{
|
||||||
|
$soapClient = $this->getSoapBuilder()->buildWithSoapHeader(
|
||||||
|
SoapClientOptionsBuilder::createWithEndpointLocation(
|
||||||
|
self::TEST_HTTP_URL.'/SwaSenderSoapFaultEndpoint.php'
|
||||||
|
),
|
||||||
|
SoapOptionsBuilder::createSwaWithClassMap(
|
||||||
|
self::TEST_HTTP_URL.'/SwaSenderEndpoint.php?wsdl',
|
||||||
|
new ClassMap([
|
||||||
|
'GenerateTestRequest' => GenerateTestRequest::class,
|
||||||
|
]),
|
||||||
|
SoapOptions::SOAP_CACHE_TYPE_NONE
|
||||||
|
),
|
||||||
|
new SoapHeader('http://schema.testcase', 'SoapHeader', [
|
||||||
|
'user' => 'admin',
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->setExpectedException(SoapFault::class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$soapClient->soapCall('dummyServiceMethodWithOutgoingLargeSwa', []);
|
||||||
|
} catch (SoapFault $e) {
|
||||||
|
self::assertEquals(
|
||||||
|
'911',
|
||||||
|
$e->faultcode
|
||||||
|
);
|
||||||
|
self::assertEquals(
|
||||||
|
'SOAP HTTP call failed: Curl error "0" with message: occurred while connecting to http://localhost:8000/tests/SwaSenderSoapFaultEndpoint.php with HTTP response code 500 with Message: This is a dummy SoapFault. and Code: 911',
|
||||||
|
$e->getMessage()
|
||||||
|
);
|
||||||
|
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
self::fail('Expected SoapFault was not thrown');
|
||||||
|
}
|
||||||
|
|
||||||
public function testSoapCallWithLargeSwaRequest()
|
public function testSoapCallWithLargeSwaRequest()
|
||||||
{
|
{
|
||||||
$soapClient = $this->getSoapBuilder()->buildWithSoapHeader(
|
$soapClient = $this->getSoapBuilder()->buildWithSoapHeader(
|
||||||
|
9
tests/SwaSenderSoapFaultEndpoint.php
Normal file
9
tests/SwaSenderSoapFaultEndpoint.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
const FIXTURES_DIR = __DIR__.'/Fixtures';
|
||||||
|
|
||||||
|
$soapServer = new \SoapServer(FIXTURES_DIR.'/DummyService.wsdl');
|
||||||
|
$soapServer->fault(
|
||||||
|
911,
|
||||||
|
'This is a dummy SoapFault.'
|
||||||
|
);
|
Loading…
Reference in New Issue
Block a user