Анализ WSDL API Soap: Не удалось загрузить из дополнительного содержимого в конце документа


На Magento 1.14.2.0.

Я подключаюсь к API SOAP по URL-адресу, например http://example.com/api/soap?wsdl=1

Однако, когда я пытаюсь получить доступ к API, это приводит к фатальному заполнению моего журнала ошибок apache

[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

Интересно отметить, что мы больше не пытаемся получить доступ к API через http://example.com/api/soap?wsdl=1, а вместо этого через https://custom-admin-url.example.com/index.php/api/soap/index/?SID=a_sid&wsdl=1.

Этот URL-адрес администратора правильный и хранится в таблице core_config_data под путем admin/url/custom.

Существует функциональность для предотвращения доступ к панели администратора может получить любой, кто не приходит с определенного IP-адреса. "Extra content at the end of the document" в ошибке на самом деле является домашней страницей html, которую мы просматриваем после перенаправления.

Как я могу наилучшим образом решить эту проблему перенаправления?

Author: Luke Rodgers, 2015-07-22

1 answers

Не было возможности удалить блокировщик IP-адресов на панели администратора, поэтому изменение кода, чтобы заставить Magento внутренне использовать действительный URL-адрес, было единственным решением, которое я вижу.

Mage_Api_Model_Server_Adapter_Soap::_instantiateServer отвечает за инициализацию сервера soap для входящих запросов,

Вот соответствующий фрагмент _instantiateServer

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

Вот важная часть 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('*/*/*');

Поскольку это работает в области администратора, URL-адрес, полученный Mage_Core_Model_Url, равен custom-admin-url.example.com. Что вызывает проблема.

Чтобы "решить" эту проблему, я создал новый модуль, расширил адаптер soap и заставил функцию getWsdlUrl работать в области веб-сайта по умолчанию, которая НЕ Mage_Core_Model_App:ADMIN_STORE_ID.

Это правильно извлекает URL-адрес, доступный в Интернете.

etc/api.xml

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

Новая модель адаптера

<?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;
    }
 0
Author: Luke Rodgers, 2015-07-22 16:11:13