Magento Soap API V2 Response Content Length Incorrect

北城余情 提交于 2019-12-05 02:17:02

问题


We are trying to connect our magento installation with a third party stock management app(built on .net). But the sync is not working, the third party tells me that the soap api is returning an empty response.

I have been pulling my hear out, because whenever I make anything in PHP the API works fine. In addition inventory updating works fine, but retrieving order/invoice information does not (well it actually does occasionally 1% of the time)

With the intermittent nature we felt that it must be a network issue, but after lots of searching and adding mage::log() into the core api files I can see that the connection is happening and further more the response object is being created by Magento.

So my deduction as that something was not right with the SOAP API (I am using version 2)

I have installed soapUI and setup our integration, it correctly receives the methods from the WSDL file but when I try to access the "login" method I get an empty response, even when I put in the incorrect login details it is empty.

soapUI outputs the following error:

ERROR:An error occured [Premature end of Content-Length delimited message body (expected: 267; received: 266], see error log for details

So it seems as though there is an issue with the http headers, some functions are able to return a response (of course without the login hash it is just invalid, but at least it is a response). From my (exceedingly limited) understanding of java and .net, they are much stricter on these things than php which would indicate why a php integration would have no issues.

Can anyone advise me why this error would occur and how to fix it?


回答1:


I'm going to assume you are using the WS-I compliant SOAP API v2 as I had this exact same issue; if not, then this still might apply. I was never able to connect to the v2 API without it being WS-I compliant, which is how I found this bug.

If you have a look at the app/code/core/Mage/Api/Model/Server/Wsi/Adapter/Soap.php file you will see in the public run function that is essentially split into two parts - 1 for the WSDL definition response and 1 for the actual SOAP response.

In the SOAP response there is a bit of string replacing going on, substituting <soap:operation soapAction=""></soap:operation> for <soap:operation soapAction="" /> and so on. This is evidently causing an issue with the content-length calculation - this is also occurring in the WSDL definition response, but it doesn't seem to be causing an issue.

I was able to successfully connect to the SOAP API by replacing the code between the try curly brackets with the code below. Basically, I ended up clearing the headers and recalculating the content-length AFTER the string replacement had taken place:

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

            $this->getController()->getResponse()
                      ->clearHeaders()
                      ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
                      ->setHeader('Content-Length',strlen($content))
                      ->setBody($content);

Hope this helps




回答2:


For reference if you are working with the V2 version you need to change:

/app/core/Mage/Api/Model/Server/V2/Adapter/Soap.php

About line 62 replace the contents of the try{} with:

$this->_instantiateServer();
$content = preg_replace(
    '/<\?xml version="([^\"]+)"([^\>]+)>/i',
    '<?xml version="$1" encoding="'.$apiConfigCharset.'"?>',
    $this->_soap->handle()
);
$this->getController()->getResponse()
    ->clearHeaders()
    ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
    ->setHeader('Content-Length',strlen($content))
    ->setBody($content);

This didin't fix everything for me, there were some instance of mysterious whitespace that was screwing everything up, one was a space after the closing tag, another was when a customer added two spaces on to the end of their phone number (??)

Anyway to clear these two I did...

This didn't fix everything for me, there were still some whitespace issues, I added a few extra preg_replace in order to fix it quickly

$content = preg_replace('/\s+/', ' ', $content);
$content = preg_replace('/Envelope> /', 'Envelope>', $content);



回答3:


The only solution which worked for me was to switch the API endpoint to NOT use index.php

The change was from: domain.com/index.php/api/v2_soap/index/wsdl/1

to: domain.com/api/v2_soap/?wsdl=1

Notice removed index.php from url. This way the request is going through api.php entrypoint instead of index.php. As a side effec the api started working much faster, as api.php more lightweight.

Steps to take:

  • make sure you have correct redirect rules set in nginx or .htaccess (see below)
  • clear Magento cache
  • open WSDL in browser (domain.com/api/v2_soap/?wsdl=1) and verify if it is correct. The soap:address node should not contain index.php part:

    <soap:address location="http://domain.com/api.php/?type=v2_soap"/>

  • use domain.com/api/v2_soap/?wsdl=1 url in your client script

Nginx configuration:

location /api {
    rewrite ^/api/rest /api.php?type=rest last;
    rewrite ^/api/v2_soap /api.php?type=v2_soap last;
    rewrite ^/api/soap /api.php?type=soap last;
}

Apache .htaccess:

uncomment line:

RewriteRule ^api/([a-z][0-9a-z_]+)/?$ api.php?type=$1 [QSA,L]

Other solutions that did not work form me:

  • editing V2/Adapter/Soap.php
  • editing Wsi/Adapter/Soap.php

I'm working on Magento 1.9.2.4



来源:https://stackoverflow.com/questions/12792563/magento-soap-api-v2-response-content-length-incorrect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!