У меня была проблема с неполными ответами SOAP XML один раз.
Настройка была такой:
- Сервер Linux
- Magento CE 1.5.1.0
- Использование SOAP v2 с включенной поддержкой WS-I
- Вызов sales_order.info
Даже если вы используете другую версию Magento и другой вызов SOAP, вы можете столкнуться с такой же ошибкой, как и я. Проблема заключалась в том, что заголовок HTTP Content-Length был неправильно рассчитан для ответов> 8000 байт .
Как проверить, не затронут ли вас эта ошибка :
- Выполнить вызов, который дает короткий ответ (например, "catalog_category.info" только с одним представлением магазина и только несколькими атрибутами). Если XML завершен, проверьте, имеет ли ответ длину <= 8000 байт. </li>
- Скопируйте файл app / code / core / Mage / Api / Model / Server / Wsi / Adapter / Soap.php в вашу папку app / code / local и отредактируйте метод run (). Если вы используете параметр «wsdl» в своем URL-адресе SOAP, отредактируйте первую часть структуры «if», в противном случае отредактируйте часть «else».
Поскольку второй способ является более точным, я пойду с этим.
- Откройте файл и найдите вызов метода -> setBody (). Как видите, происходит некоторое волшебство поиска / замены.
Запишите результат операций поиска / замены в переменную и запишите его для дальнейшего изучения. Код может выглядеть так:
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() );
}
}
}
Выполните вызов API SOAP и откройте var / log / soap.log в каталоге Magento. Если XML-файл завершен в файле журнала, но не в вашем ответе, проблема заключается в заголовке Content-Length.
Как исправить заголовок Content-Length
Оставайтесь в своей копии 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.
- Если это работает, удалите вызов Mage :: log () и перепишите код для использования в своем собственном расширении.
Если вы спросите , почему возникает эта проблема, я не могу вам точно сказать, потому что я не выискивал ошибку полностью.
Из того, что я увидел, все в порядке, если ответ XML имеет длину <= 8000 байт. Если ответ длиннее 8000 байт и XML состоит из x строк, ответ усекается до x символов. Похоже, что это проблема с различными кодами возврата каретки и / или с проблемами кодирования, которые приводят к неправильному вычислению длины содержимого ответа. </p>