Magento - 在 Lion 下使用 MAMP 堆栈时 SOAP API 响应不完整

发布于 2024-12-23 02:20:54 字数 914 浏览 1 评论 0 原文

我使用soapUI 测试了Magento 的SOAP API。我成功登录并获得了登录哈希。 然后我尝试检索产品列表,效果很好。

这是在使用最新版本的 Apache、mySQL 和 PHP 的 Linux 服务器上进行的。

然后我创建了 Magento 和数据库的备份。我想使用 MAMP 堆栈在 Lion 服务器上创建一个测试环境。 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下响应不完整?

I tested Magento's SOAP API using soapUI. I successfully logged in and got a login hash.
Then I tried to retrieve a list of products and this worked fine.

This was on a Linux server using the latest version of Apache, mySQL and PHP.

I then created a backup of Magento and the database. I wanted to create a test environment on a Lion server using a MAMP stack. The Magento backup seems to work fine, but the SOAP API doesn't.

Again I used soapUI to get a login hash and tried to retrieve all products. But now the response seems to be incomplete:

<?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

Why is the reponse incomplete under Lion/MAMP?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧人九事 2024-12-30 02:20:54

我曾经遇到过 SOAP XML 响应不完整的问题。

设置如下所示:

  • Linux 服务器
  • Magento CE 1.5.1.0
  • 使用启用了 WS-I 合规性的 SOAP v2
  • 调用 sales_order.info

即使您使用不同的 Magento 版本和不同的 SOAP 调用,您也可以可能会遇到像我一样的错误。问题是响应的 HTTP Content-Length 标头计算不正确 > 8000 字节。

如何验证您是否受到此错误的影响

  1. 执行一个提供简短响应的调用(例如,只有一个商店视图和几个属性的“catalog_category.info”)。如果 XML 完整,请检查响应的长度是否 <= 8000 字节。
  2. 将文件 app/code/core/Mage/Api/Model/Server/Wsi/Adapter/Soap.php 复制到 app/code/local 文件夹并编辑 run() 方法。如果在 SOAP URL 中使用“wsdl”参数,请编辑“if”结构的第一部分,否则编辑“else”部分。

由于第二种方法是更准确的方法,所以我会采用这种方法。

  1. 打开文件并搜索 ->setBody() 方法调用。正如您所看到的,正在进行一些搜索/替换魔法。
  2. 将搜索/替换操作的结果写入变量并记录下来以供进一步检查。代码可能如下所示:

    公共函数run()
    {
        $apiConfigCharset = Mage::getStoreConfig("api/config/charset");
    
        if ($this->getController()->getRequest()->getParam('wsdl') !== null) {
            /* 不要修改第一部分... */
        } 别的 {
            尝试 {
                $this->_instantiateServer();
    
                $内容= preg_replace(
                        '/(\>\<)/i',
                        ">\n<",
                        字符串替换(
                                '',
                                "\n",
                                字符串替换(
                                        '',
                                        "\n",
                                        预替换(
                                            '/<\?xml 版本="([^\"]+)"([^\>]+)>/i',
                                            '',
                                            $this->_soap->handle()
                                        )
                                )
                        )
                );
                法师::log($content, null, 'soap.log');
                $this->getController()->getResponse()
                     -> 清除标题()
                     ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
                     ->setBody($内容);
            } catch( Zend_Soap_Server_Exception $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            } catch( 异常 $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            }
        }
    }
    
  3. 执行 SOAP API 调用并在 Magento 目录中打开 var/log/soap.log。如果日志文件中的 XML 完整,但响应中不完整,则 Content-Length 标头就是问题所在。

