4 Commits

Author SHA1 Message Date
d495f22413 SoapFaultWithTracingData now provides request / response information from Server SoapFaults 2017-05-30 18:29:51 +02:00
8db9b374e4 SoapFault handling refactored: client now returns server fault codes + more details in message 2017-05-26 10:53:41 +02:00
f669c18c7f Merge pull request #3 from ceesco53/patch-1
composer.json refers to upstream not this fork (README.md fix)
2017-05-25 19:07:26 +02:00
524d1f3fd7 composer.json refers to upstream not this fork
Using the composer.json instructions as is will cause the rest of your instructions to fail.  It points to upstream package.  I've got some other changes coming soon.  Happy to help.
2017-05-25 12:13:58 -04:00
9 changed files with 571 additions and 195 deletions

View File

@ -47,7 +47,7 @@ Create a `composer.json` file:
```json
{
"require": {
"besimple/soap": "0.2.*@dev"
"tuscanicz/soap": "^4.2"
}
}
```
@ -144,4 +144,4 @@ See a simplified implementation of ``dummyServiceMethod`` to get a clue:
}
```
For further information and getting inspiration for your implementation, see the unit tests in ``tests`` dir.
For further information and getting inspiration for your implementation, see the unit tests in ``tests`` dir.

View File

@ -92,7 +92,7 @@ class Curl
curl_setopt($curlSession, CURLOPT_URL, $location);
curl_setopt($curlSession, CURLOPT_HEADER, true);
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true);
if (!is_null($request)) {
if ($request !== null) {
curl_setopt($curlSession, CURLOPT_POST, true);
curl_setopt($curlSession, CURLOPT_POSTFIELDS, $request);
} else {
@ -152,34 +152,35 @@ class Curl
preg_match('/HTTP\/(1\.[0-1]+) ([0-9]{3}) (.*)/', $executeSoapCallResponse, $httpResponseMessages);
$httpResponseMessage = trim(array_pop($httpResponseMessages));
$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_error($curlSession),
$location
$location,
$httpResponseCode
);
if (!is_integer($httpResponseCode) || $httpResponseCode >= 400 || $httpResponseCode === 0) {
return new CurlResponse(
$httpRequestHeadersAsString,
$this->normalizeStringOrFalse($httpRequestHeadersAsString),
$httpResponseCode,
$httpResponseMessage,
$httpResponseContentType,
self::CURL_FAILED,
$responseHeaders,
$responseBody,
$this->normalizeStringOrFalse($responseHeaders),
$this->normalizeStringOrFalse($responseBody),
$curlErrorMessage
);
}
return new CurlResponse(
$httpRequestHeadersAsString,
$this->normalizeStringOrFalse($httpRequestHeadersAsString),
$httpResponseCode,
$httpResponseMessage,
$httpResponseContentType,
self::CURL_SUCCESS,
$responseHeaders,
$responseBody
$this->normalizeStringOrFalse($responseHeaders),
$this->normalizeStringOrFalse($responseBody)
);
}
@ -234,4 +235,13 @@ class Curl
throw new Exception('Cannot parse WSDL url redirect: ' . $url);
}
private function normalizeStringOrFalse($string)
{
if ($string === false || $string === '') {
$string = null;
}
return $string;
}
}

View File

@ -19,6 +19,7 @@ use BeSimple\SoapClient\Curl\CurlOptionsBuilder;
use BeSimple\SoapClient\Curl\CurlResponse;
use BeSimple\SoapClient\SoapOptions\SoapClientOptions;
use BeSimple\SoapCommon\Fault\SoapFaultEnum;
use BeSimple\SoapCommon\Fault\SoapFaultParser;
use BeSimple\SoapCommon\Fault\SoapFaultPrefixEnum;
use BeSimple\SoapCommon\Fault\SoapFaultSourceGetter;
use BeSimple\SoapCommon\Mime\PartFactory;
@ -40,16 +41,14 @@ use SoapFault;
*/
class SoapClient extends \SoapClient
{
use SoapClientNativeMethodsTrait;
/** @var SoapClientOptions */
protected $soapClientOptions;
/** @var SoapOptions */
protected $soapOptions;
/** @var Curl */
private $curl;
/** @var SoapAttachment[] */
private $soapAttachmentsOnRequestStorage;
/** @var SoapResponse */
private $soapResponseStorage;
public function __construct(SoapClientOptions $soapClientOptions, SoapOptions $soapOptions)
{
@ -76,33 +75,6 @@ class SoapClient extends \SoapClient
@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 array $arguments
@ -125,95 +97,13 @@ class SoapClient extends \SoapClient
} catch (SoapFault $soapFault) {
if (SoapFaultSourceGetter::isNativeSoapFault($soapFault)) {
$soapResponse = $this->getSoapResponseFromStorage();
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()
);
}
$soapFault = $this->decorateNativeSoapFault($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.
* $oneWay parameter is not used at the moment.
@ -226,7 +116,7 @@ class SoapClient extends \SoapClient
*
* @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);
@ -273,22 +163,10 @@ class SoapClient extends \SoapClient
*/
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(
$soapRequest->getLocation(),
$soapRequest->getContent(),
$headers
$this->getHttpHeadersBySoapVersion($soapRequest)
);
$soapResponseTracingData = new SoapResponseTracingData(
$curlResponse->getHttpRequestHeaders(),
@ -310,26 +188,42 @@ class SoapClient extends \SoapClient
$this->getAttachmentFilters(),
$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(
SoapFaultEnum::SOAP_FAULT_HTTP.'-'.$curlResponse->getHttpResponseStatusCode(),
$curlResponse->getCurlErrorMessage(),
$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,
$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,76 @@ class SoapClient extends \SoapClient
$soapFaultMessage,
$soapResponseTracingData
);
}
throw new SoapFault(
$soapFaultCode,
$soapFaultMessage
);
}
private function decorateNativeSoapFault(SoapFault $nativePhpSoapFault)
{
$soapResponse = $this->getSoapResponseFromStorage();
if ($soapResponse instanceof SoapResponse) {
$soapFault = $this->throwSoapFaultByTracing(
SoapFaultPrefixEnum::PREFIX_PHP . '-' . $nativePhpSoapFault->getCode(),
$nativePhpSoapFault->getMessage(),
$this->getSoapResponseTracingDataFromNativeSoapFault(
$nativePhpSoapFault,
new SoapResponseTracingData(
'Content-Type: '.$soapResponse->getRequest()->getContentType(),
$soapResponse->getRequest()->getContent(),
'Content-Type: '.$soapResponse->getContentType(),
$soapResponse->getResponseContent()
)
)
);
} else {
throw new SoapFault(
$soapFaultCode,
$soapFaultMessage
$soapFault = $this->throwSoapFaultByTracing(
$nativePhpSoapFault->faultcode,
$nativePhpSoapFault->getMessage(),
$this->getSoapResponseTracingDataFromNativeSoapFault(
$nativePhpSoapFault,
new SoapResponseTracingData(
null,
null,
null,
null
)
)
);
}
return $soapFault;
}
private function checkTracing()
{
if ($this->soapClientOptions->getTrace() === false) {
throw new Exception('SoapClientOptions tracing disabled, turn on trace attribute');
private function getSoapResponseTracingDataFromNativeSoapFault(
SoapFault $nativePhpSoapFault,
SoapResponseTracingData $defaultSoapFaultTracingData
) {
if ($nativePhpSoapFault instanceof SoapFaultWithTracingData) {
return $nativePhpSoapFault->getSoapResponseTracingData();
}
return $defaultSoapFaultTracingData;
}
private function setSoapResponseToStorage(SoapResponse $soapResponseStorage)
private function getHttpHeadersBySoapVersion(SoapRequest $soapRequest)
{
$this->soapResponseStorage = $soapResponseStorage;
}
if ($soapRequest->getVersion() === SOAP_1_1) {
/**
* @param SoapAttachment[] $soapAttachments
*/
private function setSoapAttachmentsOnRequestToStorage(array $soapAttachments)
{
$this->soapAttachmentsOnRequestStorage = $soapAttachments;
}
return [
'Content-Type: ' . $soapRequest->getContentType(),
'SOAPAction: "' . $soapRequest->getAction() . '"',
'Connection: ' . ($this->soapOptions->isConnectionKeepAlive() ? 'Keep-Alive' : 'close'),
];
}
private function getSoapAttachmentsOnRequestFromStorage()
{
$soapAttachmentsOnRequest = $this->soapAttachmentsOnRequestStorage;
$this->soapAttachmentsOnRequestStorage = null;
return $soapAttachmentsOnRequest;
}
private function getSoapResponseFromStorage()
{
$soapResponse = $this->soapResponseStorage;
$this->soapResponseStorage = null;
return $soapResponse;
return [
'Content-Type: ' . $soapRequest->getContentType() . '; action="' . $soapRequest->getAction() . '"',
'Connection: ' . ($this->soapOptions->isConnectionKeepAlive() ? 'Keep-Alive' : 'close'),
];
}
}

View 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;
}
}

View 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]
);
}
}

View 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()
);
}
}

View File

@ -0,0 +1,216 @@
<?php
namespace BeSimple;
use BeSimple\SoapClient\SoapClientBuilder;
use BeSimple\SoapClient\SoapClientOptionsBuilder;
use BeSimple\SoapClient\SoapFaultWithTracingData;
use BeSimple\SoapCommon\ClassMap;
use BeSimple\SoapCommon\SoapOptions\SoapOptions;
use BeSimple\SoapCommon\SoapOptionsBuilder;
use BeSimple\SoapServer\SoapServerBuilder;
use Fixtures\GenerateTestRequest;
use PHPUnit_Framework_TestCase;
use SoapFault;
use SoapHeader;
class SoapServerAndSoapClientCommunicationSoapFaultsTest extends PHPUnit_Framework_TestCase
{
const CACHE_DIR = __DIR__ . '/../../cache';
const FIXTURES_DIR = __DIR__ . '/../Fixtures';
const TEST_HTTP_URL = 'http://localhost:8000/tests';
const TEST_HTTP_URL_INVALID = 'http://nosuchserverexists1234.com:9911';
const LARGE_SWA_FILE = self::FIXTURES_DIR.'/large-test-file.docx';
private $localWebServerProcess;
public function setUp()
{
$this->localWebServerProcess = popen('php -S localhost:8000 > /dev/null 2>&1 &', 'r');
}
public function tearDown()
{
pclose($this->localWebServerProcess);
}
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::assertInstanceOf(
SoapFaultWithTracingData::class,
$e
);
/** @var SoapFaultWithTracingData $e */
self::assertEquals(
'911',
$e->faultcode
);
self::assertContains(
'with HTTP response code 500 with Message: This is a dummy SoapFault. and Code: 911',
$e->getMessage()
);
self::assertContains(
'<faultcode>911</faultcode>',
$e->getSoapResponseTracingData()->getLastResponse()
);
self::assertContains(
'<request/>',
$e->getSoapResponseTracingData()->getLastRequest()
);
self::assertContains(
'Content-Type: application/soap+xml; charset=utf-8; action="DummyService.dummyServiceMethodWithOutgoingLargeSwa"',
$e->getSoapResponseTracingData()->getLastRequestHeaders()
);
throw $e;
}
self::fail('Expected SoapFault was not thrown');
}
public function testSoapCallSwaWithLargeSwaResponseWithNoResponseFromEndpoint()
{
$soapClient = $this->getSoapBuilder()->buildWithSoapHeader(
SoapClientOptionsBuilder::createWithEndpointLocation(
self::TEST_HTTP_URL.'/NoSuchEndpointExists'
),
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::assertInstanceOf(
SoapFaultWithTracingData::class,
$e
);
/** @var SoapFaultWithTracingData $e */
self::assertEquals(
'be-http-404',
$e->faultcode
);
self::assertContains(
'with HTTP response code 404',
$e->getMessage()
);
self::assertContains(
'not found',
$e->getSoapResponseTracingData()->getLastResponse()
);
self::assertContains(
'404 Not Found',
$e->getSoapResponseTracingData()->getLastResponseHeaders()
);
self::assertContains(
'<request/>',
$e->getSoapResponseTracingData()->getLastRequest()
);
self::assertContains(
'Content-Type: application/soap+xml; charset=utf-8; action="DummyService.dummyServiceMethodWithOutgoingLargeSwa"',
$e->getSoapResponseTracingData()->getLastRequestHeaders()
);
throw $e;
}
self::fail('Expected SoapFault was not thrown');
}
public function testSoapCallSwaWithLargeSwaResponseWithNoResponseFromEndpointHost()
{
$soapClient = $this->getSoapBuilder()->buildWithSoapHeader(
SoapClientOptionsBuilder::createWithEndpointLocation(
self::TEST_HTTP_URL_INVALID.'/NoSuchEndpointExists'
),
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::assertInstanceOf(
SoapFaultWithTracingData::class,
$e
);
/** @var SoapFaultWithTracingData $e */
self::assertEquals(
'be-http-0',
$e->faultcode
);
self::assertContains(
'Could not resolve host',
$e->getMessage()
);
self::assertNull(
$e->getSoapResponseTracingData()->getLastResponseHeaders()
);
self::assertNull(
$e->getSoapResponseTracingData()->getLastResponse()
);
self::assertContains(
'<request/>',
$e->getSoapResponseTracingData()->getLastRequest()
);
self::assertNull(
$e->getSoapResponseTracingData()->getLastRequestHeaders()
);
throw $e;
}
self::fail('Expected SoapFault was not thrown');
}
private function getSoapBuilder()
{
return new SoapClientBuilder();
}
public function getSoapServerBuilder()
{
return new SoapServerBuilder();
}
}

View File

@ -4,7 +4,6 @@ namespace BeSimple;
use BeSimple\SoapBundle\Soap\SoapAttachment;
use BeSimple\SoapClient\SoapClientBuilder;
use BeSimple\SoapClient\SoapClientBuilderTest;
use BeSimple\SoapClient\SoapClientOptionsBuilder;
use BeSimple\SoapClient\SoapFaultWithTracingData;
use BeSimple\SoapCommon\ClassMap;
@ -24,6 +23,7 @@ class SoapServerAndSoapClientCommunicationTest extends PHPUnit_Framework_TestCas
const CACHE_DIR = __DIR__ . '/../../cache';
const FIXTURES_DIR = __DIR__ . '/../Fixtures';
const TEST_HTTP_URL = 'http://localhost:8000/tests';
const TEST_HTTP_URL_INVALID = 'http://nosuchserverexists1234.com:9911';
const LARGE_SWA_FILE = self::FIXTURES_DIR.'/large-test-file.docx';
private $localWebServerProcess;

View 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.'
);