10 Commits

28 changed files with 305 additions and 95 deletions

View File

@ -25,17 +25,15 @@ class Cache
BaseCache::setEnabled($isEnabled);
if (BaseCache::ENABLED == BaseCache::isEnabled()) {
BaseCache::setType($type);
BaseCache::setDirectory($directory);
BaseCache::setType($type);
BaseCache::setDirectory($directory);
if (null !== $lifetime) {
BaseCache::setLifetime($lifetime);
}
if (null !== $lifetime) {
BaseCache::setLifetime($lifetime);
}
if (null !== $limit) {
BaseCache::setLimit($limit);
}
if (null !== $limit) {
BaseCache::setLimit($limit);
}
}
}
}

View File

@ -98,6 +98,23 @@ class BeSimpleSoapExtension extends Extension
}
}
$proxy = $options['proxy'];
if (false !== $proxy['host']) {
if (null !== $proxy['auth']) {
if ('basic' === $proxy['auth']) {
$proxy['auth'] = \CURLAUTH_BASIC;
} elseif ('ntlm' === $proxy['auth']) {
$proxy['auth'] = \CURLAUTH_NTLM;
}
}
$definition->addMethodCall('withProxy', array(
$proxy['host'], $proxy['port'],
$proxy['login'], $proxy['password'],
$proxy['auth']
));
}
if (isset($defOptions['cache_type'])) {
$defOptions['cache_type'] = $this->getCacheType($defOptions['cache_type']);
}

View File

