7 Commits

Author SHA1 Message Date
cf6e147c26 Merge remote-tracking branch 'remotes/origin/develop' 2017-02-18 00:14:21 +01:00
f276a30a47 Curl/WsdlGenerator - better error handling 2017-02-18 00:13:02 +01:00
4edc46e67f Parser fix - MimeMessages with CRLF caused iconv_mime_decode throwing Exceptions 2017-02-17 15:06:06 +01:00
a76526a5b6 DEFAULT_CONNECTION_TIMEOUT default value increased to 120 2017-02-17 11:20:09 +01:00
baf32c1350 Curl is now returning response body even on error
It is better to switch off CURLOPT_FAILONERROR and check response status manually by HTTP response code
2017-02-17 11:07:26 +01:00
5c0bf914e3 Unused SoapClientNativeDataTransferObject removed 2017-02-17 03:36:16 +01:00
01d10b89fd SoapClient now handles Attachments better
The inner storage is now the only possible way to handle attachments and hydrate responses by using ClassMap at the same time. To get the response objects from ClassMap, use SoapResponse->getResponseObject() method
2017-02-17 03:19:22 +01:00
8 changed files with 97 additions and 88 deletions

View File

@ -62,7 +62,7 @@ class Curl
curl_setopt_array($curlSession, [
CURLOPT_ENCODING => '',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_FAILONERROR => true,
CURLOPT_FAILONERROR => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_HEADER => true,
@ -147,6 +147,8 @@ class Curl
$headerSize = curl_getinfo($curlSession, CURLINFO_HEADER_SIZE);
$httpResponseCode = curl_getinfo($curlSession, CURLINFO_HTTP_CODE);
$httpResponseContentType = curl_getinfo($curlSession, CURLINFO_CONTENT_TYPE);;
$responseBody = substr($executeSoapCallResponse, $headerSize);
$responseHeaders = substr($executeSoapCallResponse, 0, $headerSize);
preg_match('/HTTP\/(1\.[0-1]+) ([0-9]{3}) (.*)/', $executeSoapCallResponse, $httpResponseMessages);
$httpResponseMessage = trim(array_pop($httpResponseMessages));
$curlErrorMessage = sprintf(
@ -156,7 +158,7 @@ class Curl
$location
);
if ($executeSoapCallResponse === false) {
if (!is_integer($httpResponseCode) || $httpResponseCode >= 400 || $httpResponseCode === 0) {
return new CurlResponse(
$httpRequestHeadersAsString,
@ -164,6 +166,8 @@ class Curl
$httpResponseMessage,
$httpResponseContentType,
self::CURL_FAILED,
$responseHeaders,
$responseBody,
$curlErrorMessage
);
}
@ -174,9 +178,8 @@ class Curl
$httpResponseMessage,
$httpResponseContentType,
self::CURL_SUCCESS,
null,
substr($executeSoapCallResponse, 0, $headerSize),
substr($executeSoapCallResponse, $headerSize)
$responseHeaders,
$responseBody
);
}

View File

@ -13,7 +13,7 @@ use Exception;
class CurlOptionsBuilder
{
const DEFAULT_MAX_REDIRECTS = 10;
const DEFAULT_CONNECTION_TIMEOUT = 10;
const DEFAULT_CONNECTION_TIMEOUT = 120;
public static function buildDefault()
{

View File

@ -19,9 +19,9 @@ class CurlResponse
$httpResponseStatusMessage,
$httpResponseContentType,
$curlStatus,
$curlErrorMessage = null,
$responseHeader = null,
$responseBody = null
$responseHeader,
$responseBody,
$curlErrorMessage = null
) {
$this->httpRequestHeaders = $httpRequestHeaders;
$this->httpResponseStatusCode = $httpResponseStatusCode;
@ -78,21 +78,11 @@ class CurlResponse
return $this->curlErrorMessage;
}
public function hasResponseHeader()
{
return $this->responseHeader !== null;
}
public function getResponseHeader()
{
return $this->responseHeader;
}
public function hasResponseBody()
{
return $this->responseBody !== null;
}
public function getResponseBody()
{
return $this->responseBody;

View File

@ -41,6 +41,10 @@ class SoapClient extends \SoapClient
protected $soapClientOptions;
protected $soapOptions;
private $curl;
/** @var SoapAttachment[] */
private $soapAttachmentsOnRequestStorage;
/** @var SoapResponse */
private $soapResponseStorage;
public function __construct(SoapClientOptions $soapClientOptions, SoapOptions $soapOptions)
{
@ -54,7 +58,8 @@ class SoapClient extends \SoapClient
$wsdlPath = $this->loadWsdl(
$this->curl,
$soapOptions->getWsdlFile(),
$soapOptions->getWsdlCacheType()
$soapOptions->getWsdlCacheType(),
false
);
} catch (Exception $e) {
throw new SoapFault(
@ -88,9 +93,9 @@ class SoapClient extends \SoapClient
* @param array|null $output_headers
* @return string
*/
public function __soapCall($function_name, array $arguments, array $options = null, $input_headers = null, array &$output_headers = null)
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)->getContent();
return $this->soapCall($function_name, $arguments, $options, $input_headers, $output_headers)->getResponseContent();
}
/**
@ -104,17 +109,13 @@ class SoapClient extends \SoapClient
*/
public function soapCall($functionName, array $arguments, array $soapAttachments = [], array $options = null, $inputHeaders = null, array &$outputHeaders = null)
{
ob_start();
parent::__soapCall($functionName, $arguments, $options, $inputHeaders, $outputHeaders);
$nativeSoapClientRequest = $this->mapNativeDataJsonToDto(ob_get_clean());
$this->setSoapAttachmentsOnRequestToStorage($soapAttachments);
$soapResponseAsObject = parent::__soapCall($functionName, $arguments, $options, $inputHeaders, $outputHeaders);
return $this->performSoapRequest(
$nativeSoapClientRequest->request,
$nativeSoapClientRequest->location,
$nativeSoapClientRequest->action,
$nativeSoapClientRequest->version,
$soapAttachments
);
$soapResponse = $this->getSoapResponseFromStorage();
$soapResponse->setResponseObject($soapResponseAsObject);
return $soapResponse;
}
/**
@ -130,34 +131,16 @@ class SoapClient extends \SoapClient
*/
public function __doRequest($request, $location, $action, $version, $oneWay = 0)
{
$soapClientNativeDataTransferObject = new SoapClientNativeDataTransferObject(
$soapResponse = $this->performSoapRequest(
$request,
$location,
$action,
$version
$version,
$this->getSoapAttachmentsOnRequestFromStorage()
);
echo json_encode($soapClientNativeDataTransferObject);
$this->setSoapResponseToStorage($soapResponse);
return $request;
}
/**
* Custom request method to be able to modify the SOAP messages.
* $oneWay parameter is not used at the moment.
*
* @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
*/
public function performSoapRequest($request, $location, $action, $version, array $soapAttachments = [])
{
$soapRequest = $this->createSoapRequest($location, $action, $version, $request, $soapAttachments);
return $this->performHttpSoapRequest($soapRequest);
return $soapResponse->getResponseContent();
}
/** @deprecated */
@ -200,6 +183,25 @@ class SoapClient extends \SoapClient
);
}
/**
* Custom request method to be able to modify the SOAP messages.
* $oneWay parameter is not used at the moment.
*
* @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
*/
private function performSoapRequest($request, $location, $action, $version, array $soapAttachments = [])
{
$soapRequest = $this->createSoapRequest($location, $action, $version, $request, $soapAttachments);
return $this->performHttpSoapRequest($soapRequest);
}
/**
* @param string $location Location
* @param string $action SOAP action
@ -336,18 +338,6 @@ class SoapClient extends \SoapClient
return $filters;
}
private function mapNativeDataJsonToDto($nativeDataJson)
{
$nativeData = json_decode($nativeDataJson);
return new SoapClientNativeDataTransferObject(
$nativeData->request,
$nativeData->location,
$nativeData->action,
$nativeData->version
);
}
private function returnSoapResponseByTracing(
$isTracingEnabled,
SoapRequest $soapRequest,
@ -405,4 +395,33 @@ class SoapClient extends \SoapClient
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

@ -1,19 +0,0 @@
<?php
namespace BeSimple\SoapClient;
class SoapClientNativeDataTransferObject
{
public $request;
public $location;
public $action;
public $version;
public function __construct($request, $location, $action, $version)
{
$this->request = $request;
$this->location = $location;
$this->action = $action;
$this->version = $version;
}
}

View File

@ -6,8 +6,23 @@ use BeSimple\SoapCommon\SoapResponse as CommonSoapResponse;
class SoapResponse extends CommonSoapResponse
{
/**
* @var mixed
*/
protected $responseObject;
public function getResponseContent()
{
return $this->getContent();
}
public function getResponseObject()
{
return $this->responseObject;
}
public function setResponseObject($responseObject)
{
$this->responseObject = $responseObject;
}
}

View File

@ -75,7 +75,7 @@ class WsdlDownloader
$curlResponse = $curl->executeCurlWithCachedSession($wsdlPath);
if ($curlResponse->curlStatusSuccess()) {
if (mb_strlen($curlResponse->getResponseBody()) === 0) {
throw new Exception('Could not write WSDL cache file: curl response empty');
throw new Exception('Could not write WSDL cache file: empty curl response from: '.$wsdlPath);
}
if ($resolveRemoteIncludes === true) {
$document = $this->getXmlFileDOMDocument($curl, $cacheType, $curlResponse->getResponseBody(), $wsdlPath);

View File

@ -110,7 +110,8 @@ class Parser
}
if (strpos($currentHeader, ':') !== false) {
list($headerName, $headerValue) = explode(':', $currentHeader, 2);
$headerValue = iconv_mime_decode($headerValue, 0, Part::CHARSET_UTF8);
$headerValueWithNoCrAtTheEnd = trim($headerValue);
$headerValue = iconv_mime_decode($headerValueWithNoCrAtTheEnd, 0, Part::CHARSET_UTF8);
$parsedMimeHeaders = ContentTypeParser::parseContentTypeHeader($headerName, $headerValue);
foreach ($parsedMimeHeaders as $parsedMimeHeader) {
$currentPart->setHeader(