SoapFaultWithTracingData now provides request / response information from Server SoapFaults

This commit is contained in:
Petr Bechyně 2017-05-30 18:29:51 +02:00
parent 8db9b374e4
commit d495f22413
4 changed files with 262 additions and 59 deletions

View File

@ -92,7 +92,7 @@ class Curl
curl_setopt($curlSession, CURLOPT_URL, $location); curl_setopt($curlSession, CURLOPT_URL, $location);
curl_setopt($curlSession, CURLOPT_HEADER, true); curl_setopt($curlSession, CURLOPT_HEADER, true);
curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true); curl_setopt($curlSession, CURLOPT_RETURNTRANSFER, true);
if (!is_null($request)) { if ($request !== null) {
curl_setopt($curlSession, CURLOPT_POST, true); curl_setopt($curlSession, CURLOPT_POST, true);
curl_setopt($curlSession, CURLOPT_POSTFIELDS, $request); curl_setopt($curlSession, CURLOPT_POSTFIELDS, $request);
} else { } else {
@ -162,25 +162,25 @@ class Curl
if (!is_integer($httpResponseCode) || $httpResponseCode >= 400 || $httpResponseCode === 0) { if (!is_integer($httpResponseCode) || $httpResponseCode >= 400 || $httpResponseCode === 0) {
return new CurlResponse( return new CurlResponse(
$httpRequestHeadersAsString, $this->normalizeStringOrFalse($httpRequestHeadersAsString),
$httpResponseCode, $httpResponseCode,
$httpResponseMessage, $httpResponseMessage,
$httpResponseContentType, $httpResponseContentType,
self::CURL_FAILED, self::CURL_FAILED,
$responseHeaders, $this->normalizeStringOrFalse($responseHeaders),
$responseBody, $this->normalizeStringOrFalse($responseBody),
$curlErrorMessage $curlErrorMessage
); );
} }
return new CurlResponse( return new CurlResponse(
$httpRequestHeadersAsString, $this->normalizeStringOrFalse($httpRequestHeadersAsString),
$httpResponseCode, $httpResponseCode,
$httpResponseMessage, $httpResponseMessage,
$httpResponseContentType, $httpResponseContentType,
self::CURL_SUCCESS, self::CURL_SUCCESS,
$responseHeaders, $this->normalizeStringOrFalse($responseHeaders),
$responseBody $this->normalizeStringOrFalse($responseBody)
); );
} }
@ -235,4 +235,13 @@ class Curl
throw new Exception('Cannot parse WSDL url redirect: ' . $url); throw new Exception('Cannot parse WSDL url redirect: ' . $url);
} }
private function normalizeStringOrFalse($string)
{
if ($string === false || $string === '') {
$string = null;
}
return $string;
}
} }

View File

@ -316,33 +316,50 @@ class SoapClient extends \SoapClient
{ {
$soapResponse = $this->getSoapResponseFromStorage(); $soapResponse = $this->getSoapResponseFromStorage();
if ($soapResponse instanceof SoapResponse) { if ($soapResponse instanceof SoapResponse) {
$tracingData = new SoapResponseTracingData( $soapFault = $this->throwSoapFaultByTracing(
SoapFaultPrefixEnum::PREFIX_PHP . '-' . $nativePhpSoapFault->getCode(),
$nativePhpSoapFault->getMessage(),
$this->getSoapResponseTracingDataFromNativeSoapFault(
$nativePhpSoapFault,
new SoapResponseTracingData(
'Content-Type: '.$soapResponse->getRequest()->getContentType(), 'Content-Type: '.$soapResponse->getRequest()->getContentType(),
$soapResponse->getRequest()->getContent(), $soapResponse->getRequest()->getContent(),
'Content-Type: '.$soapResponse->getContentType(), 'Content-Type: '.$soapResponse->getContentType(),
$soapResponse->getResponseContent() $soapResponse->getResponseContent()
); )
$soapFault = $this->throwSoapFaultByTracing( )
SoapFaultPrefixEnum::PREFIX_PHP . '-' . $nativePhpSoapFault->getCode(),
$nativePhpSoapFault->getMessage(),
$tracingData
); );
} else { } else {
$soapFault = $this->throwSoapFaultByTracing( $soapFault = $this->throwSoapFaultByTracing(
$nativePhpSoapFault->faultcode, $nativePhpSoapFault->faultcode,
$nativePhpSoapFault->getMessage(), $nativePhpSoapFault->getMessage(),
$this->getSoapResponseTracingDataFromNativeSoapFault(
$nativePhpSoapFault,
new SoapResponseTracingData( new SoapResponseTracingData(
null, null,
null, null,
null, null,
null null
) )
)
); );
} }
return $soapFault; return $soapFault;
} }
private function getSoapResponseTracingDataFromNativeSoapFault(
SoapFault $nativePhpSoapFault,
SoapResponseTracingData $defaultSoapFaultTracingData
) {
if ($nativePhpSoapFault instanceof SoapFaultWithTracingData) {
return $nativePhpSoapFault->getSoapResponseTracingData();
}
return $defaultSoapFaultTracingData;
}
private function getHttpHeadersBySoapVersion(SoapRequest $soapRequest) private function getHttpHeadersBySoapVersion(SoapRequest $soapRequest)
{ {
if ($soapRequest->getVersion() === SOAP_1_1) { if ($soapRequest->getVersion() === SOAP_1_1) {

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\SoapBundle\Soap\SoapAttachment;
use BeSimple\SoapClient\SoapClientBuilder; use BeSimple\SoapClient\SoapClientBuilder;
use BeSimple\SoapClient\SoapClientBuilderTest;
use BeSimple\SoapClient\SoapClientOptionsBuilder; use BeSimple\SoapClient\SoapClientOptionsBuilder;
use BeSimple\SoapClient\SoapFaultWithTracingData; use BeSimple\SoapClient\SoapFaultWithTracingData;
use BeSimple\SoapCommon\ClassMap; use BeSimple\SoapCommon\ClassMap;
@ -17,7 +16,6 @@ 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
@ -25,6 +23,7 @@ class SoapServerAndSoapClientCommunicationTest extends PHPUnit_Framework_TestCas
const CACHE_DIR = __DIR__ . '/../../cache'; const CACHE_DIR = __DIR__ . '/../../cache';
const FIXTURES_DIR = __DIR__ . '/../Fixtures'; const FIXTURES_DIR = __DIR__ . '/../Fixtures';
const TEST_HTTP_URL = 'http://localhost:8000/tests'; 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'; const LARGE_SWA_FILE = self::FIXTURES_DIR.'/large-test-file.docx';
private $localWebServerProcess; 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() public function testSoapCallWithLargeSwaRequest()
{ {
$soapClient = $this->getSoapBuilder()->buildWithSoapHeader( $soapClient = $this->getSoapBuilder()->buildWithSoapHeader(