diff --git a/src/BeSimple/SoapServer/.gitignore b/src/BeSimple/SoapServer/.gitignore
new file mode 100644
index 0000000..f8d178e
--- /dev/null
+++ b/src/BeSimple/SoapServer/.gitignore
@@ -0,0 +1,5 @@
+vendor
+/phpunit.xml
+.buildpath
+.project
+.settings
\ No newline at end of file
diff --git a/src/BeSimple/SoapServer/composer.json b/src/BeSimple/SoapServer/composer.json
new file mode 100644
index 0000000..5a19a6e
--- /dev/null
+++ b/src/BeSimple/SoapServer/composer.json
@@ -0,0 +1,32 @@
+{
+ "name": "besimple/soap-server",
+ "type": "library",
+ "description": "Build and consume SOAP Server based web services",
+ "keywords": [ "soap", "soap-server" ],
+ "homepage": "https://github.com/BeSimple/BeSimpleSoapServer",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Francis Besset",
+ "email": "francis.besset@gmail.com"
+ },
+ {
+ "name": "Christian Kerl",
+ "email": "christian-kerl@web.de"
+ },
+ {
+ "name": "Andreas Schamberger",
+ "email": "mail@andreass.net"
+ }
+ ],
+ "require": {
+ "php": ">=5.3.0",
+ "besimple/soap-common": "dev-master"
+ },
+ "autoload": {
+ "psr-0": {
+ "BeSimple\\SoapServer": "BeSimple/SoapServer/src/"
+ }
+ },
+ "target-dir": "BeSimple/SoapServer"
+}
diff --git a/src/BeSimple/SoapServer/phpunit.xml.dist b/src/BeSimple/SoapServer/phpunit.xml.dist
new file mode 100644
index 0000000..6b95145
--- /dev/null
+++ b/src/BeSimple/SoapServer/phpunit.xml.dist
@@ -0,0 +1,31 @@
+
+
+
+
+
+ ./tests/BeSimple/
+
+
+
+
+
+ benchmark
+
+
+
+
+
+ ./src/BeSimple/
+
+
+
diff --git a/src/BeSimple/SoapServer/src/BeSimple/SoapServer/MimeFilter.php b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/MimeFilter.php
new file mode 100644
index 0000000..84f16ba
--- /dev/null
+++ b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/MimeFilter.php
@@ -0,0 +1,138 @@
+
+ * (c) Francis Besset
+ *
+ * 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\Helper;
+use BeSimple\SoapCommon\Mime\MultiPart as MimeMultiPart;
+use BeSimple\SoapCommon\Mime\Parser as MimeParser;
+use BeSimple\SoapCommon\Mime\Part as MimePart;
+use BeSimple\SoapCommon\SoapRequest;
+use BeSimple\SoapCommon\SoapRequestFilter;
+use BeSimple\SoapCommon\SoapResponse;
+use BeSimple\SoapCommon\SoapResponseFilter;
+
+/**
+ * MIME filter.
+ *
+ * @author Andreas Schamberger
+ */
+class MimeFilter implements SoapRequestFilter, SoapResponseFilter
+{
+ /**
+ * Attachment type.
+ *
+ * @var int Helper::ATTACHMENTS_TYPE_SWA | Helper::ATTACHMENTS_TYPE_MTOM
+ */
+ protected $attachmentType = Helper::ATTACHMENTS_TYPE_SWA;
+
+ /**
+ * Constructor.
+ *
+ * @param int $attachmentType Helper::ATTACHMENTS_TYPE_SWA | Helper::ATTACHMENTS_TYPE_MTOM
+ */
+ public function __construct($attachmentType)
+ {
+ $this->attachmentType = $attachmentType;
+ }
+
+ /**
+ * Reset all properties to default values.
+ */
+ public function resetFilter()
+ {
+ $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();
+
+ // check content type if it is a multipart mime message
+ $requestContentType = $request->getContentType();
+ if (false !== stripos($requestContentType, 'multipart/related')) {
+ // parse mime message
+ $headers = array(
+ 'Content-Type' => trim($requestContentType),
+ );
+ $multipart = MimeParser::parseMimeMessage($request->getContent(), $headers);
+ // get soap payload and update SoapResponse object
+ $soapPart = $multipart->getPart();
+ // convert href -> myhref for external references as PHP throws exception in this case
+ // http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/ext/soap/php_encoding.c?view=markup#l3436
+ $content = preg_replace('/href=(?!#)/', 'myhref=', $soapPart->getContent());
+ $request->setContent($content);
+ $request->setContentType($soapPart->getHeader('Content-Type'));
+ // store attachments
+ $attachments = $multipart->getParts(false);
+ foreach ($attachments as $cid => $attachment) {
+ $attachmentsRecieved[$cid] = $attachment;
+ }
+ }
+
+ // add attachments to response object
+ if (count($attachmentsRecieved) > 0) {
+ $request->setAttachments($attachmentsRecieved);
+ }
+ }
+
+ /**
+ * 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);
+ $soapVersion = $response->getVersion();
+ // change content type headers for MTOM with SOAP 1.1
+ if ($soapVersion == SOAP_1_1 && $this->attachmentType & Helper::ATTACHMENTS_TYPE_MTOM) {
+ $multipart->setHeader('Content-Type', 'type', 'application/xop+xml');
+ $multipart->setHeader('Content-Type', 'start-info', 'text/xml');
+ $soapPart->setHeader('Content-Type', 'application/xop+xml');
+ $soapPart->setHeader('Content-Type', 'type', 'text/xml');
+ }
+ // change content type headers for SOAP 1.2
+ elseif ($soapVersion == SOAP_1_2) {
+ $multipart->setHeader('Content-Type', 'type', 'application/soap+xml');
+ $soapPart->setHeader('Content-Type', 'application/soap+xml');
+ }
+ $multipart->addPart($soapPart, true);
+ foreach ($attachmentsToSend as $cid => $attachment) {
+ $multipart->addPart($attachment, false);
+ }
+ $response->setContent($multipart->getMimeMessage());
+
+ // TODO
+ $headers = $multipart->getHeadersForHttp();
+ list($name, $contentType) = explode(': ', $headers[0]);
+
+ $response->setContentType($contentType);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapKernel.php b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapKernel.php
new file mode 100644
index 0000000..a928738
--- /dev/null
+++ b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapKernel.php
@@ -0,0 +1,47 @@
+
+ * (c) Francis Besset
+ * (c) Andreas Schamberger
+ *
+ * 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;
+use BeSimple\SoapCommon\SoapResponse;
+
+/**
+ * SoapKernel for Server.
+ *
+ * @author Andreas Schamberger
+ */
+class SoapKernel extends CommonSoapKernel
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function filterRequest(SoapRequest $request)
+ {
+ parent::filterRequest($request);
+
+ $this->attachments = $request->getAttachments();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function filterResponse(SoapResponse $response)
+ {
+ $response->setAttachments($this->attachments);
+ $this->attachments = array();
+
+ parent::filterResponse($response);
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapRequest.php b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapRequest.php
new file mode 100644
index 0000000..8a03d7a
--- /dev/null
+++ b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapRequest.php
@@ -0,0 +1,71 @@
+
+ * (c) Francis Besset
+ *
+ * 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\SoapRequest as CommonSoapRequest;
+use BeSimple\SoapCommon\SoapMessage;
+
+/**
+ * SoapRequest class for SoapClient. Provides factory function for request object.
+ *
+ * @author Andreas Schamberger
+ */
+class SoapRequest extends CommonSoapRequest
+{
+ /**
+ * Factory function for SoapRequest.
+ *
+ * @param string $content Content
+ * @param string $version SOAP version
+ *
+ * @return BeSimple\SoapClient\SoapRequest
+ */
+ public static function create($content, $version)
+ {
+ $content = is_null($content) ? file_get_contents("php://input") : $content;
+ $location = self::getCurrentUrl();
+ $action = $_SERVER[SoapMessage::SOAP_ACTION_HEADER];
+ $contentType = $_SERVER[SoapMessage::CONTENT_TYPE_HEADER];
+
+ $request = new SoapRequest();
+ // $content is if unmodified from SoapClient not a php string type!
+ $request->setContent((string) $content);
+ $request->setLocation($location);
+ $request->setAction($action);
+ $request->setVersion($version);
+ $request->setContentType($contentType);
+
+ return $request;
+ }
+
+ /**
+ * Builds the current URL from the $_SERVER array.
+ *
+ * @return string
+ */
+ public static function getCurrentUrl()
+ {
+ $url = '';
+ if (isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) === 'on' || $_SERVER['HTTPS'] === '1')) {
+ $url .= 'https://';
+ } else {
+ $url .= 'http://';
+ }
+ $url .= isset( $_SERVER['SERVER_NAME'] ) ? $_SERVER['SERVER_NAME'] : '';
+ if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] != 80) {
+ $url .= ":{$_SERVER['SERVER_PORT']}";
+ }
+ $url .= isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
+ return $url;
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapResponse.php b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapResponse.php
new file mode 100644
index 0000000..e624fcb
--- /dev/null
+++ b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapResponse.php
@@ -0,0 +1,62 @@
+
+ * (c) Francis Besset
+ *
+ * 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\SoapResponse as CommonSoapResponse;
+use BeSimple\SoapCommon\SoapMessage;
+
+/**
+ * SoapResponse class for SoapClient. Provides factory function for response object.
+ *
+ * @author Andreas Schamberger
+ */
+class SoapResponse extends CommonSoapResponse
+{
+ /**
+ * Factory function for SoapResponse.
+ *
+ * @param string $content Content
+ * @param string $location Location
+ * @param string $action SOAP action
+ * @param string $version SOAP version
+ *
+ * @return BeSimple\SoapClient\SoapResponse
+ */
+ public static function create($content, $location, $action, $version)
+ {
+ $response = new SoapResponse();
+ $response->setContent($content);
+ $response->setLocation($location);
+ $response->setAction($action);
+ $response->setVersion($version);
+ $contentType = SoapMessage::getContentTypeForVersion($version);
+ $response->setContentType($contentType);
+
+ return $response;
+ }
+
+ /**
+ * Send SOAP response to client.
+ */
+ public function send()
+ {
+ // set Content-Type header
+ header('Content-Type: ' . $this->getContentType());
+ // get content to send
+ $response = $this->getContent();
+ // set Content-Length header
+ header('Content-Length: '. strlen($response));
+ // send response to client
+ echo $response;
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapServer.php b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapServer.php
new file mode 100644
index 0000000..ced2ad0
--- /dev/null
+++ b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapServer.php
@@ -0,0 +1,161 @@
+
+ * (c) Francis Besset
+ *
+ * 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\Helper;
+use BeSimple\SoapCommon\Converter\MtomTypeConverter;
+use BeSimple\SoapCommon\Converter\SwaTypeConverter;
+
+/**
+ * Extended SoapServer that allows adding filters for SwA, MTOM, ... .
+ *
+ * @author Andreas Schamberger
+ * @author Christian Kerl
+ */
+class SoapServer extends \SoapServer
+{
+ /**
+ * Soap version.
+ *
+ * @var int
+ */
+ protected $soapVersion = SOAP_1_1;
+
+ /**
+ * Soap kernel.
+ *
+ * @var \BeSimple\SoapServer\SoapKernel
+ */
+ protected $soapKernel = null;
+
+ /**
+ * Constructor.
+ *
+ * @param string $wsdl WSDL file
+ * @param array(string=>mixed) $options Options array
+ */
+ public function __construct($wsdl, array $options = array())
+ {
+ // store SOAP version
+ if (isset($options['soap_version'])) {
+ $this->soapVersion = $options['soap_version'];
+ }
+ // create soap kernel instance
+ $this->soapKernel = new SoapKernel();
+ // set up type converter and mime filter
+ $this->configureMime($options);
+ // we want the exceptions option to be set
+ $options['exceptions'] = true;
+ parent::__construct($wsdl, $options);
+ }
+
+ /**
+ * Custom handle method to be able to modify the SOAP messages.
+ *
+ * @param string $request Request string
+ */
+ public function handle($request = null)
+ {
+ // wrap request data in SoapRequest object
+ $soapRequest = SoapRequest::create($request, $this->soapVersion);
+
+ // handle actual SOAP request
+ $soapResponse = $this->handle2($soapRequest);
+
+ // send SOAP response to client
+ $soapResponse->send();
+ }
+
+ /**
+ * Runs the currently registered request filters on the request, calls the
+ * necessary functions (through the parent's class handle()) and runs the
+ * response filters.
+ *
+ * @param SoapRequest $soapRequest SOAP request object
+ *
+ * @return SoapResponse
+ */
+ public function handle2(SoapRequest $soapRequest)
+ {
+ // run SoapKernel on SoapRequest
+ $this->soapKernel->filterRequest($soapRequest);
+
+ // call parent \SoapServer->handle() and buffer output
+ ob_start();
+ parent::handle($soapRequest->getContent());
+ $response = ob_get_clean();
+
+ // wrap response data in SoapResponse object
+ $soapResponse = SoapResponse::create(
+ $response,
+ $soapRequest->getLocation(),
+ $soapRequest->getAction(),
+ $soapRequest->getVersion()
+ );
+
+ // run SoapKernel on SoapResponse
+ $this->soapKernel->filterResponse($soapResponse);
+
+ return $soapResponse;
+ }
+
+ /**
+ * Get SoapKernel instance.
+ *
+ * @return \BeSimple\SoapServer\SoapKernel
+ */
+ public function getSoapKernel()
+ {
+ return $this->soapKernel;
+ }
+
+ /**
+ * Configure filter and type converter for SwA/MTOM.
+ *
+ * @param array &$options SOAP constructor options array.
+ *
+ * @return void
+ */
+ private function configureMime(array &$options)
+ {
+ if (isset($options['attachment_type']) && Helper::ATTACHMENTS_TYPE_BASE64 !== $options['attachment_type']) {
+ // register mime filter in SoapKernel
+ $mimeFilter = new MimeFilter($options['attachment_type']);
+ $this->soapKernel->registerFilter($mimeFilter);
+ // configure type converter
+ if (Helper::ATTACHMENTS_TYPE_SWA === $options['attachment_type']) {
+ $converter = new SwaTypeConverter();
+ $converter->setKernel($this->soapKernel);
+ } elseif (Helper::ATTACHMENTS_TYPE_MTOM === $options['attachment_type']) {
+ $xmlMimeFilter = new XmlMimeFilter($options['attachment_type']);
+ $this->soapKernel->registerFilter($xmlMimeFilter);
+ $converter = new MtomTypeConverter();
+ $converter->setKernel($this->soapKernel);
+ }
+ // configure typemap
+ if (!isset($options['typemap'])) {
+ $options['typemap'] = array();
+ }
+ $options['typemap'][] = array(
+ 'type_name' => $converter->getTypeName(),
+ 'type_ns' => $converter->getTypeNamespace(),
+ 'from_xml' => function($input) use ($converter) {
+ return $converter->convertXmlToPhp($input);
+ },
+ 'to_xml' => function($input) use ($converter) {
+ return $converter->convertPhpToXml($input);
+ },
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapServerBuilder.php b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapServerBuilder.php
new file mode 100644
index 0000000..365c812
--- /dev/null
+++ b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/SoapServerBuilder.php
@@ -0,0 +1,200 @@
+
+ * (c) Francis Besset
+ *
+ * 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\AbstractSoapBuilder;
+use BeSimple\SoapCommon\Helper;
+
+/**
+ * SoapServerBuilder provides a fluent interface to configure and create a SoapServer instance.
+ *
+ * @author Christian Kerl
+ */
+class SoapServerBuilder extends AbstractSoapBuilder
+{
+ protected $persistence;
+ protected $errorReporting;
+
+ protected $handlerClass;
+ protected $handlerObject;
+
+ /**
+ * Create new instance with default options.
+ *
+ * @return \BeSimple\SoapServer\SoapServerBuilder
+ */
+ static public function createWithDefaults()
+ {
+ return parent::createWithDefaults()
+ ->withErrorReporting(false);
+ }
+
+ /**
+ * Initializes all options with the defaults used in the native SoapServer.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ // TODO: this is not the default, but safer
+ $this->withErrorReporting(false);
+ }
+
+ /**
+ * Finally returns a SoapClient instance.
+ *
+ * @return \BeSimple\SoapServer\SoapServer
+ */
+ public function build()
+ {
+ $this->validateOptions();
+
+ use_soap_error_handler($this->errorReporting);
+
+ $server = new SoapServer($this->wsdl, $this->getSoapOptions());
+
+ if (null !== $this->persistence) {
+ $server->setPersistence($this->persistence);
+ }
+
+ if (null !== $this->handlerClass) {
+ $server->setClass($this->handlerClass);
+ } elseif (null !== $this->handlerObject) {
+ $server->setObject($this->handlerObject);
+ }
+
+ return $server;
+ }
+
+ /**
+ * Cofigures the SOAP actor.
+ *
+ * @param string $actor Actor name
+ *
+ * @return \BeSimple\SoapServer\SoapServerBuilder
+ */
+ public function withActor($actor)
+ {
+ $this->options['actor'] = $actor;
+
+ return $this;
+ }
+
+ /**
+ * Enables persistence.
+ *
+ * @return \BeSimple\SoapServer\SoapServerBuilder
+ */
+ public function withPersistanceRequest()
+ {
+ $this->persistence = SOAP_PERSISTENCE_REQUEST;
+
+ return $this;
+ }
+
+ /**
+ * Enables the HTTP session. The handler object is persisted between multiple requests in a session.
+ *
+ * @return \BeSimple\SoapServer\SoapServerBuilder
+ */
+ public function withPersistenceSession()
+ {
+ $this->persistence = SOAP_PERSISTENCE_SESSION;
+
+ return $this;
+ }
+
+ /**
+ * Enables reporting of internal errors to clients. This should only be enabled in development environments.
+ *
+ * @param boolean $enable Enable error reporting
+ *
+ * @return \BeSimple\SoapServer\SoapServerBuilder
+ */
+ public function withErrorReporting($enable = true)
+ {
+ $this->errorReporting = $enable;
+
+ return $this;
+ }
+
+ /**
+ * SOAP attachment type Base64.
+ *
+ * @return \BeSimple\SoapServer\SoapServerBuilder
+ */
+ public function withBase64Attachments()
+ {
+ $this->options['attachment_type'] = Helper::ATTACHMENTS_TYPE_BASE64;
+
+ return $this;
+ }
+
+ /**
+ * SOAP attachment type SwA.
+ *
+ * @return \BeSimple\SoapServer\SoapServerBuilder
+ */
+ public function withSwaAttachments()
+ {
+ $this->options['attachment_type'] = Helper::ATTACHMENTS_TYPE_SWA;
+
+ return $this;
+ }
+
+ /**
+ * SOAP attachment type MTOM.
+ *
+ * @return \BeSimple\SoapServer\SoapServerBuilder
+ */
+ public function withMtomAttachments()
+ {
+ $this->options['attachment_type'] = Helper::ATTACHMENTS_TYPE_MTOM;
+
+ return $this;
+ }
+
+ /**
+ * Configures the handler class or object.
+ *
+ * @param mixed $handler Can be either a class name or an object.
+ *
+ * @return \BeSimple\SoapServer\SoapServerBuilder
+ */
+ public function withHandler($handler)
+ {
+ if (is_string($handler) && class_exists($handler)) {
+ $this->handlerClass = $handler;
+ $this->handlerObject = null;
+ } elseif (is_object($handler)) {
+ $this->handlerClass = null;
+ $this->handlerObject = $handler;
+ } else {
+ throw new \InvalidArgumentException('The handler has to be a class name or an object');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Validate options.
+ */
+ protected function validateOptions()
+ {
+ $this->validateWsdl();
+
+ if (null === $this->handlerClass && null === $this->handlerObject) {
+ throw new \InvalidArgumentException('The handler has to be configured!');
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapServer/src/BeSimple/SoapServer/XmlMimeFilter.php b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/XmlMimeFilter.php
new file mode 100644
index 0000000..7562745
--- /dev/null
+++ b/src/BeSimple/SoapServer/src/BeSimple/SoapServer/XmlMimeFilter.php
@@ -0,0 +1,75 @@
+
+ * (c) Francis Besset
+ *
+ * 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\FilterHelper;
+use BeSimple\SoapCommon\Helper;
+use BeSimple\SoapCommon\Mime\MultiPart as MimeMultiPart;
+use BeSimple\SoapCommon\Mime\Parser as MimeParser;
+use BeSimple\SoapCommon\Mime\Part as MimePart;
+use BeSimple\SoapCommon\SoapRequest;
+use BeSimple\SoapCommon\SoapRequestFilter;
+use BeSimple\SoapCommon\SoapResponse;
+use BeSimple\SoapCommon\SoapResponseFilter;
+
+/**
+ * XML MIME filter that fixes the namespace of xmime:contentType attribute.
+ *
+ * @author Andreas Schamberger
+ */
+class XmlMimeFilter implements SoapResponseFilter
+{
+ /**
+ * Reset all properties to default values.
+ */
+ public function resetFilter()
+ {
+ }
+
+ /**
+ * 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
+ $filterHelper = new FilterHelper($dom);
+
+ // add the neccessary namespaces
+ $filterHelper->addNamespace(Helper::PFX_XMLMIME, Helper::NS_XMLMIME);
+
+ // get xsd:base64binary elements
+ $xpath = new \DOMXPath($dom);
+ $xpath->registerNamespace('XOP', Helper::NS_XOP);
+ $query = '//XOP:Include/..';
+ $nodes = $xpath->query($query);
+
+ // exchange attributes
+ if ($nodes->length > 0) {
+ foreach ($nodes as $node) {
+ if ($node->hasAttribute('contentType')) {
+ $contentType = $node->getAttribute('contentType');
+ $node->removeAttribute('contentType');
+ $filterHelper->setAttribute($node, Helper::NS_XMLMIME, 'contentType', $contentType);
+ }
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapServer/tests/BeSimple/Tests/SoapServer/SoapServerBuilderTest.php b/src/BeSimple/SoapServer/tests/BeSimple/Tests/SoapServer/SoapServerBuilderTest.php
new file mode 100644
index 0000000..df46d46
--- /dev/null
+++ b/src/BeSimple/SoapServer/tests/BeSimple/Tests/SoapServer/SoapServerBuilderTest.php
@@ -0,0 +1,45 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace BeSimple\Tests\SoapServer;
+
+use BeSimple\SoapServer\SoapServerBuilder;
+
+/**
+ * UnitTest for \BeSimple\SoapServer\SoapServerBuilder
+ *
+ * @author Christian Kerl
+ */
+class SoapServerBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testUnconfiguredWsdl()
+ {
+ $builder = $this->getSoapServerBuilder();
+
+ $this->setExpectedException('InvalidArgumentException');
+ $builder->build();
+ }
+
+ public function testUnconfiguredHandler()
+ {
+ $builder = $this->getSoapServerBuilder();
+ $builder->withWsdl('my.wsdl');
+
+ $this->setExpectedException('InvalidArgumentException');
+ $builder->build();
+ }
+
+ public function getSoapServerBuilder()
+ {
+ return new SoapServerBuilder();
+ }
+}
\ No newline at end of file
diff --git a/src/BeSimple/SoapServer/tests/bootstrap.php b/src/BeSimple/SoapServer/tests/bootstrap.php
new file mode 100644
index 0000000..3fbc18f
--- /dev/null
+++ b/src/BeSimple/SoapServer/tests/bootstrap.php
@@ -0,0 +1,29 @@
+
+ * (c) Francis Besset
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+/*
+
+CAUTION: This file installs the dependencies needed to run the BeSimpleSoapClient test suite.
+
+https://github.com/BeSimple/BeSimpleSoapClient
+
+*/
+
+if (!is_dir($vendorDir = dirname(__FILE__).'/vendor')) {
+ mkdir($vendorDir, 0777, true);
+}
+
+$deps = array(
+ array('besimple-soapcommon', 'http://github.com/BeSimple/BeSimpleSoapCommon.git', 'origin/HEAD'),
+);
+
+foreach ($deps as $dep) {
+ list($name, $url, $rev) = $dep;
+
+ echo "> Installing/Updating $name\n";
+
+ $installDir = $vendorDir.'/'.$name;
+ if (!is_dir($installDir)) {
+ system(sprintf('git clone %s %s', escapeshellarg($url), escapeshellarg($installDir)));
+ }
+
+ system(sprintf('cd %s && git fetch origin && git reset --hard %s', escapeshellarg($installDir), escapeshellarg($rev)));
+}