Large refactoring of SoapKernel

This commit is contained in:
Petr Bechyně 2016-11-01 18:13:23 +01:00
parent 155aa029ce
commit 969709cae5
7 changed files with 72 additions and 169 deletions

View File

@ -295,6 +295,7 @@ class SoapClient extends \SoapClient
private function configureMime(array $options)
{
// @todo: PBe: refactor same as SoapServer
if (Helper::ATTACHMENTS_TYPE_BASE64 !== $options['attachment_type']) {
// register mime filter in SoapKernel
$mimeFilter = new MimeFilter($options['attachment_type']);

View File

@ -1,34 +1,16 @@
<?php
/*
* This file is part of the BeSimpleSoapClient.
*
* (c) Christian Kerl <christian-kerl@web.de>
* (c) Francis Besset <francis.besset@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapCommon\Converter;
use BeSimple\SoapCommon\Mime\Part as MimePart;
use BeSimple\SoapCommon\SoapKernel;
use BeSimple\SoapCommon\Converter\SoapKernelAwareInterface;
use BeSimple\SoapCommon\Converter\TypeConverterInterface;
/**
* SwA type converter.
*
* @author Andreas Schamberger <mail@andreass.net>
*/
class SwaTypeConverter implements TypeConverterInterface, SoapKernelAwareInterface
class SwaTypeConverter implements TypeConverterInterface
{
/**
* @var \BeSimple\SoapCommon\SoapKernel $soapKernel SoapKernel instance
*/
protected $soapKernel = null;
/**
* {@inheritDoc}
*/
@ -60,6 +42,7 @@ class SwaTypeConverter implements TypeConverterInterface, SoapKernelAwareInterfa
if ('cid:' === substr($ref, 0, 4)) {
$contentId = urldecode(substr($ref, 4));
// @todo-critical: ci je nyni zodpovednost vygetovat attachmenty
if (null !== ($part = $this->soapKernel->getAttachment($contentId))) {
return $part->getContent();
@ -80,16 +63,9 @@ class SwaTypeConverter implements TypeConverterInterface, SoapKernelAwareInterfa
$part = new MimePart($data);
$contentId = trim($part->getHeader('Content-ID'), '<>');
$this->soapKernel->addAttachment($part);
// @todo-critical: ci je nyni zodpovednost nastrkat attachmenty
//$this->soapKernel->addAttachment($part);
return sprintf('<%s href="%s"/>', $this->getTypeName(), 'cid:' . $contentId);
}
/**
* {@inheritDoc}
*/
public function setKernel(SoapKernel $soapKernel)
{
$this->soapKernel = $soapKernel;
}
}

View File

@ -1,23 +1,8 @@
<?php
/*
* This file is part of the BeSimpleSoapCommon.
*
* (c) Christian Kerl <christian-kerl@web.de>
* (c) Francis Besset <francis.besset@gmail.com>
* (c) Andreas Schamberger <mail@andreass.net>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapCommon;
use BeSimple\SoapCommon\Mime\Part as MimePart;
use BeSimple\SoapCommon\SoapRequest;
use BeSimple\SoapCommon\SoapResponse;
use BeSimple\SoapCommon\SoapRequestFilter;
use BeSimple\SoapCommon\SoapResponseFilter;
/**
* SoapKernel provides methods to pre- and post-process SoapRequests and SoapResponses using
@ -25,30 +10,10 @@ use BeSimple\SoapCommon\SoapResponseFilter;
* the chain-of-responsibility pattern).
*
* @author Christian Kerl <christian-kerl@web.de>
* @author Petr Bechyně <petr.bechyne@vodafone.com>
*/
class SoapKernel
{
/**
* Mime attachments.
*
* @var array(\BeSimple\SoapCommon\Mime\Part)
*/
protected $attachments = array();
/**
* Request filters.
*
* @var array(SoapRequestFilter)
*/
private $requestFilters = array();
/**
* Response filters.
*
* @var array(SoapResponseFilter)
*/
private $responseFilters = array();
/**
* Add attachment.
*
@ -82,48 +47,40 @@ class SoapKernel
return null;
}
/**
* Registers the given object either as filter for SoapRequests or as filter for SoapResponses
* or as filter for both depending on the implemented interfaces. Inner filters have to be registered
* before outer filters. This means the order is as follows: RequestFilter2->RequestFilter1 and
* ResponseFilter1->ResponseFilter2.
*
* TODO: add priority mechanism to ensure correct order of filters
*
* @param SoapRequestFilter|SoapResponseFilter $filter Filter to register
*/
public function registerFilter($filter)
{
if ($filter instanceof SoapRequestFilter) {
array_unshift($this->requestFilters, $filter);
}
if ($filter instanceof SoapResponseFilter) {
array_push($this->responseFilters, $filter);
}
}
/**
* Applies all registered SoapRequestFilter to the given SoapRequest.
*
* @param SoapRequest $request Soap request
* @param SoapRequestFilter[]|SoapResponseFilter[] $filters
* @return SoapRequest
*/
public function filterRequest(SoapRequest $request)
public function filterRequest(SoapRequest $request, array $filters)
{
foreach ($this->requestFilters as $filter) {
$filter->filterRequest($request);
foreach ($filters as $filter) {
if ($filter instanceof SoapRequestFilter) {
$request = $filter->filterRequest($request);
}
}
return $request;
}
/**
* Applies all registered SoapResponseFilter to the given SoapResponse.
*
* @param SoapResponse $response SOAP response
* @param SoapRequestFilter[]|SoapResponseFilter[] $filters
* @return SoapResponse
*/
public function filterResponse(SoapResponse $response)
public function filterResponse(SoapResponse $response, array $filters)
{
foreach ($this->responseFilters as $filter) {
$filter->filterResponse($response);
foreach ($filters as $filter) {
if ($filter instanceof SoapResponseFilter) {
$response = $filter->filterResponse($response);
}
}
return $response;
}
}

View File

@ -53,25 +53,17 @@ class MimeFilter implements SoapRequestFilter, SoapResponseFilter
$this->attachmentType = Helper::ATTACHMENTS_TYPE_SWA;
}
/**
* Modify the given request XML.
*
* @param \BeSimple\SoapCommon\SoapRequest $request SOAP request
*
* @return void
*/
public function filterRequest(SoapRequest $request)
{
// array to store attachments
$attachmentsRecieved = array();
$attachmentsReceived = [];
// check content type if it is a multipart mime message
$requestContentType = $request->getContentType();
if (false !== stripos($requestContentType, 'multipart/related')) {
if (stripos($requestContentType, 'multipart/related') !== false) {
// parse mime message
$headers = array(
$headers = [
'Content-Type' => trim($requestContentType),
);
];
$multipart = MimeParser::parseMimeMessage($request->getContent(), $headers);
// get soap payload and update SoapResponse object
$soapPart = $multipart->getPart();
@ -83,29 +75,20 @@ class MimeFilter implements SoapRequestFilter, SoapResponseFilter
// store attachments
$attachments = $multipart->getParts(false);
foreach ($attachments as $cid => $attachment) {
$attachmentsRecieved[$cid] = $attachment;
$attachmentsReceived[$cid] = $attachment;
}
}
// add attachments to response object
if (count($attachmentsRecieved) > 0) {
$request->setAttachments($attachmentsRecieved);
}
if (count($attachmentsReceived) > 0) {
$request->setAttachments($attachmentsReceived);
}
return $request;
}
/**
* Modify the given response XML.
*
* @param \BeSimple\SoapCommon\SoapResponse $response SOAP response
*
* @return void
*/
public function filterResponse(SoapResponse $response)
{
// get attachments from request object
$attachmentsToSend = $response->getAttachments();
// build mime message if we have attachments
if (count($attachmentsToSend) > 0) {
$multipart = new MimeMultiPart();
$soapPart = new MimePart($response->getContent(), 'text/xml', 'utf-8', MimePart::ENCODING_EIGHT_BIT);
@ -134,5 +117,7 @@ class MimeFilter implements SoapRequestFilter, SoapResponseFilter
$response->setContentType($contentType);
}
return $response;
}
}

View File

@ -1,43 +1,32 @@
<?php
/*
* This file is part of the BeSimpleSoapCommon.
*
* (c) Christian Kerl <christian-kerl@web.de>
* (c) Francis Besset <francis.besset@gmail.com>
* (c) Andreas Schamberger <mail@andreass.net>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace BeSimple\SoapServer;
use BeSimple\SoapCommon\SoapKernel as CommonSoapKernel;
use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest;
use BeSimple\SoapCommon\SoapResponse as CommonSoapResponse;
use BeSimple\SoapCommon\SoapKernel;
use BeSimple\SoapCommon\SoapRequest;
/**
* SoapKernel for Server.
*
* @todo-critical: kill this shit
* @author Andreas Schamberger <mail@andreass.net>
*/
class SoapKernel extends CommonSoapKernel
class SoapServerKernel extends SoapKernel
{
/**
* {@inheritDoc}
*/
public function filterRequest(CommonSoapRequest $request)
public function filterRequest(SoapRequest $request, array $filters)
{
parent::filterRequest($request);
parent::filterRequest($request, $filters);
$this->attachments = $request->getAttachments();
// attachments are now gone from here
}
/**
* {@inheritDoc}
*/
public function filterResponse(CommonSoapResponse $response)
public function filterResponse(SoapResponse $response)
{
$response->setAttachments($this->attachments);
$this->attachments = array();

View File

@ -12,7 +12,7 @@
namespace BeSimple\SoapServer;
use BeSimple\SoapCommon\SoapMessage;
use BeSimple\SoapCommon\SoapKernel;
use BeSimple\SoapCommon\SoapOptions\SoapOptions;
use BeSimple\SoapCommon\SoapRequest;
use BeSimple\SoapCommon\SoapRequestFactory;
@ -34,6 +34,8 @@ class SoapServer extends \SoapServer
protected $soapVersion;
protected $soapKernel;
protected $soapServerOptions;
protected $soapOptions;
/**
* Constructor.
@ -44,11 +46,13 @@ class SoapServer extends \SoapServer
public function __construct(SoapServerOptions $soapServerOptions, SoapOptions $soapOptions)
{
if ($soapOptions->hasAttachments()) {
$soapOptions = $this->configureMime($soapOptions);
$soapOptions = $this->configureTypeConverters($soapOptions);
}
$this->soapKernel = new SoapKernel();
$this->soapVersion = $soapOptions->getSoapVersion();
$this->soapServerOptions = $soapServerOptions;
$this->soapOptions = $soapOptions;
parent::__construct(
$soapOptions->getWsdlFile(),
@ -95,8 +99,9 @@ class SoapServer extends \SoapServer
*/
private function handleSoapRequest(SoapRequest $soapRequest)
{
// run SoapKernel on SoapRequest
$this->soapKernel->filterRequest($soapRequest);
if ($this->soapOptions->hasAttachments()) {
$soapRequest = $this->soapKernel->filterRequest($soapRequest, $this->getFilters());
}
ob_start();
parent::handle($soapRequest->getContent());
@ -114,36 +119,20 @@ class SoapServer extends \SoapServer
$soapRequest->getVersion()
);
// run SoapKernel on SoapResponse
$this->soapKernel->filterResponse($soapResponse);
if ($this->soapOptions->hasAttachments()) {
$this->soapKernel->filterResponse($soapResponse, $this->getFilters());
}
return $soapResponse;
}
/**
* Get SoapKernel instance.
*
* @return \BeSimple\SoapServer\SoapKernel
*/
public function getSoapKernel()
{
return $this->soapKernel;
}
private function configureMime(SoapOptions $soapOptions)
private function configureTypeConverters(SoapOptions $soapOptions)
{
if ($soapOptions->getAttachmentType() !== SoapOptions::SOAP_ATTACHMENTS_TYPE_BASE64) {
$mimeFilter = new MimeFilter($soapOptions->getAttachmentType());
$this->soapKernel->registerFilter($mimeFilter);
if ($soapOptions->getAttachmentType() === SoapOptions::SOAP_ATTACHMENTS_TYPE_SWA) {
$converter = new SwaTypeConverter();
$converter->setKernel($this->soapKernel);
$soapOptions->getTypeConverterCollection()->add($converter);
$soapOptions->getTypeConverterCollection()->add(new SwaTypeConverter());
} elseif ($soapOptions->getAttachmentType() === SoapOptions::SOAP_ATTACHMENTS_TYPE_MTOM) {
$this->soapKernel->registerFilter(new XmlMimeFilter($soapOptions->getAttachmentType()));
$converter = new MtomTypeConverter();
$converter->setKernel($this->soapKernel);
$soapOptions->getTypeConverterCollection()->add($converter);
$soapOptions->getTypeConverterCollection()->add(new MtomTypeConverter());
} else {
throw new Exception('Unresolved SOAP_ATTACHMENTS_TYPE: ' . $soapOptions->getAttachmentType());
}
@ -151,4 +140,17 @@ class SoapServer extends \SoapServer
return $soapOptions;
}
private function getFilters()
{
$filters = [];
if ($this->soapOptions->getAttachmentType() !== SoapOptions::SOAP_ATTACHMENTS_TYPE_BASE64) {
$filters[] = new MimeFilter($this->soapOptions->getAttachmentType());
}
if ($this->soapOptions->getAttachmentType() === SoapOptions::SOAP_ATTACHMENTS_TYPE_MTOM) {
$filters[] = new XmlMimeFilter($this->soapOptions->getAttachmentType());
}
return $filters;
}
}

View File

@ -31,16 +31,8 @@ class XmlMimeFilter implements SoapResponseFilter
{
}
/**
* Modify the given response XML.
*
* @param \BeSimple\SoapCommon\SoapResponse $response SOAP request
*
* @return void
*/
public function filterResponse(SoapResponse $response)
{
// get \DOMDocument from SOAP request
$dom = $response->getContentDocument();
// create FilterHelper
@ -66,5 +58,6 @@ class XmlMimeFilter implements SoapResponseFilter
}
}
return $response;
}
}