如何更正 Content-Length 标头

  1. 保留 Mage_Api_Model_Server_Wsi_Adapter_Soap 副本并向我们刚刚修改的代码添加一行:

    公共函数run()
    {
        $apiConfigCharset = Mage::getStoreConfig("api/config/charset");
    
        if ($this->getController()->getRequest()->getParam('wsdl') !== null) {
            /* 不要修改第一部分... */
        } 别的 {
            尝试 {
                $this->_instantiateServer();
    
                $内容= preg_replace(
                        '/(\>\<)/i',
                        ">\n<",
                        字符串替换(
                                '',
                                "\n",
                                字符串替换(
                                        '',
                                        "\n",
                                        预替换(
                                            '/<\?xml 版本="([^\"]+)"([^\>]+)>/i',
                                            '',
                                            $this->_soap->handle()
                                        )
                                )
                        )
                );
                法师::log($content, null, 'soap.log');
                $this->getController()->getResponse()
                     -> 清除标题()
                     ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
                     ->setHeader('内容长度',strlen($content), true)
                     ->setBody($内容);
            } catch( Zend_Soap_Server_Exception $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            } catch( 异常 $e ) {
                $this->fault( $e->getCode(), $e->getMessage() );
            }
        }
    }
    

    注意这一行:

    ->setHeader('内容长度',strlen($content), true)
    

    我们计算并设置 Content-Length 标头。第三个参数 true 很重要,因为它告诉框架覆盖现有的 Content-Length 标头。

  2. 如果这有效,请删除 Mage::log() 调用并重写代码以在您自己的扩展中使用。

如果您问为什么会出现此问题,我无法准确告诉您,因为我没有一路追查该错误。

据我所知,只要 XML 响应的长度 <= 8000 字节,一切都很好。如果响应长度超过 8000 字节且 XML 由 x 行组成,则响应将被截断 x 个字符。看起来这是不同的回车代码和/或编码问题的问题,导致响应内容长度的计算错误。

I had a problem with incomplete SOAP XML responses once.

The setup was like this:

  • Linux server
  • Magento CE 1.5.1.0
  • Usage of SOAP v2 with WS-I compliance enabled
  • Call of sales_order.info

Even if you use a different Magento version and a different SOAP call, you may suffer from a similar bug as I did. The problem was that the HTTP Content-Length header was calculated incorrectly for responses > 8000 bytes.

How to verify if you are affected by this bug:

  1. Execute a call which delivers a short response (e.g. "catalog_category.info" with just a single store-view and only few attributes). If the XML is complete, check if the response has a length <= 8000 bytes.
  2. Copy the file app/code/core/Mage/Api/Model/Server/Wsi/Adapter/Soap.php to your app/code/local folder and edit the run() method. If you use the "wsdl" parameter in your SOAP URL, edit the first part of the "if" structure, otherwise edit the "else" part.

As the second way is the more accurate way to do it, I'll go with this.

  1. Open the file and search for the ->setBody() method call. As you can see, there is some search/replace magic going on.
  2. Write the result of the search/replace operations into a variable and log it for further examination. The code may look like this:

    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. Execute the SOAP API call and open var/log/soap.log in your Magento directory. If the XML is complete in the log file but not in your response, then the Content-Length header is the problem.

How to correct the Content-Length header

  1. Stay in your copy of Mage_Api_Model_Server_Wsi_Adapter_Soap and add one line to the code we just modified:

    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() );
            }
        }
    }
    

    Note the line:

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

    We calculate and set the Content-Length header. The third parameter, true, is important because it tells the framework to overwrite the existing Content-Length header.

  2. If this works, remove the Mage::log() call and rewrite the code for use in your own extension.

If you ask why this problem occurs I can't tell you exactly because I didn't hunt the bug all the way down.

From what I saw, everything is fine as long as the XML response has a length <= 8000 bytes. If the response is longer than 8000 bytes and the XML consists of x lines, the response is truncated by x characters. It looks like it is a problem with the different carriage return codes and/or with encoding issues which lead to the wrong calculation of the response content length.

救星 2024-12-30 02:20:54

我认为您的 PHP 配置发生了变化。您可能会遇到 PHP.ini memory_limitmax_execution_time 错误。您应该能够通过在 Magento 根目录中的每个服务器上创建一个简单的文件(将文件放入 Magento 根目录中很重要,因为 .htaccess 文件可能会覆盖 PHP 设置)并比较值来比较 PHP 设置

: >info.php

<?php phpinfo();

您还可以检查 Apache 错误日志以获取更多信息。

I think that your PHP configuration changed. You're likely running into a PHP.ini memory_limit or max_execution_time error. You should be able to compare your PHP settings by creating a simple file on each server in your Magento root (it's important that you put the file in your Magento root because the .htaccess file might be overriding PHP settings) and comparing values:

info.php

<?php phpinfo();

You can also check your Apache error logs for additional information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文