Skip to content
This repository has been archived by the owner on Jan 31, 2020. It is now read-only.

Soap: Autodiscover encodes service URI twice #25

Open
GeeH opened this issue Jun 28, 2016 · 4 comments
Open

Soap: Autodiscover encodes service URI twice #25

GeeH opened this issue Jun 28, 2016 · 4 comments

Comments

@GeeH
Copy link
Contributor

GeeH commented Jun 28, 2016

This issue has been moved from the zendframework repository as part of the bug migration program as outlined here - http://framework.zend.com/blog/2016-04-11-issue-closures.html


Original Issue: https://api.github.com/repos/zendframework/zendframework/issues/7541
User: @LastDragon-ru
Created On: 2015-05-20T09:06:27Z
Updated At: 2015-11-06T21:40:25Z

<?php
class TestService {
    /**
     * @return string
     */
    public function test() {
        return __METHOD__;
    }
}

$wsdl         = './service.xml';
$wsdlUri      = 'http://127.0.0.1/soap/server.php?a=a&b=b';
$autodiscover = new \Zend\Soap\AutoDiscover();

$autodiscover->setUri($wsdlUri);
$autodiscover->setClass('TestService');

$autodiscover->dump($wsdl);

WSDL:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://127.0.0.1/soap/server.php?a=a&amp;b=b" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" name="TestService" targetNamespace="http://127.0.0.1/soap/server.php?a=a&amp;amp;b=b">
    <types>
        <xsd:schema targetNamespace="http://127.0.0.1/soap/server.php?a=a&amp;amp;b=b" />
    </types>
    <portType name="TestServicePort">
        <operation name="test">
            <documentation>test</documentation>
            <input message="tns:testIn" />
            <output message="tns:testOut" />
        </operation>
    </portType>
    <binding name="TestServiceBinding" type="tns:TestServicePort">
        <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
        <operation name="test">
            <soap:operation soapAction="http://127.0.0.1/soap/server.php?a=a&amp;amp;b=b#test" />
            <input>
                <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://127.0.0.1/soap/server.php?a=a&amp;amp;b=b" />
            </input>
            <output>
                <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://127.0.0.1/soap/server.php?a=a&amp;amp;b=b" />
            </output>
        </operation>
    </binding>
    <service name="TestServiceService">
        <port name="TestServicePort" binding="tns:TestServiceBinding">
            <soap:address location="http://127.0.0.1/soap/server.php?a=a&amp;amp;b=b" />
        </port>
    </service>
    <message name="testIn" />
    <message name="testOut">
        <part name="return" type="xsd:string" />
    </message>
</definitions>

WSDL file contains &amp; instead of & in attributes (non critical) and soap:address@location (critical)


@sh3bang
Copy link

sh3bang commented Jul 6, 2016

are any workaround possible?

@sh3bang
Copy link

sh3bang commented Jul 6, 2016

i am using as workaround this:

header('Content-Type: text/xml');
$pattern = '/="(.*?)(?:&amp;amp;)(.*?)"/';
$replacement = '="${1}&amp;${2}"';
echo preg_replace($pattern, $replacement, $autodiscover->toXml());

instead of this:
$autodiscover->handle();

NOTE: replace only ONE of "&amp;amp;" occurrences within double quotes!

@LastDragon-ru
Copy link

Now I can say that the URL with query params as XML namespace is not a good idea - I had a few problems with others SOAP clients/servers... So for now I use the following code:

$serviceNs    = 'http://example.com/soap/1.0'; 
$serviceUri   = 'http://example.com/soap.php?a=1&b=2';

// Wsdl
$autodiscover = new \Zend\Soap\AutoDiscover();

$autodiscover->setUri($serviceNs);
$autodiscover->setServiceName('MySoapWebService');

$wsdlDom = $autodiscover->generate()->toDomDocument();

// Remove <operation> (this tag is not necessary).
foreach ($wsdlDom->getElementsByTagName('operation') as $node) {
    /* @var $node DOMElement */
    if ($node->hasAttribute('soapAction')) {
        $node->parentNode->removeChild($node);
    }
}

// Fix namespace 
$ns = \Zend\Uri\Uri::encodePath($serviceNs);

foreach ($wsdlDom->getElementsByTagName('address') as $node) {
    /* @var $node DOMElement */
    if ($node->hasAttribute('location')) {
        $node->setAttribute('location', str_replace($ns, $serviceUri, $node->getAttribute('location')));
    }
}

// Remove @namespace (XML already contains our NS in root tag)
foreach ($wsdlDom->getElementsByTagName('body') as $node) {
    /* @var $node DOMElement */
    if ($node->hasAttribute('namespace')) {
        $node->removeAttribute('namespace');
    }
}

// Fix '&amp;amp;'
$wsdlContent = $wsdlDom->saveXML();
$wsdlContent = str_replace('&amp;amp;', '&amp;', $wsdlContent);

Finally, I suggest split URI into URL and NS and than fix &amp;amp; in URL :)

@weierophinney
Copy link
Member

This repository has been closed and moved to laminas/laminas-soap; a new issue has been opened at laminas/laminas-soap#16.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants