/usr/share/php/GuzzleHttp/Ring/Client/CurlHandler.php is in php-guzzlehttp-ringphp 1.1.0-2ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | <?php
namespace GuzzleHttp\Ring\Client;
use GuzzleHttp\Ring\Future\CompletedFutureArray;
use GuzzleHttp\Ring\Core;
/**
* HTTP handler that uses cURL easy handles as a transport layer.
*
* Requires PHP 5.5+
*
* When using the CurlHandler, custom curl options can be specified as an
* associative array of curl option constants mapping to values in the
* **curl** key of the "client" key of the request.
*/
class CurlHandler
{
/** @var callable */
private $factory;
/** @var array Array of curl easy handles */
private $handles = [];
/** @var array Array of owned curl easy handles */
private $ownedHandles = [];
/** @var int Total number of idle handles to keep in cache */
private $maxHandles;
/**
* Accepts an associative array of options:
*
* - factory: Optional callable factory used to create cURL handles.
* The callable is passed a request hash when invoked, and returns an
* array of the curl handle, headers resource, and body resource.
* - max_handles: Maximum number of idle handles (defaults to 5).
*
* @param array $options Array of options to use with the handler
*/
public function __construct(array $options = [])
{
$this->handles = $this->ownedHandles = [];
$this->factory = isset($options['handle_factory'])
? $options['handle_factory']
: new CurlFactory();
$this->maxHandles = isset($options['max_handles'])
? $options['max_handles']
: 5;
}
public function __destruct()
{
foreach ($this->handles as $handle) {
if (is_resource($handle)) {
curl_close($handle);
}
}
}
/**
* @param array $request
*
* @return CompletedFutureArray
*/
public function __invoke(array $request)
{
return new CompletedFutureArray(
$this->_invokeAsArray($request)
);
}
/**
* @internal
*
* @param array $request
*
* @return array
*/
public function _invokeAsArray(array $request)
{
$factory = $this->factory;
// Ensure headers are by reference. They're updated elsewhere.
$result = $factory($request, $this->checkoutEasyHandle());
$h = $result[0];
$hd =& $result[1];
$bd = $result[2];
Core::doSleep($request);
curl_exec($h);
$response = ['transfer_stats' => curl_getinfo($h)];
$response['curl']['error'] = curl_error($h);
$response['curl']['errno'] = curl_errno($h);
$response['transfer_stats'] = array_merge($response['transfer_stats'], $response['curl']);
$this->releaseEasyHandle($h);
return CurlFactory::createResponse([$this, '_invokeAsArray'], $request, $response, $hd, $bd);
}
private function checkoutEasyHandle()
{
// Find an unused handle in the cache
if (false !== ($key = array_search(false, $this->ownedHandles, true))) {
$this->ownedHandles[$key] = true;
return $this->handles[$key];
}
// Add a new handle
$handle = curl_init();
$id = (int) $handle;
$this->handles[$id] = $handle;
$this->ownedHandles[$id] = true;
return $handle;
}
private function releaseEasyHandle($handle)
{
$id = (int) $handle;
if (count($this->ownedHandles) > $this->maxHandles) {
curl_close($this->handles[$id]);
unset($this->handles[$id], $this->ownedHandles[$id]);
} else {
// curl_reset doesn't clear these out for some reason
static $unsetValues = [
CURLOPT_HEADERFUNCTION => null,
CURLOPT_WRITEFUNCTION => null,
CURLOPT_READFUNCTION => null,
CURLOPT_PROGRESSFUNCTION => null,
];
curl_setopt_array($handle, $unsetValues);
curl_reset($handle);
$this->ownedHandles[$id] = false;
}
}
}
|