@ -24,6 +24,7 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder;
class Configuration
{
private $cacheTypes = array('none', 'disk', 'memory', 'disk_memory');
private $proxyAuth = array('basic', 'ntlm');
/**
* Generates the configuration tree.
@ -85,12 +86,33 @@ class Configuration
->scalarNode('cache_type')
->validate()
->ifNotInArray($this->cacheTypes)
->thenInvalid(sprintf('The cache type has to be either %s', implode(', ', $this->cacheTypes)))
->thenInvalid(sprintf('The cache type has to be either: %s', implode(', ', $this->cacheTypes)))
->end()
->end()
->arrayNode('classmap')
->useAttributeAsKey('name')->prototype('scalar')->end()
->end()
->arrayNode('proxy')
->info('proxy configuration')
->addDefaultsIfNotSet()
->beforeNormalization()
->ifTrue(function ($v) { return !is_array($v); })
->then(function ($v) { return array('host' => null === $v ? false : $v); })
->end()
->children()
->scalarNode('host')->defaultFalse()->end()
->scalarNode('port')->defaultValue(3128)->end()
->scalarNode('login')->defaultNull()->end()
->scalarNode('password')->defaultNull()->end()
->scalarNode('auth')
->defaultNull()
->validate()
->ifNotInArray($this->proxyAuth)
->thenInvalid(sprintf('The proxy auth has to be either: %s', implode(', ', $this->proxyAuth)))
->end()
->end()
->end()
->end()
->end()
->end()
->end()

View File

@ -16,6 +16,7 @@
</argument>
<argument type="service" id="besimple.soap.classmap" />
<argument type="service" id="besimple.soap.converter.collection" />
<argument type="service" id="besimple.soap.cache" /> <!-- hack to load besimple cache configuration -->
</service>
<service id="besimple.soap.client" factory-service="besimple.soap.client.builder" factory-method="build" class="%besimple.soap.client.builder.class%" abstract="true" />

View File

@ -12,7 +12,7 @@
<service id="besimple.soap.cache" class="%besimple.soap.cache.class%">
<argument>%kernel.debug%</argument>
<argument>%besimple.soap.cache.type%</argument>
<argument>%besimple.soap.cache.dir%/php</argument>
<argument>%besimple.soap.cache.dir%/cache</argument>
<argument>%besimple.soap.cache.lifetime%</argument>
<argument>%besimple.soap.cache.limit%</argument>
</service>

View File

@ -33,4 +33,8 @@ SoapServer
SoapClient
----------
Coming soon.
.. toctree::
:maxdepth: 1
:numbered:
soapclient/configuration

View File

@ -0,0 +1,158 @@
Configuration
=============
Client configuration
--------------------
Configure your first client in your config file:
.. code-block:: yaml
# app/config/config.yml
be_simple_soap:
clients:
DemoApi:
# required
wsdl: http://localhost/app_dev.php/ws/DemoApi?wsdl
# classmap (optional)
classmap:
type_name: "Full\Class\Name"
# proxy (optional)
proxy:
host: proxy.domain.name # required to enable proxy configuration
port: 3128
login: ~
password: ~
auth: ~ # can be 'basic' or 'ntlm'
Using client
------------
.. code-block:: php
namespace Acme\DemoBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DemoController extends Controller
{
public function helloAction($name)
{
// The client service name is `besimple.soap.client.demoapi`:
// `besimple.soap.client.`: is the base name of your client
// `demoapi`: is the name specified in your config file converted to lowercase
$client = $this->container->get('besimple.soap.client.demoapi');
// call `hello` method on WebService with the string parameter `$name`
$helloResult = $client->hello($name);
return $this->render('AcmeDemoBundle:Demo:hello.html.twig', array(
'hello' => $helloResult,
));
}
}
Classmap
--------
Configuration
~~~~~~~~~~~~~
.. code-block:: yaml
# app/config/config.yml
be_simple_soap:
clients:
DemoApi:
# ...
classmap:
User: Acme\DemoBundle\Api\UserApi
# add other type_name: classname
UserApi class
~~~~~~~~~~~~~
.. code-block:: php
namespace Acme\DemoBundle\Api;
class UserApi
{
private $username;
private $firstname;
private $lastname;
public function __construct($username)
{
$this->username = $username;
}
public function getFirstname()
{
return $this->firstname;
}
public function getLastname()
{
return $this->lastname;
}
}
Usage
~~~~~
.. code-block:: php
namespace Acme\DemoBundle\Controller;
use Acme\DemoBundle\Api\UserApi;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DemoController extends Controller
{
public function userAction($username)
{
// The client service name is `besimple.soap.client.demoapi`:
// `besimple.soap.client.`: is the base name of your client
// `demoapi`: is the name specified in your config file converted to lowercase
$client = $this->container->get('besimple.soap.client.demoapi');
// call `getUser` method on WebService with an instance of UserApi
// if the `getUserByUsername` method return a `User` type then `$userResult` is an instance of UserApi
$userResult = $client->getUserByUsername($username);
return $this->render('AcmeDemoBundle:Demo:user.html.twig', array(
'user' => $userResult,
));
}
}
Without classmap configuration the `$userResult` is an instance of `stdClass`:
.. code-block:: text
object(stdClass)#5561 (3) {
["username"]=>
string(6) "FooBar"
["firstname"]=>
string(3) "Foo"
["lastname"]=>
string(3) "Bar"
}
With classmap configuration the `$userResult` is an instance of `Acme\DemoBundle\Api\UserApi`:
.. code-block:: text
object(Acme\DemoBundle\Api\UserApi)#208 (3) {
["username":"Acme\DemoBundle\Api\UserApi":private]=>
string(6) "FooBar"
["firstname":"Acme\DemoBundle\Api\UserApi":private]=>
string(3) "Foo"
["lastname":"Acme\DemoBundle\Api\UserApi":private]=>
string(3) "Bar"
}

View File

@ -80,6 +80,7 @@ class Curl
if (isset($options['connection_timeout'])) {
curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, $options['connection_timeout']);
}
if (isset($options['proxy_host'])) {
if (false !== $options['proxy_host']) {
$proxyHost = $options['proxy_host'].(isset($options['proxy_port']) ? $options['proxy_port'] : 8080);
@ -88,10 +89,16 @@ class Curl
}
curl_setopt($this->ch, CURLOPT_PROXY, $proxyHost);
if (false !== $proxyHost && isset($options['proxy_login'])) {
curl_setopt($this->ch, CURLOPT_PROXYUSERPWD, $options['proxy_login'].':'.$options['proxy_password']);
if (isset($options['proxy_auth'])) {
curl_setopt($this->ch, CURLOPT_PROXYAUTH, $options['proxy_auth']);
}
}
}
if (isset($options['proxy_user'])) {
curl_setopt($this->ch, CURLOPT_PROXYUSERPWD, $options['proxy_user'] . ':' . $options['proxy_password']);
}
if (isset($options['login'])) {
curl_setopt($this->ch, CURLOPT_HTTPAUTH, isset($options['extra_options']['http_auth']) ? $options['extra_options']['http_auth'] : CURLAUTH_ANY);
curl_setopt($this->ch, CURLOPT_USERPWD, $options['login'].':'.$options['password']);

View File

@ -41,15 +41,6 @@ class SoapClient extends \SoapClient
*/
protected $tracingEnabled = false;
/**
* Work around missing header/php://input access in PHP cli webserver by
* setting headers additionally as GET parameters and SOAP request body
* explicitly as POST variable.
*
* @var boolean
*/
private $cliWebserverWorkaround = false;
/**
* cURL instance.
*
@ -108,10 +99,7 @@ class SoapClient extends \SoapClient
if (isset($options['soap_version'])) {
$this->soapVersion = $options['soap_version'];
}
// activate cli webserver workaround
if (isset($options['cli_webserver_workaround'])) {
$this->cliWebserverWorkaround = $options['cli_webserver_workaround'];
}
$this->curl = new Curl($options);
if (isset($options['extra_options'])) {
@ -158,25 +146,6 @@ class SoapClient extends \SoapClient
$location = $soapRequest->getLocation();
$content = $soapRequest->getContent();
/*
* Work around missing header/php://input access in PHP cli webserver by
* setting headers additionally as GET parameters and SOAP request body
* explicitly as POST variable
*/
if ($this->cliWebserverWorkaround === true) {
if (strpos($location, '?') === false) {
$location .= '?';
} else {
$location .= '&';
}
$location .= SoapMessage::CONTENT_TYPE_HEADER.'='.urlencode($soapRequest->getContentType());
$location .= '&';
$location .= SoapMessage::SOAP_ACTION_HEADER.'='.urlencode($soapRequest->getAction());
$content = http_build_query(array('request' => $content));
$headers = array();
}
$headers = $this->filterRequestHeaders($soapRequest, $headers);
@ -189,6 +158,7 @@ class SoapClient extends \SoapClient
$headers,
$options
);
// tracing enabled: store last request header and body
if ($this->tracingEnabled === true) {
$this->lastRequestHeaders = $this->curl->getRequestHeaders();

View File

@ -175,19 +175,28 @@ class SoapClientBuilder extends AbstractSoapBuilder
*
* @param string $host Host
* @param int $port Port
* @param string $username Username
* @param string $login Login
* @param string $password Password
* @param int $auth Authentication method
*
* @return \BeSimple\SoapClient\SoapClientBuilder
*/
public function withProxy($host, $port, $username = null, $password = null)
public function withProxy($host, $port, $login = null, $password = null, $auth = null)
{
$this->soapOptions['proxy_host'] = $host;
$this->soapOptions['proxy_port'] = $port;
if ($username) {
$this->soapOptions['proxy_login'] = $username;
if ($login) {
$this->soapOptions['proxy_login'] = $login;
$this->soapOptions['proxy_password'] = $password;
if ($auth) {
if (!in_array($auth, array(\CURLAUTH_BASIC, \CURLAUTH_NTLM), true)) {
throw new \InvalidArgumentException('Invalid authentication method: CURLAUTH_BASIC or CURLAUTH_NTLM constants are availables.');
}
$this->soapOptions['proxy_auth'] = $auth;
}
}
return $this;
@ -236,4 +245,4 @@ class SoapClientBuilder extends AbstractSoapBuilder
{
$this->validateWsdl();
}
}
}

View File

@ -28,6 +28,7 @@ class MtomAxisInteropTest extends TestCase
'base64Binary' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\base64Binary',
'AttachmentRequest' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\AttachmentRequest',
),
'proxy_host' => false,
);
public function testAttachment()
@ -48,4 +49,4 @@ class MtomAxisInteropTest extends TestCase
// $this->assertEquals($b64->_, file_get_contents($fileCreatedByServer));
// unlink($fileCreatedByServer);
}
}
}

