Wednesday 26 November 2014

No response and catching errors cURL PHP

I covered this in another post however I thought it deserved its own "snippet". I use cURL when connecting to CRM's SOAP service as I found it easy to use almost right away.

Because I could use it right away I didn't really spend anytime thinking about it. That was until code that had been working for months suddenly stopped. I received no response from the service but I couldn't figure out why.

The investigation led me to the following function:
 public static function GetSOAPResponse($url, $request) {
    // Set up headers.
    $headers = array(
      "POST " . "/Organization.svc" . " HTTP/1.1",
      "Host: yourorganisation.api.crm5.dynamics.com",
      'Connection: Keep-Alive',
      "Content-type: application/soap+xml; charset=UTF-8",
      "Content-length: " . strlen($request),
    );
 
    $cURLHandle = curl_init();
    curl_setopt($cURLHandle, CURLOPT_URL, $url);
    curl_setopt($cURLHandle, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($cURLHandle, CURLOPT_TIMEOUT, 60);
    curl_setopt($cURLHandle, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($cURLHandle, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($cURLHandle, CURLOPT_SSLVERSION, 3);
    curl_setopt($cURLHandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($cURLHandle, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($cURLHandle, CURLOPT_POST, 1);
    curl_setopt($cURLHandle, CURLOPT_POSTFIELDS, $request);
    $response = curl_exec($cURLHandle);
    curl_close($cURLHandle);
 
    return $response;
  }

In such a small project such as this when something stops working the question is usually what dependencies have changed? I presumed something at the Microsoft end (I was using CRM Online) had changed but the question was what.

A quick Google search on curl_exec shows that it does not throw exceptions due to it being a C library all wrapped up. So in order to get an exception you need to instead use the following:
if( ! $response = curl_exec($cURLHandle)) 
   { 
       trigger_error(curl_error($cURLHandle)); 
   }

This will fire off a PHP exception for the cURL error. Which led me to my real issue!

Microsoft due to the 'poodle' vulnerability in SSL updated to SSL version 4. The code I had above (grabbed from some other persons post presumably!) has the SSL Version explicitly stated. By changing this to 4 the issue went away. However I thought it was easier to just remove that setting and this seemed to do the trick (and hopefully makes it a bit more robust for future use!). So the updated code is below.

public static function GetSOAPResponse($url, $request) {
   // Set up headers.
   $headers = array(
     "POST " . "/Organization.svc" . " HTTP/1.1",
     "Host: yourorganisation.api.crm5.dynamics.com",
     'Connection: Keep-Alive',
     "Content-type: application/soap+xml; charset=UTF-8",
     "Content-length: " . strlen($request),
   );
 
   $cURLHandle = curl_init();
   curl_setopt($cURLHandle, CURLOPT_URL, $url);
   curl_setopt($cURLHandle, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($cURLHandle, CURLOPT_TIMEOUT, 60);
   curl_setopt($cURLHandle, CURLOPT_SSL_VERIFYPEER, FALSE);
   curl_setopt($cURLHandle, CURLOPT_FOLLOWLOCATION, TRUE);
   curl_setopt($cURLHandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
   curl_setopt($cURLHandle, CURLOPT_HTTPHEADER, $headers);
   curl_setopt($cURLHandle, CURLOPT_POST, 1);
   curl_setopt($cURLHandle, CURLOPT_POSTFIELDS, $request);
   if( ! $response = curl_exec($cURLHandle)) 
   { 
       trigger_error(curl_error($cURLHandle)); 
   }
   curl_close($cURLHandle);
 
   return $response;
 }

No comments:

Post a Comment