Permalink
Browse files

Merge pull request #1 from aschamberger/master

Sync Server with Client and document builder methods
  • Loading branch information...
2 parents 0554e14 + 3183810 commit 8dace85c50986e3c5c8cbb96436ad2d0d904257d @christiankerl christiankerl committed May 22, 2012
View
@@ -1 +1,5 @@
-/vendor
+vendor
+/phpunit.xml
+.buildpath
+.project
+.settings
@@ -0,0 +1,138 @@
+<?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\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 <mail@andreass.net>
+ */
+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);
+ }
+ }
+}
@@ -0,0 +1,47 @@
+<?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;
+use BeSimple\SoapCommon\SoapResponse;
+
+/**
+ * SoapKernel for Server.
+ *
+ * @author Andreas Schamberger <mail@andreass.net>
+ */
+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);
+ }
+}
@@ -0,0 +1,71 @@
+<?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\SoapServer;
+
+use BeSimple\SoapCommon\SoapRequest as CommonSoapRequest;
+use BeSimple\SoapCommon\SoapMessage;
+
+/**
+ * SoapRequest class for SoapClient. Provides factory function for request object.
+ *
+ * @author Andreas Schamberger <mail@andreass.net>
+ */
+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;
+ }
+}
@@ -0,0 +1,62 @@
+<?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\SoapServer;
+
+use BeSimple\SoapCommon\SoapResponse as CommonSoapResponse;
+use BeSimple\SoapCommon\SoapMessage;
+
+/**
+ * SoapResponse class for SoapClient. Provides factory function for response object.
+ *
+ * @author Andreas Schamberger <mail@andreass.net>
+ */
+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;
+ }
+}
Oops, something went wrong.

0 comments on commit 8dace85

Please sign in to comment.