View File

@ -37,6 +37,7 @@ class SwaAxisInteropTest extends TestCase
'uploadFile' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\uploadFile',
'uploadFileResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\uploadFileResponse',
),
'proxy_host' => false,
);
public function testUploadDownloadText()
@ -74,4 +75,4 @@ class SwaAxisInteropTest extends TestCase
$this->assertEquals($upload->data, $result->data);
}
}
}

View File

@ -32,6 +32,7 @@ class WsAddressingAxisInteropTest extends TestCase
private $options = array(
'soap_version' => SOAP_1_2,
'features' => SOAP_SINGLE_ELEMENT_ARRAYS, // make sure that result is array for size=1
'proxy_host' => false,
);
public function testSession()
@ -56,4 +57,4 @@ class WsAddressingAxisInteropTest extends TestCase
$this->assertEquals($soapSessionId1, $soapSessionId2);
}
}
}

View File

@ -64,6 +64,7 @@ class WsSecuritySigEncAxisInteropTest extends TestCase
'addBookResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\addBookResponse',
'BookInformation' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\BookInformation',
),
'proxy_host' => false,
);
public function testSigEnc()
@ -103,4 +104,4 @@ class WsSecuritySigEncAxisInteropTest extends TestCase
// getBooksByType("scifi");
}
}
}

View File

