Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unwanted Strings attached in the start and end of a SOAP response in PHP SoapClient

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?

like image 376
Ashok Poudel Avatar asked Dec 21 '16 12:12

Ashok Poudel


3 Answers

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);
    }
}
like image 144
Rei Avatar answered Oct 17 '22 16:10

Rei


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" );
like image 23
Nishant Nair Avatar answered Oct 17 '22 16:10

Nishant Nair


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.

like image 2
Ravshan Abdulaev Avatar answered Oct 17 '22 16:10

Ravshan Abdulaev