From d495f224130062584ac5200bb0044cb16cf677f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Bechyn=C4=9B?= Date: Tue, 30 May 2017 18:29:51 +0200 Subject: [PATCH] SoapFaultWithTracingData now provides request / response information from Server SoapFaults --- src/BeSimple/SoapClient/Curl/Curl.php | 23 +- src/BeSimple/SoapClient/SoapClient.php | 41 +++- ...dSoapClientCommunicationSoapFaultsTest.php | 216 ++++++++++++++++++ ...apServerAndSoapClientCommunicationTest.php | 41 +--- 4 files changed, 262 insertions(+), 59 deletions(-) create mode 100644 tests/BeSimple/SoapServerAndSoapClientCommunicationSoapFaultsTest.php diff --git a/src/BeSimple/SoapClient/Curl/Curl.php b/src/BeSimple/SoapClient/Curl/Curl.php index 8048832..dab5243 100644 --- a/src/BeSimple/SoapClient/Curl/Curl.php +++ b/src/BeSimple/SoapClient/Curl/Curl.php @@ -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 { @@ -162,25 +162,25 @@ class Curl 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) ); } @@ -235,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; + } } diff --git a/src/BeSimple/SoapClient/SoapClient.php b/src/BeSimple/SoapClient/SoapClient.php index 2ecd385..4683cb0 100644 --- a/src/BeSimple/SoapClient/SoapClient.php +++ b/src/BeSimple/SoapClient/SoapClient.php @@ -316,26 +316,31 @@ class SoapClient extends \SoapClient { $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 + $this->getSoapResponseTracingDataFromNativeSoapFault( + $nativePhpSoapFault, + new SoapResponseTracingData( + 'Content-Type: '.$soapResponse->getRequest()->getContentType(), + $soapResponse->getRequest()->getContent(), + 'Content-Type: '.$soapResponse->getContentType(), + $soapResponse->getResponseContent() + ) + ) ); } else { $soapFault = $this->throwSoapFaultByTracing( $nativePhpSoapFault->faultcode, $nativePhpSoapFault->getMessage(), - new SoapResponseTracingData( - null, - null, - null, - null + $this->getSoapResponseTracingDataFromNativeSoapFault( + $nativePhpSoapFault, + new SoapResponseTracingData( + null, + null, + null, + null + ) ) ); } @@ -343,6 +348,18 @@ class SoapClient extends \SoapClient return $soapFault; } + private function getSoapResponseTracingDataFromNativeSoapFault( + SoapFault $nativePhpSoapFault, + SoapResponseTracingData $defaultSoapFaultTracingData + ) { + if ($nativePhpSoapFault instanceof SoapFaultWithTracingData) { + + return $nativePhpSoapFault->getSoapResponseTracingData(); + } + + return $defaultSoapFaultTracingData; + } + private function getHttpHeadersBySoapVersion(SoapRequest $soapRequest) { if ($soapRequest->getVersion() === SOAP_1_1) { diff --git a/tests/BeSimple/SoapServerAndSoapClientCommunicationSoapFaultsTest.php b/tests/BeSimple/SoapServerAndSoapClientCommunicationSoapFaultsTest.php new file mode 100644 index 0000000..f5366ff --- /dev/null +++ b/tests/BeSimple/SoapServerAndSoapClientCommunicationSoapFaultsTest.php @@ -0,0 +1,216 @@ +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( + '911', + $e->getSoapResponseTracingData()->getLastResponse() + ); + self::assertContains( + '', + $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( + '', + $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( + '', + $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(); + } +} diff --git a/tests/BeSimple/SoapServerAndSoapClientCommunicationTest.php b/tests/BeSimple/SoapServerAndSoapClientCommunicationTest.php index 7dbff0b..ee55c01 100644 --- a/tests/BeSimple/SoapServerAndSoapClientCommunicationTest.php +++ b/tests/BeSimple/SoapServerAndSoapClientCommunicationTest.php @@ -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; @@ -17,7 +16,6 @@ use Fixtures\DummyServiceMethodWithIncomingLargeSwaRequest; use Fixtures\DummyServiceMethodWithOutgoingLargeSwaRequest; use Fixtures\GenerateTestRequest; use PHPUnit_Framework_TestCase; -use SoapFault; use SoapHeader; class SoapServerAndSoapClientCommunicationTest extends PHPUnit_Framework_TestCase @@ -25,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; @@ -125,44 +124,6 @@ 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() { $soapClient = $this->getSoapBuilder()->buildWithSoapHeader(