@ -40,6 +40,7 @@ class WsSecurityUserPassAxisInteropTest extends TestCase
'addBookResponse' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\addBookResponse',
'BookInformation' => 'BeSimple\SoapClient\Tests\AxisInterop\Fixtures\BookInformation',
),
'proxy_host' => false,
);
public function testUserPassText()
@ -93,4 +94,4 @@ class WsSecurityUserPassAxisInteropTest extends TestCase
// getBooksByType("scifi");
}
}
}

View File

@ -74,7 +74,9 @@ class CurlTest extends AbstractWebserverTest
public function testGetResponseBody()
{
$curl = new Curl();
$curl = new Curl(array(
'proxy_host' => false,
));
$curl->exec(sprintf('http://localhost:%d/curl.txt', WEBSERVER_PORT));
$this->assertEquals('This is a testfile for cURL.', $curl->getResponseBody());
@ -82,7 +84,9 @@ class CurlTest extends AbstractWebserverTest
public function testGetResponseContentType()
{
$curl = new Curl();
$curl = new Curl(array(
'proxy_host' => false,
));
$curl->exec(sprintf('http://localhost:%d/curl.txt', WEBSERVER_PORT));
$this->assertEquals('text/plain; charset=UTF-8', $curl->getResponseContentType());
@ -93,7 +97,9 @@ class CurlTest extends AbstractWebserverTest
public function testGetResponseHeaders()
{
$curl = new Curl();
$curl = new Curl(array(
'proxy_host' => false,
));
$curl->exec(sprintf('http://localhost:%d/curl.txt', WEBSERVER_PORT));
$this->assertEquals(117 + self::$websererPortLength, strlen($curl->getResponseHeaders()));
@ -104,7 +110,9 @@ class CurlTest extends AbstractWebserverTest
public function testGetResponseStatusCode()
{
$curl = new Curl();
$curl = new Curl(array(
'proxy_host' => false,
));
$curl->exec(sprintf('http://localhost:%d/curl.txt', WEBSERVER_PORT));
$this->assertEquals(200, $curl->getResponseStatusCode());

View File

@ -18,7 +18,6 @@ $options = array(
'base64Binary' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\base64Binary',
'AttachmentRequest' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\AttachmentRequest',
),
'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
'connection_timeout' => 1,
);

View File

@ -20,7 +20,7 @@ class MtomServerInteropTest extends TestCase
'base64Binary' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\base64Binary',
'AttachmentRequest' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\AttachmentRequest',
),
'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
'proxy_host' => false,
);
public function testAttachment()
@ -41,4 +41,4 @@ class MtomServerInteropTest extends TestCase
$this->assertEquals($b64->_, file_get_contents($fileCreatedByServer));
unlink($fileCreatedByServer);
}
}
}

View File

@ -24,7 +24,6 @@ $options = array(
'uploadFile' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\uploadFile',
'uploadFileResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\uploadFileResponse',
),
'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
);
$sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/SwA.wsdl', $options);

View File

@ -23,7 +23,7 @@ class SwaServerInteropTest extends TestCase
'uploadFile' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\uploadFile',
'uploadFileResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\uploadFileResponse',
),
'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
'proxy_host' => false,
);
public function testUploadDownloadText()

View File

@ -31,7 +31,6 @@ $options = array(
'addBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBookResponse',
'BookInformation' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation',
),
'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
);
$sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/WsSecuritySigEnc.wsdl', $options);

View File

@ -30,7 +30,7 @@ class WsSecuritySigEncServerInteropTest extends TestCase
'addBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBookResponse',
'BookInformation' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation',
),
'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
'proxy_host' => false,
);
public function testSigEnc()
@ -70,4 +70,4 @@ class WsSecuritySigEncServerInteropTest extends TestCase
// getBooksByType("scifi");
}
}
}

View File

@ -28,7 +28,6 @@ $options = array(
'addBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBookResponse',
'BookInformation' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation',
),
'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
);
$sc = new BeSimpleSoapClient(__DIR__.'/Fixtures/WsSecurityUserPass.wsdl', $options);

View File

@ -29,7 +29,7 @@ class WsSecurityUserPassServerInteropTest extends TestCase
'addBookResponse' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\addBookResponse',
'BookInformation' => 'BeSimple\SoapClient\Tests\ServerInterop\Fixtures\BookInformation',
),
'cli_webserver_workaround' => true, // Work around missing header access in PHP cli webserver by setting headers additionally as GET parameters.
'proxy_host' => false,
);
public function testUserPassText()
@ -83,4 +83,4 @@ class WsSecurityUserPassServerInteropTest extends TestCase
// getBooksByType("scifi");
}
}
}

View File

