Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does it work with the magic WSDL URI query parameter?

I'm building a Soap server within a Symfony application. As first step I created a controller with my "hello world" Soap action and defined the route for it:

routing.yml

api.soap.foo
    path: /soapapi/foo
    defaults: { _controller: SoapBundle\Controller\FooController:bar }
    methods: [GET, HEAD, POST]

FooController#bar(...)

protected function bar(Request $request)
{
    $autodiscover = new AutoDiscover();
    $autodiscover
        ->setClass(MyFooBarService::class)
        ->setUri('http://my-app.loc/soapapi/foo/bar')
        ->setServiceName('MyFooBarService')
    ;
    $wsdl = $autodiscover->generate();
    $wsdl->dump(__DIR__ . '/soapapi-foo-bar.wsdl');
    $server = new SoapServer(__DIR__ . '/soapapi-foo-bar.wsdl');
    $server->setObject($this->myFooBarService);
    $response = new Response();
    $response->headers->set('Content-Type', 'text/xml; charset=ISO-8859-1');
    ob_start();
    $server->handle();
    $response->setContent(ob_get_clean());
    return $response;
}

Now, when I call http://my-app.loc/soapapi/foo/bar in a browser or using cURL (so via HTTP GET), I get an error:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Body>
        <SOAP-ENV:Fault>
            <faultcode>SOAP-ENV:Client</faultcode>
            <faultstring>Bad Request</faultstring>
        </SOAP-ENV:Fault>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

But when I call http://my-app.loc/soapapi/foo/bar?wsdl, I actually get the (generated) WSDL document. Why? I have not defined anywhere, that it should work like this. Why and how does this (magic) work? Is it Symfony specific magic?

like image 900
automatix Avatar asked Jan 11 '17 21:01

automatix


Video Answer


1 Answers

This is a great question.

No this is not Symfony specific, it's a behavior of the built-in SOAP server in PHP. When the endpoint URL is accessed with ?wsdl appended, the SOAP server will respond with the wsdl document that it was instantiated with in the constructor:

$server = new SoapServer(__DIR__ . '/soapapi-foo-bar.wsdl');

I haven't been able to find where this behavior is documented on the PHP website, but it clearly exists and is reproducible.

The code for the feature can be found in PHP's source code starting on line 1369 and ending on line 1396. The code checks if the request method is GET and checks for the presence of a 'wsdl' query parameter.

like image 98
Kris Peeling Avatar answered Nov 15 '22 04:11

Kris Peeling