Question

On Magento 1.14.2.0.

I am connecting to the SOAP API via a URL like http://example.com/api/soap?wsdl=1

However, when I try and access the API it fatals filling my apache error log fills with

[Wed Jul 22 14:05:55 2015] FastCGI: server "/tmp/php-fpm5.5" stderr: PHP message: PHP Fatal error:  SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://custom-admin-url.example.com/index.php/api/soap/index/?SID=a_sid&wsdl=1' : Extra content at the end of the document
[Wed Jul 22 14:05:55 2015] FastCGI: server "/tmp/php-fpm5.5" stderr:  in /var/www/vhosts/development/example/lib/Zend/Soap/Server.php on line 814

The interesting thing to note is that we are no longer trying to access the API via http://example.com/api/soap?wsdl=1, but by https://custom-admin-url.example.com/index.php/api/soap/index/?SID=a_sid&wsdl=1 instead.

This admin url is correct, and is the one stored in the core_config_data table under the path admin/url/custom.

There is functionality to prevent the admin panel being accessed by anyone not coming from a certain IP address. The "Extra content at the end of the document" in the error is actually the html home page we view after being redirected.

How can I best solve this redirect issue?

Was it helpful?

Solution

It was not an option to remove the IP blocker on the admin panel, so a code change to force Magento to internally use a valid URL was the only solution I can see.

Mage_Api_Model_Server_Adapter_Soap::_instantiateServer is responsible for initialising the soap server for incoming requests,

Here's the relevant snippet of _instantiateServer

try {
    $this->_soap = new Zend_Soap_Server($this->getWsdlUrl(array("wsdl" => 1)), array('encoding' => $apiConfigCharset));
} catch (SoapFault $e) {

Here's the important part of getWsdlUrl

public function getWsdlUrl($params = null, $withAuth = true)
{
    $urlModel = Mage::getModel('core/url')
        ->setUseSession(false);

    $wsdlUrl = $params !== null
        ? $urlModel->getUrl('*/*/*', array('_current' => true, '_query' => $params))
        : $urlModel->getUrl('*/*/*');

Because this is operating within the admin scope, the url retrieved by Mage_Core_Model_Url is custom-admin-url.example.com. Which is causing the problem.

To "solve" this I created a new module, extended the soap adapter and forced the getWsdlUrl function to operate within the default website scope, which is NOT Mage_Core_Model_App:ADMIN_STORE_ID.

This correctly retrieves a web accessible url.

etc/api.xml

<config>
    <api>
        <adapters>
            <soap>
                <model>convenient_api/server_api_soap</model>
            </soap>
        </adapters>
    </api>
</config>

New adapter model

<?php
class Convenient_Api_Model_Server_Api_Soap extends Mage_Api_Model_Server_Adapter_Soap
{
    public function getWsdlUrl($params = null, $withAuth = true)
    {
        $defaultStoreId = Mage::app()->getWebsite(true)->getDefaultGroup()->getDefaultStoreId();

        $emulator = Mage::getModel('core/app_emulation');
        $env = $emulator->startEnvironmentEmulation($defaultStoreId);

        $url = parent::getWsdlUrl($params, $withAuth);

        $emulator->stopEnvironmentEmulation($env);

        return $url;
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top