8

I am executing the following php code while trying to get request from a SOAP API server

try {
    $soap = new SoapClient($wsdl, $options);
    $data = $soap->GetXYZ($params);
}
catch(Exception $e) {
    $Lastresponse = $soap->__getLastResponse();
}

All I got was "looks like we got no XML document" response code.

But when I looked at the $Lastresponse variable in the catch block, I found it as below:

------=_Part_1134075_393252946.1482317378966 Content-Type: application/xop+xml; charset=utf-8; type="text/xml" <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> ......all valid data ... </SOAP-ENV:Body> </SOAP-ENV:Envelope> ------=_Part_1134075_393252946.1482317378966--

Note: the $options parameters I am using is:

$options = array(
    'uri'=>'http://schemas.xmlsoap.org/soap/envelope/',
    //'style'=>SOAP_RPC,
    //'use'=>SOAP_ENCODED,
    'soap_version'=>SOAP_1_1,
    'cache_wsdl'=>WSDL_CACHE_NONE,
    'connection_timeout'=>15,
    'trace'=>true,
    'encoding'=>'UTF-8',
    'exceptions'=>true
);

Although I did a workaround to parse the xml, does anyone has any idea about those extra -----Part bits? Is there something I am doing wrong?

Ashok Poudel
  • 266
  • 3
  • 16
  • 1
    and what is the thrown Exception? – alepeino Dec 27 '16 at 12:43
  • Problem seems to be from SOAP Server. Server is injecting the headers in the request. – anwerj Dec 30 '16 at 14:19
  • in php the starting space of the file ie – Nishant Nair Dec 31 '16 at 14:30
  • your Soap Client doesn't properly understand the HTTP protocol, i'd say fix your client (if you'd use CURL as a backend instead of raw sockets, CURL would handle it for you, but if you want raw sockets.. fix your http protocol implementation) – hanshenrik Jan 02 '17 at 16:50
  • Following on from @hanshenrik this is the multi part encoding and it's part of HTTP1.1 specification it's also used in emails for Attachments and used for multi type messages E.G Plain Text and HTML format inside a single message – Barkermn01 Jan 03 '17 at 03:40

3 Answers3

5

Those -----Part things are called the boundary in multipart messages explained here and defined in RFC2387.

After an investigation, it seems that SoapClient is incapable of parsing multipart messages, which is why you got that exception.

The solution is to extend SoapClient to extract the XML content with regex or other string functions. Here is an example from this page:

class MySoapClient extends SoapClient {
    public function __doRequest($request, $location, $action, $version, $one_way = 0) { 
        $response = parent::__doRequest($request, $location, $action, $version, $one_way);
        $start = strpos($response,'<?xml'); 
        $end = strrpos($response,'>'); 
        return substr($response,$start,$end-$start+1);
    }
}
Community
  • 1
  • 1
Rei
  • 6,263
  • 14
  • 28
  • `__getLastResponse()` is a low level method, more for debugging. The OP is asking why the exception is thrown. Unfortunately he does not provide enough information to answer that. – ThW Dec 29 '16 at 20:33
2

Requesting you to try out using below query

            $headers = array(
            "POST: ".url." HTTP/1.1",
            "Host: ".domain."",
            "Accept-Encoding: gzip,deflate",
            "Content-type: text/xml;charset=UTF-8",
            "SOAPAction: \"http://tempuri.org/wsdlurl/methodname\"",
            "Connection: Keep-Alive",
            "Content-length:".strlen($xml),
            "User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
            "
            )

    $url = your url;
    $ch = curl_init();      
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_ENCODING, '');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $options); // the SOAP request
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);     
    $response = curl_exec($ch);
    $err = curl_error($ch);
    $doc = new DOMDocument();
    $doc->loadXML( $response );     
    $authKey = $doc->getElementsByTagName( "fieldname" );
Nishant Nair
  • 1,999
  • 1
  • 13
  • 18
2

You are to catch Exception:

SoapClient::SoapClient() will generate an E_ERROR error if the location and uri options aren't provided in non-WSDL mode.

A SoapFault exception will be thrown if the wsdl URI cannot be loaded.

Community
  • 1
  • 1