Rectangle 27 3

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

This is super thanks, I am using v2 and so I had to change another file. Unfortunately I am still getting the same issue, one byte is still going missing, is there anywhere else that the body could be being changed?

BTW a quick fix at the moment is ->setHeader('Content-Length',strlen($content)-1)

@Zyava - quite possibly, I didn't enter the link in my comments (which I normally do for this exact reason) and it was over a year ago that I had the issue

I am marking this as the correct answer, I was using the v2 API and so for reference I will create an answer below which includes the fix for that situation. All of my requests were out by 1 byte and so the -1 fix works well for me, I can't understand where that byte is going, but I have more important things in life.

Magento Soap API V2 Response Content Length Incorrect - Stack Overflow

api magento soap magento-1.7
Rectangle 27 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 (??)

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

Magento Soap API V2 Response Content Length Incorrect - Stack Overflow

api magento soap magento-1.7
Rectangle 27 6

Yes, you can, and I'll show you below, but remember that the point of a SOAP API is to abstract all that XML stuff away and let you deal with the native objects of your programming system (in this case, PHP).

PHP's native SOAP client implementation has debugging methods which will allow you view the request and response for the last soap request made. You'll need to instantiate your client object with the trace option.

$proxy = new SoapClient('http://www.MAGENTO.co.uk/api/v2_soap/?wsdl', array('trace' => 1));

and then you should be able to do something like this

//could echo as well, I always `var_dump` first in case of unexpected results
var_dump($proxy->__getLastRequestHeaders());

var_dump($proxy->__getLastRequest());

var_dump($proxy->__getLastResponseHeaders());

var_dump($proxy->__getLastResponse());

The __getLastResponse method should return the raw SOAP XML.

thank you so much this is perfect. A quick other question, do you know if there is a way to extract the orders with the address details included or must these be queried separately?

Excellent answer, you saved me after hours of digging in the code !

Magento Soap Api (v2), how to show XML response - Stack Overflow

xml api magento soap
Rectangle 27 1

The problem you're experiencing is that .NET/C# is having trouble parsing the content type Magento is sending along with it's response. SOAP is notoriously finicky about receiving just the right stuff in just the right format. Couple that with PHP's rather poor implementation of the protocol and you're in for a lot of fun.

I'm looking at a Magento 1.9 for the following information:

app/code/core/Mage/Api/Model/Server/V2/Adapter/Soap.php
51. ->clearHeaders()
52. ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset)
53. ->setBod...

Note that that Content-Type header matches your text/xml; charset=utf-8 desired charset. Adjusting line 52 to:

52. ->setHeader('Content-Type','text/xml; charset='.$apiConfigCharset, true)

tells Magento to force overwriting that header if it's already set.

Make sure to make a copy of the file with it's full path to the app/code/local/Mage/... to avoid overwriting core files. You'll thank me when you want to upgrade Magento at some point.

Also, make sure to look carefully, there's two setHeader() calls in that file.

And finally, there's also a WS-I compliant SOAP adapter available, the same fix applies to that file. You can find it in app/code/core/Mage/Api/Model/Server/Wsi/Adapter/Soap.php.

php - Problems calling Magento SOAP V2 Service in C# - Stack Overflow

c# php magento iis soap
Rectangle 27 0

Yes, you can, and I'll show you below, but remember that the point of a SOAP API is to abstract all that XML stuff away and let you deal with the native objects of your programming system (in this case, PHP).

PHP's native SOAP client implementation has debugging methods which will allow you view the request and response for the last soap request made. You'll need to instantiate your client object with the trace option.

$proxy = new SoapClient('http://www.MAGENTO.co.uk/api/v2_soap/?wsdl', array('trace' => 1));

and then you should be able to do something like this

//could echo as well, I always `var_dump` first in case of unexpected results
var_dump($proxy->__getLastRequestHeaders());

var_dump($proxy->__getLastRequest());

var_dump($proxy->__getLastResponseHeaders());

var_dump($proxy->__getLastResponse());

The __getLastResponse method should return the raw SOAP XML.

thank you so much this is perfect. A quick other question, do you know if there is a way to extract the orders with the address details included or must these be queried separately?

Magento Soap Api (v2), how to show XML response - Stack Overflow

xml api magento soap
Rectangle 27 0

The wsdl.xml had a small mis-configuration in the following line:

<binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>

Magento WSI SOAP v2 API Custom Webservice Returns Empty Response - Sta...

api magento soap
Rectangle 27 0

Other solutions that did not work form me:

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

domain.com/index.php/api/v2_soap/index/wsdl/1
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.

  • make sure you have correct redirect rules set in nginx or .htaccess (see below)

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

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;
}
RewriteRule ^api/([a-z][0-9a-z_]+)/?$ api.php?type=$1 [QSA,L]

Magento Soap API V2 Response Content Length Incorrect - Stack Overflow

api magento soap magento-1.7
Rectangle 27 0

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/core/Mage/Api/Model/Server/Wsi/Adapyter/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);

This is super thanks, I am using v2 and so I had to change another file. Unfortunately I am still getting the same issue, one byte is still going missing, is there anywhere else that the body could be being changed?

BTW a quick fix at the moment is ->setHeader('Content-Length',strlen($content)-1)

@Zyava - quite possibly, I didn't enter the link in my comments (which I normally do for this exact reason) and it was over a year ago that I had the issue

I am marking this as the correct answer, I was using the v2 API and so for reference I will create an answer below which includes the fix for that situation. All of my requests were out by 1 byte and so the -1 fix works well for me, I can't understand where that byte is going, but I have more important things in life.

Magento Soap API V2 Response Content Length Incorrect - Stack Overflow

api magento soap magento-1.7
Rectangle 27 0

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

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

Magento Soap API V2 Response Content Length Incorrect - Stack Overflow

api magento soap magento-1.7