Magento - неполный ответ SOAP API при использовании стека MAMP под Lion - PullRequest
1 голос
/ 24 декабря 2011

Я тестировал SOAP API Magento, используя soapUI. Я успешно вошел в систему и получил хэш входа в систему. Затем я попытался получить список продуктов, и это работало нормально.

Это было на сервере Linux, использующем последнюю версию Apache, mySQL и PHP.

Затем я создал резервную копию Magento и базу данных. Я хотел создать тестовую среду на сервере Lion, используя стек MAMP. Кажется, что резервная копия Magento работает нормально, а SOAP API - нет.

Снова я использовал soapUI для получения хэша логина и попытался получить все продукты. Но теперь ответ кажется неполным:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Magento">
<SOAP-ENV:Body>
<ns1:catalogProductListResponseParam>
<result>
<complexObjectArray>
<product_id>7167</product_id>
<sku>000140</sku>
... etc ...
<complexObjectArray>34</complexObjectArray>
</category_ids>
<website_ids>
<complexObjectArray>1</complexObjectArray>
</website_ids>
</complexObjectArray>
<complexObjectArray>
<product

Почему ответ от Lion / MAMP неполный?

Ответы [ 2 ]

11 голосов
/ 26 декабря 2011

У меня была проблема с неполными ответами SOAP XML один раз.

Настройка была такой:

  • Сервер Linux
  • Magento CE 1.5.1.0
  • Использование SOAP v2 с включенной поддержкой WS-I
  • Вызов sales_order.info

Даже если вы используете другую версию Magento и другой вызов SOAP, вы можете столкнуться с такой же ошибкой, как и я. Проблема заключалась в том, что заголовок HTTP Content-Length был неправильно рассчитан для ответов> 8000 байт .

Как проверить, не затронут ли вас эта ошибка :

  1. Выполнить вызов, который дает короткий ответ (например, "catalog_category.info" только с одним представлением магазина и только несколькими атрибутами). Если XML завершен, проверьте, имеет ли ответ длину <= 8000 байт. </li>
  2. Скопируйте файл app / code / core / Mage / Api / Model / Server / Wsi / Adapter / Soap.php в вашу папку app / code / local и отредактируйте метод run (). Если вы используете параметр «wsdl» в своем URL-адресе SOAP, отредактируйте первую часть структуры «if», в противном случае отредактируйте часть «else».

Поскольку второй способ является более точным, я пойду с этим.

  1. Откройте файл и найдите вызов метода -> setBody (). Как видите, происходит некоторое волшебство поиска / замены.
  2. Запишите результат операций поиска / замены в переменную и запишите его для дальнейшего изучения. Код может выглядеть так:

    public function run()
    {
        $apiConfigCharset = Mage::getStoreConfig("api/config/charset");
    
        if ($this->getController()->getRequest()->getParam('wsdl') !== null) {
            /* don't modify the first part ... */
        } else {
            try {
                $this->_instantiateServer();
    
                $content = preg_replace(
                        '/(\>\<)/i',
                        ">\n<",
                        str_replace(
                                '<soap:operation soapAction=""></soap:operation>',
                                "<soap:operation soapAction=\"\" />\n",
                                str_replace(
                                        '<soap:body use="literal"></soap:body>',
                                        "<soap:body use=\"literal\" />\n",
                                        preg_replace(
                                            '/<\?xml version="([^\"]+)"([^\>]+)>/i',
                                            '<?xml version="$1" encoding="'.$apiConfigCharset.'"?>',
                                            $this->_soap->handle()
                                        )
                                )
                        )
                );
                Mage::log($content, null, 'soap.log');
                $this->getController()->getResponse()
                     ->clearHeaders()
                     ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
                     ->setBody($content);
            } catch( Zend_Soap_Server_Exception $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            } catch( Exception $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            }
        }
    }
    
  3. Выполните вызов API SOAP и откройте var / log / soap.log в каталоге Magento. Если XML-файл завершен в файле журнала, но не в вашем ответе, проблема заключается в заголовке Content-Length.

Как исправить заголовок Content-Length

  1. Оставайтесь в своей копии Mage_Api_Model_Server_Wsi_Adapter_Soap и добавьте одну строку в код, который мы только что изменили:

    public function run()
    {
        $apiConfigCharset = Mage::getStoreConfig("api/config/charset");
    
        if ($this->getController()->getRequest()->getParam('wsdl') !== null) {
            /* don't modify the first part ... */
        } else {
            try {
                $this->_instantiateServer();
    
                $content = preg_replace(
                        '/(\>\<)/i',
                        ">\n<",
                        str_replace(
                                '<soap:operation soapAction=""></soap:operation>',
                                "<soap:operation soapAction=\"\" />\n",
                                str_replace(
                                        '<soap:body use="literal"></soap:body>',
                                        "<soap:body use=\"literal\" />\n",
                                        preg_replace(
                                            '/<\?xml version="([^\"]+)"([^\>]+)>/i',
                                            '<?xml version="$1" encoding="'.$apiConfigCharset.'"?>',
                                            $this->_soap->handle()
                                        )
                                )
                        )
                );
                Mage::log($content, null, 'soap.log');
                $this->getController()->getResponse()
                     ->clearHeaders()
                     ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
                     ->setHeader('Content-Length',strlen($content), true)
                     ->setBody($content);
            } catch( Zend_Soap_Server_Exception $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            } catch( Exception $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            }
        }
    }
    

    Обратите внимание на строку:

    ->setHeader('Content-Length',strlen($content), true)
    

    Мы вычисляем и устанавливаем заголовок Content-Length. Третий параметр, true, важен, потому что он указывает платформе перезаписать существующий заголовок Content-Length.

  2. Если это работает, удалите вызов Mage :: log () и перепишите код для использования в своем собственном расширении.

Если вы спросите , почему возникает эта проблема, я не могу вам точно сказать, потому что я не выискивал ошибку полностью.

Из того, что я увидел, все в порядке, если ответ XML имеет длину <= 8000 байт. Если ответ длиннее 8000 байт и XML состоит из x строк, ответ усекается до x символов. Похоже, что это проблема с различными кодами возврата каретки и / или с проблемами кодирования, которые приводят к неправильному вычислению длины содержимого ответа. </p>

0 голосов
/ 26 декабря 2011

Я думаю, что ваша конфигурация PHP изменилась. Вероятно, вы столкнулись с ошибкой PHP.ini memory_limit или max_execution_time. Вы должны быть в состоянии сравнить ваши настройки PHP, создав простой файл на каждом сервере в корне Magento (важно, чтобы вы поместили файл в корень Magento, поскольку файл .htaccess может переопределять настройки PHP) и сравнив значения:

info.php

<?php phpinfo();

Вы также можете проверить журналы ошибок Apache для получения дополнительной информации.

...