public function AcquiaPurgeExecutorBase::requestsExecute in Acquia Purge 7
Execute a series of HTTP requests efficiently through cURL's multi handler.
Parameters
AcquiaPurgeExecutorRequestInterface[] $requests: Unassociative list of request objects created by ::getRequest(). The properties 'scheme', 'method', 'uri' are used for executing the request. The properties 'result', 'error_curl', 'response_code' and 'error_debug' are updated during execution.
string $no_ssl_verify: Skip host and peer verification, don't use for requests that include sensitive data (e.g. API keys).
Overrides AcquiaPurgeExecutorInterface::requestsExecute
1 call to AcquiaPurgeExecutorBase::requestsExecute()
- AcquiaPurgeExecutorAcquia::invalidate in lib/
executor/ AcquiaPurgeExecutorAcquia.php - Invalidate one or multiple paths from an external layer.
File
- lib/
executor/ AcquiaPurgeExecutorBase.php, line 114 - Contains AcquiaPurgeExecutorBase.
Class
- AcquiaPurgeExecutorBase
- Provides an executor, which is responsible for taking a set of invalidation objects and wiping these paths/URLs from an external cache.
Code
public function requestsExecute($requests, $no_ssl_verify = FALSE) {
$single_mode = count($requests) === 1;
$processed = array();
// Initialize the cURL multi handler.
if (!$single_mode) {
$curl_multi = curl_multi_init();
}
// Enter our event loop and keep on requesting until $unprocessed is empty.
$unprocessed = count($requests);
while ($unprocessed > 0) {
// Group requests per sets that we can run in parallel.
for ($i = 0; $i < AcquiaPurgeCapacity::HTTP_PARALLEL_REQUESTS; $i++) {
if ($r = array_shift($requests)) {
$r->curl = curl_init();
// Instantiate the cURL resource and configure its runtime parameters.
curl_setopt($r->curl, CURLOPT_URL, $r->uri);
curl_setopt($r->curl, CURLOPT_HTTPHEADER, $r->headers);
curl_setopt($r->curl, CURLOPT_CUSTOMREQUEST, $r->method);
curl_setopt($r->curl, CURLOPT_FAILONERROR, TRUE);
curl_setopt($r->curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($r->curl, CURLOPT_TIMEOUT, AcquiaPurgeCapacity::HTTP_REQUEST_TIMEOUT);
// For SSL purging, we disable SSL host and peer verification. This
// should trigger red flags to the security concerned user, but it
// also avoids purges to fail on sites with self-signed certs. This
// therefore is a risk worth taking in return for a better user
// experience as compromised cache invalidation requests couldn't
// cause much harm anyway.
if ($no_ssl_verify && $r->scheme === 'https') {
curl_setopt($r->curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($r->curl, CURLOPT_SSL_VERIFYPEER, FALSE);
}
// Add our handle to the multiple cURL handle.
if (!$single_mode) {
curl_multi_add_handle($curl_multi, $r->curl);
}
$processed[] = $r;
$unprocessed--;
}
}
// Execute the created handles in parallel.
if (!$single_mode) {
$active = NULL;
do {
$mrc = curl_multi_exec($curl_multi, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($curl_multi) != -1) {
do {
$mrc = curl_multi_exec($curl_multi, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
}
else {
curl_exec($processed[0]->curl);
$single_info = array(
'result' => curl_errno($processed[0]->curl),
);
}
// Iterate the set of results and fetch cURL result and resultcodes. Only
// process those with the 'curl' property as the property will be removed.
foreach ($processed as $i => $r) {
if (!isset($r->curl)) {
continue;
}
$info = $single_mode ? $single_info : curl_multi_info_read($curl_multi);
$processed[$i]->result = $info['result'] == CURLE_OK ? TRUE : FALSE;
$processed[$i]->error_curl = $info['result'];
$processed[$i]->response_code = curl_getinfo($r->curl, CURLINFO_HTTP_CODE);
// Collect debugging information if necessary.
$processed[$i]->error_debug = '';
if (!$processed[$i]->result) {
$debug = array(
'method' => $r->method,
'headers' => $r->headers,
);
$debug = array_merge($debug, curl_getinfo($r->curl));
unset($debug['certinfo']);
$processed[$i]->error_debug = $this
->exportDebugSymbols($debug);
}
// Remove the handle if parallel processing occurred.
if (!$single_mode) {
curl_multi_remove_handle($curl_multi, $r->curl);
}
curl_close($r->curl);
$r->curl = NULL;
}
}
if (!$single_mode) {
curl_multi_close($curl_multi);
}
}