@ -96,6 +96,20 @@ class SoapClientBuilderTest extends \PHPUnit_Framework_TestCase
$builder->withProxy('127.0.0.1', 8585, 'foo', 'bar');
$this->assertEquals($this->mergeOptions(array('proxy_host' => '127.0.0.1', 'proxy_port' => 8585, 'proxy_login' => 'foo', 'proxy_password' => 'bar')), $builder->getSoapOptions());
$builder->withProxy('127.0.0.1', 8585, 'foo', 'bar', \CURLAUTH_BASIC);
$this->assertEquals($this->mergeOptions(array('proxy_host' => '127.0.0.1', 'proxy_port' => 8585, 'proxy_login' => 'foo', 'proxy_password' => 'bar', 'proxy_auth' => \CURLAUTH_BASIC)), $builder->getSoapOptions());
$builder->withProxy('127.0.0.1', 8585, 'foo', 'bar', \CURLAUTH_NTLM);
$this->assertEquals($this->mergeOptions(array('proxy_host' => '127.0.0.1', 'proxy_port' => 8585, 'proxy_login' => 'foo', 'proxy_password' => 'bar', 'proxy_auth' => \CURLAUTH_NTLM)), $builder->getSoapOptions());
try {
$builder->withProxy('127.0.0.1', 8585, 'foo', 'bar', -100);
$this->fail('An expected exception has not been raised.');
} catch (\Exception $e) {
$this->assertInstanceOf('InvalidArgumentException', $e);
}
}
public function testCreateWithDefaults()

View File

@ -115,7 +115,9 @@ class WsdlDownloaderTest extends AbstractWebserverTest
Cache::setDirectory($wsdlCacheUrl);
$cacheDirForRegExp = preg_quote($wsdlCacheUrl, '#');
$wsdlDownloader = new WsdlDownloader(new Curl());
$wsdlDownloader = new WsdlDownloader(new Curl(array(
'proxy_host' => false,
)));
$r = new \ReflectionClass($wsdlDownloader);
$m = $r->getMethod('resolveRemoteIncludes');
$m->setAccessible(true);
@ -178,7 +180,9 @@ class WsdlDownloaderTest extends AbstractWebserverTest
Cache::setDirectory($wsdlCacheUrl);
$cacheDirForRegExp = preg_quote($wsdlCacheUrl, '#');
$wsdlDownloader = new WsdlDownloader(new Curl());
$wsdlDownloader = new WsdlDownloader(new Curl(array(
'proxy_host' => false,
)));
$r = new \ReflectionClass($wsdlDownloader);
$m = $r->getMethod('resolveRemoteIncludes');
$m->setAccessible(true);

View File

@ -28,6 +28,13 @@ abstract class SoapMessage
*/
const CONTENT_TYPE_HEADER = 'CONTENT_TYPE';
/**
* $_SERVER key for 'Content-Type' header (with PHP cli-webserver)
*
* @var string
*/
const HTTP_CONTENT_TYPE_HEADER = 'HTTP_CONTENT_TYPE';
/**
* $_SERVER key for 'SOAPAction' header.
*

View File

@ -32,29 +32,19 @@ class SoapRequest extends CommonSoapRequest
*/
public static function create($content, $version)
{
$location = self::getCurrentUrl();
/*
* Work around missing header/php://input access in PHP cli webserver by
* setting headers additionally as GET parameters and SOAP request body
* explicitly as POST variable
*/
if (php_sapi_name() == "cli-server") {
$content = is_null($content) ? $_POST['request'] : $content;
$action = $_GET[SoapMessage::SOAP_ACTION_HEADER];
$contentType = $_GET[SoapMessage::CONTENT_TYPE_HEADER];
} else {
$content = is_null($content) ? file_get_contents("php://input") : $content;
$action = isset($_SERVER[SoapMessage::SOAP_ACTION_HEADER]) ? $_SERVER[SoapMessage::SOAP_ACTION_HEADER] : null;
$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->setContent((string) (null === $content ? file_get_contents("php://input") : $content));
$request->setLocation(self::getCurrentUrl());
$request->setAction(isset($_SERVER[SoapMessage::SOAP_ACTION_HEADER]) ? $_SERVER[SoapMessage::SOAP_ACTION_HEADER] : null);
$request->setVersion($version);
$request->setContentType($contentType);
if (isset($_SERVER[SoapMessage::CONTENT_TYPE_HEADER])) {
$request->setContentType($_SERVER[SoapMessage::CONTENT_TYPE_HEADER]);
} elseif (isset($_SERVER[SoapMessage::HTTP_CONTENT_TYPE_HEADER])) {
$request->setContentType($_SERVER[SoapMessage::HTTP_CONTENT_TYPE_HEADER]);
}
return $request;
}