Tuesday, February 5, 2013

PHP - cURL - Optimise Speed Reusing SSL Connections

Below is an example of using cURL to fetch multiple URLs that are using SSL and then reuse those connections to retrieve more data. This example fetches 2 URLs simultaneously which both open an SSL connection, then the next lot of 2 URLs reuse those connections to retrieve data thereby bypassing the SSL handshake.

<?php
//Number of SSL connections to use
$connections = 2;

//Array of URLs to retrieve using https
$urls = array();
$urls[] = 'https://www.googleapis.com/plus/v1/people/105381197794279347286?fields=displayName%2Cgender%2CobjectType&key=AIzaSyCFj15TpkchL4OUhLD1Q2zgxQnMb7v3XaM';
$urls[] = 'https://www.googleapis.com/plus/v1/people/105381197794279347286?fields=displayName%2Cgender%2CobjectType&key=AIzaSyCFj15TpkchL4OUhLD1Q2zgxQnMb7v3XaM';
$urls[] = 'https://www.googleapis.com/plus/v1/people/105381197794279347286?fields=displayName%2Cgender%2CobjectType&key=AIzaSyCFj15TpkchL4OUhLD1Q2zgxQnMb7v3XaM';
$urls[] = 'https://www.googleapis.com/plus/v1/people/105381197794279347286?fields=displayName%2Cgender%2CobjectType&key=AIzaSyCFj15TpkchL4OUhLD1Q2zgxQnMb7v3XaM';
$urls[] = 'https://www.googleapis.com/plus/v1/people/105381197794279347286?fields=displayName%2Cgender%2CobjectType&key=AIzaSyCFj15TpkchL4OUhLD1Q2zgxQnMb7v3XaM';
$urls[] = 'https://www.googleapis.com/plus/v1/people/105381197794279347286?fields=displayName%2Cgender%2CobjectType&key=AIzaSyCFj15TpkchL4OUhLD1Q2zgxQnMb7v3XaM';

//Number of times to reuse each SSL connection (6/2 = 3)
$reuse = count($urls) / $connections;

//Array used to store multiple cURL handles for each SSL connection
$handle = array();

//Array used to store all returned page data
$result = array();

//Log file used to see that only 2 SSL conections are being used
//$logfh = fopen("curl.log", 'a+');

//Loop for each SSL connection
for($r=0;$r<$reuse;$r++) {
  //Loop for each reuse of the SSL connection
  for($c=0;$c<$connections;$c++) {
    //Initialise a cURL session using the urls
    $handle[$c] = curl_init($urls[($r*$connections)+$c]);

    //Set any options you want here
    curl_setopt($handle[$c], CURLOPT_HTTPHEADER, array('x-origin: https://developers.google.com'));
    curl_setopt($handle[$c], CURLOPT_RETURNTRANSFER, true);
    //Turns on detailed info for the log
    //curl_setopt($handle[$c], CURLOPT_VERBOSE, true);
    //Send the output to the log file
    //curl_setopt($handle[$c], CURLOPT_STDERR, $logfh);

    static $multi = NULL;
    if (empty($multi)) {
      //Initialise a multi cURL session if one does not already exist
      $multi = curl_multi_init();
    }

    //Add the single cURL handle to the mutli cURL handle
    curl_multi_add_handle($multi, $handle[$c]);
  }

  $running = NULL;
  do {
    //Execute all handles in $multi until all are completed
    curl_multi_exec($multi, $running);
  } while($running > 0);

  for($i=0;$i<$connections;$i++) {
    //Do something with each result
    $result[] = curl_multi_getcontent($handle[$i]);
    //Remove the single cURL handle from the multi cURL handle
    curl_multi_remove_handle($multi, $handle[$i]);
  }
}
//Dump the result which will show my public profile info 6 times
var_dump($result);
?>

Output: This will output 6 arrays, one for each of the pages we retrieved. It will contain some public information from my Google+ profile.

Note: If you use the curl.log you must ensure you have the correct permissions on the file.

Post a Comment