1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Guzzle\Http; |
4
|
|
|
|
5
|
|
|
use Guzzle\Common\Collection; |
6
|
|
|
use Guzzle\Common\AbstractHasDispatcher; |
7
|
|
|
use Guzzle\Common\Exception\ExceptionCollection; |
8
|
|
|
use Guzzle\Common\Exception\InvalidArgumentException; |
9
|
|
|
use Guzzle\Common\Exception\RuntimeException; |
10
|
|
|
use Guzzle\Common\Version; |
11
|
|
|
use Guzzle\Parser\ParserRegistry; |
12
|
|
|
use Guzzle\Parser\UriTemplate\UriTemplateInterface; |
13
|
|
|
use Guzzle\Http\Message\RequestInterface; |
14
|
|
|
use Guzzle\Http\Message\RequestFactory; |
15
|
|
|
use Guzzle\Http\Message\RequestFactoryInterface; |
16
|
|
|
use Guzzle\Http\Curl\CurlMultiInterface; |
17
|
|
|
use Guzzle\Http\Curl\CurlMultiProxy; |
18
|
|
|
use Guzzle\Http\Curl\CurlHandle; |
19
|
|
|
use Guzzle\Http\Curl\CurlVersion; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* HTTP client |
23
|
|
|
*/ |
24
|
|
|
class Client extends AbstractHasDispatcher implements ClientInterface |
25
|
|
|
{ |
26
|
|
|
/** @deprecated Use [request.options][params] */ |
27
|
|
|
const REQUEST_PARAMS = 'request.params'; |
28
|
|
|
|
29
|
|
|
const REQUEST_OPTIONS = 'request.options'; |
30
|
|
|
const CURL_OPTIONS = 'curl.options'; |
31
|
|
|
const SSL_CERT_AUTHORITY = 'ssl.certificate_authority'; |
32
|
|
|
const DISABLE_REDIRECTS = RedirectPlugin::DISABLE; |
33
|
|
|
const DEFAULT_SELECT_TIMEOUT = 1.0; |
34
|
|
|
const MAX_HANDLES = 3; |
35
|
|
|
|
36
|
|
|
/** @var Collection Default HTTP headers to set on each request */ |
37
|
|
|
protected $defaultHeaders; |
38
|
|
|
|
39
|
|
|
/** @var string The user agent string to set on each request */ |
40
|
|
|
protected $userAgent; |
41
|
|
|
|
42
|
|
|
/** @var Collection Parameter object holding configuration data */ |
43
|
|
|
private $config; |
44
|
|
|
|
45
|
|
|
/** @var Url Base URL of the client */ |
46
|
|
|
private $baseUrl; |
47
|
|
|
|
48
|
|
|
/** @var CurlMultiInterface CurlMulti object used internally */ |
49
|
|
|
private $curlMulti; |
50
|
|
|
|
51
|
|
|
/** @var UriTemplateInterface URI template owned by the client */ |
52
|
|
|
private $uriTemplate; |
53
|
|
|
|
54
|
|
|
/** @var RequestFactoryInterface Request factory used by the client */ |
55
|
|
|
protected $requestFactory; |
56
|
|
|
|
57
|
|
|
public static function getAllEvents() |
58
|
|
|
{ |
59
|
|
|
return array(self::CREATE_REQUEST); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* @param string $baseUrl Base URL of the web service |
64
|
|
|
* @param array|Collection $config Configuration settings |
65
|
|
|
* |
66
|
|
|
* @throws RuntimeException if cURL is not installed |
67
|
|
|
*/ |
68
|
|
|
public function __construct($baseUrl = '', $config = null) |
69
|
|
|
{ |
70
|
|
|
if (!extension_loaded('curl')) { |
71
|
|
|
// @codeCoverageIgnoreStart |
72
|
|
|
throw new RuntimeException('The PHP cURL extension must be installed to use Guzzle.'); |
73
|
|
|
// @codeCoverageIgnoreEnd |
74
|
|
|
} |
75
|
|
|
$this->setConfig($config ?: new Collection()); |
76
|
|
|
$this->initSsl(); |
77
|
|
|
$this->setBaseUrl($baseUrl); |
78
|
|
|
$this->defaultHeaders = new Collection(); |
79
|
|
|
$this->setRequestFactory(RequestFactory::getInstance()); |
80
|
|
|
$this->userAgent = $this->getDefaultUserAgent(); |
81
|
|
|
if (!$this->config[self::DISABLE_REDIRECTS]) { |
82
|
|
|
$this->addSubscriber(new RedirectPlugin()); |
83
|
|
|
} |
84
|
|
|
} |
85
|
|
|
|
86
|
|
View Code Duplication |
final public function setConfig($config) |
|
|
|
|
87
|
|
|
{ |
88
|
|
|
if ($config instanceof Collection) { |
89
|
|
|
$this->config = $config; |
90
|
|
|
} elseif (is_array($config)) { |
91
|
|
|
$this->config = new Collection($config); |
92
|
|
|
} else { |
93
|
|
|
throw new InvalidArgumentException('Config must be an array or Collection'); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
return $this; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
final public function getConfig($key = false) |
100
|
|
|
{ |
101
|
|
|
return $key ? $this->config[$key] : $this->config; |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Set a default request option on the client that will be used as a default for each request |
106
|
|
|
* |
107
|
|
|
* @param string $keyOrPath request.options key (e.g. allow_redirects) or path to a nested key (e.g. headers/foo) |
108
|
|
|
* @param mixed $value Value to set |
109
|
|
|
* |
110
|
|
|
* @return $this |
111
|
|
|
*/ |
112
|
|
|
public function setDefaultOption($keyOrPath, $value) |
113
|
|
|
{ |
114
|
|
|
$keyOrPath = self::REQUEST_OPTIONS . '/' . $keyOrPath; |
115
|
|
|
$this->config->setPath($keyOrPath, $value); |
116
|
|
|
|
117
|
|
|
return $this; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* Retrieve a default request option from the client |
122
|
|
|
* |
123
|
|
|
* @param string $keyOrPath request.options key (e.g. allow_redirects) or path to a nested key (e.g. headers/foo) |
124
|
|
|
* |
125
|
|
|
* @return mixed|null |
126
|
|
|
*/ |
127
|
|
|
public function getDefaultOption($keyOrPath) |
128
|
|
|
{ |
129
|
|
|
$keyOrPath = self::REQUEST_OPTIONS . '/' . $keyOrPath; |
130
|
|
|
|
131
|
|
|
return $this->config->getPath($keyOrPath); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
final public function setSslVerification($certificateAuthority = true, $verifyPeer = true, $verifyHost = 2) |
135
|
|
|
{ |
136
|
|
|
$opts = $this->config[self::CURL_OPTIONS] ?: array(); |
137
|
|
|
|
138
|
|
|
if ($certificateAuthority === true) { |
139
|
|
|
// use bundled CA bundle, set secure defaults |
140
|
|
|
$opts[CURLOPT_CAINFO] = __DIR__ . '/Resources/cacert.pem'; |
141
|
|
|
$opts[CURLOPT_SSL_VERIFYPEER] = true; |
142
|
|
|
$opts[CURLOPT_SSL_VERIFYHOST] = 2; |
143
|
|
View Code Duplication |
} elseif ($certificateAuthority === false) { |
|
|
|
|
144
|
|
|
unset($opts[CURLOPT_CAINFO]); |
145
|
|
|
$opts[CURLOPT_SSL_VERIFYPEER] = false; |
146
|
|
|
$opts[CURLOPT_SSL_VERIFYHOST] = 0; |
147
|
|
|
} elseif ($verifyPeer !== true && $verifyPeer !== false && $verifyPeer !== 1 && $verifyPeer !== 0) { |
148
|
|
|
throw new InvalidArgumentException('verifyPeer must be 1, 0 or boolean'); |
149
|
|
|
} elseif ($verifyHost !== 0 && $verifyHost !== 1 && $verifyHost !== 2) { |
150
|
|
|
throw new InvalidArgumentException('verifyHost must be 0, 1 or 2'); |
151
|
|
|
} else { |
152
|
|
|
$opts[CURLOPT_SSL_VERIFYPEER] = $verifyPeer; |
153
|
|
|
$opts[CURLOPT_SSL_VERIFYHOST] = $verifyHost; |
154
|
|
|
if (is_file($certificateAuthority)) { |
155
|
|
|
unset($opts[CURLOPT_CAPATH]); |
156
|
|
|
$opts[CURLOPT_CAINFO] = $certificateAuthority; |
157
|
|
|
} elseif (is_dir($certificateAuthority)) { |
158
|
|
|
unset($opts[CURLOPT_CAINFO]); |
159
|
|
|
$opts[CURLOPT_CAPATH] = $certificateAuthority; |
160
|
|
|
} else { |
161
|
|
|
throw new RuntimeException( |
162
|
|
|
'Invalid option passed to ' . self::SSL_CERT_AUTHORITY . ': ' . $certificateAuthority |
163
|
|
|
); |
164
|
|
|
} |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
$this->config->set(self::CURL_OPTIONS, $opts); |
168
|
|
|
|
169
|
|
|
return $this; |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
public function createRequest($method = 'GET', $uri = null, $headers = null, $body = null, array $options = array()) |
173
|
|
|
{ |
174
|
|
|
if (!$uri) { |
175
|
|
|
$url = $this->getBaseUrl(); |
176
|
|
|
} else { |
177
|
|
|
if (!is_array($uri)) { |
178
|
|
|
$templateVars = null; |
179
|
|
|
} else { |
180
|
|
|
list($uri, $templateVars) = $uri; |
181
|
|
|
} |
182
|
|
|
if (strpos($uri, '://')) { |
183
|
|
|
// Use absolute URLs as-is |
184
|
|
|
$url = $this->expandTemplate($uri, $templateVars); |
185
|
|
|
} else { |
186
|
|
|
$url = Url::factory($this->getBaseUrl())->combine($this->expandTemplate($uri, $templateVars)); |
|
|
|
|
187
|
|
|
} |
188
|
|
|
} |
189
|
|
|
|
190
|
|
|
// If default headers are provided, then merge them under any explicitly provided headers for the request |
191
|
|
|
if (count($this->defaultHeaders)) { |
192
|
|
|
if (!$headers) { |
193
|
|
|
$headers = $this->defaultHeaders->toArray(); |
194
|
|
|
} elseif (is_array($headers)) { |
195
|
|
|
$headers += $this->defaultHeaders->toArray(); |
196
|
|
|
} elseif ($headers instanceof Collection) { |
197
|
|
|
$headers = $headers->toArray() + $this->defaultHeaders->toArray(); |
198
|
|
|
} |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
return $this->prepareRequest($this->requestFactory->create($method, (string) $url, $headers, $body), $options); |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
public function getBaseUrl($expand = true) |
205
|
|
|
{ |
206
|
|
|
return $expand ? $this->expandTemplate($this->baseUrl) : $this->baseUrl; |
|
|
|
|
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
public function setBaseUrl($url) |
210
|
|
|
{ |
211
|
|
|
$this->baseUrl = $url; |
|
|
|
|
212
|
|
|
|
213
|
|
|
return $this; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
public function setUserAgent($userAgent, $includeDefault = false) |
217
|
|
|
{ |
218
|
|
|
if ($includeDefault) { |
219
|
|
|
$userAgent .= ' ' . $this->getDefaultUserAgent(); |
220
|
|
|
} |
221
|
|
|
$this->userAgent = $userAgent; |
222
|
|
|
|
223
|
|
|
return $this; |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Get the default User-Agent string to use with Guzzle |
228
|
|
|
* |
229
|
|
|
* @return string |
230
|
|
|
*/ |
231
|
|
|
public function getDefaultUserAgent() |
232
|
|
|
{ |
233
|
|
|
return 'Guzzle/' . Version::VERSION |
234
|
|
|
. ' curl/' . CurlVersion::getInstance()->get('version') |
235
|
|
|
. ' PHP/' . PHP_VERSION; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
public function get($uri = null, $headers = null, $options = array()) |
239
|
|
|
{ |
240
|
|
|
// BC compat: $options can be a string, resource, etc to specify where the response body is downloaded |
241
|
|
|
return is_array($options) |
242
|
|
|
? $this->createRequest('GET', $uri, $headers, null, $options) |
243
|
|
|
: $this->createRequest('GET', $uri, $headers, $options); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
public function head($uri = null, $headers = null, array $options = array()) |
247
|
|
|
{ |
248
|
|
|
return $this->createRequest('HEAD', $uri, $headers, null, $options); |
249
|
|
|
} |
250
|
|
|
|
251
|
|
|
public function delete($uri = null, $headers = null, $body = null, array $options = array()) |
252
|
|
|
{ |
253
|
|
|
return $this->createRequest('DELETE', $uri, $headers, $body, $options); |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
public function put($uri = null, $headers = null, $body = null, array $options = array()) |
257
|
|
|
{ |
258
|
|
|
return $this->createRequest('PUT', $uri, $headers, $body, $options); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
public function patch($uri = null, $headers = null, $body = null, array $options = array()) |
262
|
|
|
{ |
263
|
|
|
return $this->createRequest('PATCH', $uri, $headers, $body, $options); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
public function post($uri = null, $headers = null, $postBody = null, array $options = array()) |
267
|
|
|
{ |
268
|
|
|
return $this->createRequest('POST', $uri, $headers, $postBody, $options); |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
public function options($uri = null, array $options = array()) |
272
|
|
|
{ |
273
|
|
|
return $this->createRequest('OPTIONS', $uri, $options); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
public function send($requests) |
277
|
|
|
{ |
278
|
|
|
if (!($requests instanceof RequestInterface)) { |
279
|
|
|
return $this->sendMultiple($requests); |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
try { |
283
|
|
|
/** @var $requests RequestInterface */ |
284
|
|
|
$this->getCurlMulti()->add($requests)->send(); |
285
|
|
|
return $requests->getResponse(); |
286
|
|
|
} catch (ExceptionCollection $e) { |
287
|
|
|
throw $e->getFirst(); |
288
|
|
|
} |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
/** |
292
|
|
|
* Set a curl multi object to be used internally by the client for transferring requests. |
293
|
|
|
* |
294
|
|
|
* @param CurlMultiInterface $curlMulti Multi object |
295
|
|
|
* |
296
|
|
|
* @return self |
297
|
|
|
*/ |
298
|
|
|
public function setCurlMulti(CurlMultiInterface $curlMulti) |
299
|
|
|
{ |
300
|
|
|
$this->curlMulti = $curlMulti; |
301
|
|
|
|
302
|
|
|
return $this; |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* @return CurlMultiInterface|CurlMultiProxy |
307
|
|
|
*/ |
308
|
|
|
public function getCurlMulti() |
309
|
|
|
{ |
310
|
|
|
if (!$this->curlMulti) { |
311
|
|
|
$this->curlMulti = new CurlMultiProxy( |
312
|
|
|
self::MAX_HANDLES, |
313
|
|
|
$this->getConfig('select_timeout') ?: self::DEFAULT_SELECT_TIMEOUT |
|
|
|
|
314
|
|
|
); |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
return $this->curlMulti; |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
public function setRequestFactory(RequestFactoryInterface $factory) |
321
|
|
|
{ |
322
|
|
|
$this->requestFactory = $factory; |
323
|
|
|
|
324
|
|
|
return $this; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* Set the URI template expander to use with the client |
329
|
|
|
* |
330
|
|
|
* @param UriTemplateInterface $uriTemplate URI template expander |
331
|
|
|
* |
332
|
|
|
* @return self |
333
|
|
|
*/ |
334
|
|
|
public function setUriTemplate(UriTemplateInterface $uriTemplate) |
335
|
|
|
{ |
336
|
|
|
$this->uriTemplate = $uriTemplate; |
337
|
|
|
|
338
|
|
|
return $this; |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* Expand a URI template while merging client config settings into the template variables |
343
|
|
|
* |
344
|
|
|
* @param string $template Template to expand |
345
|
|
|
* @param array $variables Variables to inject |
346
|
|
|
* |
347
|
|
|
* @return string |
348
|
|
|
*/ |
349
|
|
|
protected function expandTemplate($template, array $variables = null) |
350
|
|
|
{ |
351
|
|
|
$expansionVars = $this->getConfig()->toArray(); |
352
|
|
|
if ($variables) { |
353
|
|
|
$expansionVars = $variables + $expansionVars; |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
return $this->getUriTemplate()->expand($template, $expansionVars); |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* Get the URI template expander used by the client |
361
|
|
|
* |
362
|
|
|
* @return UriTemplateInterface |
363
|
|
|
*/ |
364
|
|
|
protected function getUriTemplate() |
365
|
|
|
{ |
366
|
|
|
if (!$this->uriTemplate) { |
367
|
|
|
$this->uriTemplate = ParserRegistry::getInstance()->getParser('uri_template'); |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
return $this->uriTemplate; |
371
|
|
|
} |
372
|
|
|
|
373
|
|
|
/** |
374
|
|
|
* Send multiple requests in parallel |
375
|
|
|
* |
376
|
|
|
* @param array $requests Array of RequestInterface objects |
377
|
|
|
* |
378
|
|
|
* @return array Returns an array of Response objects |
379
|
|
|
*/ |
380
|
|
|
protected function sendMultiple(array $requests) |
381
|
|
|
{ |
382
|
|
|
$curlMulti = $this->getCurlMulti(); |
383
|
|
|
foreach ($requests as $request) { |
384
|
|
|
$curlMulti->add($request); |
385
|
|
|
} |
386
|
|
|
$curlMulti->send(); |
387
|
|
|
|
388
|
|
|
/** @var $request RequestInterface */ |
389
|
|
|
$result = array(); |
390
|
|
|
foreach ($requests as $request) { |
391
|
|
|
$result[] = $request->getResponse(); |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
return $result; |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
/** |
398
|
|
|
* Prepare a request to be sent from the Client by adding client specific behaviors and properties to the request. |
399
|
|
|
* |
400
|
|
|
* @param RequestInterface $request Request to prepare for the client |
401
|
|
|
* @param array $options Options to apply to the request |
402
|
|
|
* |
403
|
|
|
* @return RequestInterface |
404
|
|
|
*/ |
405
|
|
|
protected function prepareRequest(RequestInterface $request, array $options = array()) |
406
|
|
|
{ |
407
|
|
|
$request->setClient($this)->setEventDispatcher(clone $this->getEventDispatcher()); |
408
|
|
|
|
409
|
|
|
if ($curl = $this->config[self::CURL_OPTIONS]) { |
410
|
|
|
$request->getCurlOptions()->overwriteWith(CurlHandle::parseCurlConfig($curl)); |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
if ($params = $this->config[self::REQUEST_PARAMS]) { |
|
|
|
|
414
|
|
|
Version::warn('request.params is deprecated. Use request.options to add default request options.'); |
415
|
|
|
$request->getParams()->overwriteWith($params); |
416
|
|
|
} |
417
|
|
|
|
418
|
|
|
if ($this->userAgent && !$request->hasHeader('User-Agent')) { |
419
|
|
|
$request->setHeader('User-Agent', $this->userAgent); |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
if ($defaults = $this->config[self::REQUEST_OPTIONS]) { |
423
|
|
|
$this->requestFactory->applyOptions($request, $defaults, RequestFactoryInterface::OPTIONS_AS_DEFAULTS); |
424
|
|
|
} |
425
|
|
|
|
426
|
|
|
if ($options) { |
|
|
|
|
427
|
|
|
$this->requestFactory->applyOptions($request, $options); |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
$this->dispatch('client.create_request', array('client' => $this, 'request' => $request)); |
431
|
|
|
|
432
|
|
|
return $request; |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
/** |
436
|
|
|
* Initializes SSL settings |
437
|
|
|
*/ |
438
|
|
|
protected function initSsl() |
439
|
|
|
{ |
440
|
|
|
$authority = $this->config[self::SSL_CERT_AUTHORITY]; |
441
|
|
|
|
442
|
|
|
if ($authority === 'system') { |
443
|
|
|
return; |
444
|
|
|
} |
445
|
|
|
|
446
|
|
|
if ($authority === null) { |
447
|
|
|
$authority = true; |
448
|
|
|
} |
449
|
|
|
|
450
|
|
|
if ($authority === true && substr(__FILE__, 0, 7) == 'phar://') { |
451
|
|
|
$authority = self::extractPharCacert(__DIR__ . '/Resources/cacert.pem'); |
452
|
|
|
} |
453
|
|
|
|
454
|
|
|
$this->setSslVerification($authority); |
455
|
|
|
} |
456
|
|
|
|
457
|
|
|
/** |
458
|
|
|
* @deprecated |
459
|
|
|
*/ |
460
|
|
|
public function getDefaultHeaders() |
461
|
|
|
{ |
462
|
|
|
Version::warn(__METHOD__ . ' is deprecated. Use the request.options array to retrieve default request options'); |
463
|
|
|
return $this->defaultHeaders; |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
/** |
467
|
|
|
* @deprecated |
468
|
|
|
*/ |
469
|
|
View Code Duplication |
public function setDefaultHeaders($headers) |
|
|
|
|
470
|
|
|
{ |
471
|
|
|
Version::warn(__METHOD__ . ' is deprecated. Use the request.options array to specify default request options'); |
472
|
|
|
if ($headers instanceof Collection) { |
473
|
|
|
$this->defaultHeaders = $headers; |
474
|
|
|
} elseif (is_array($headers)) { |
475
|
|
|
$this->defaultHeaders = new Collection($headers); |
476
|
|
|
} else { |
477
|
|
|
throw new InvalidArgumentException('Headers must be an array or Collection'); |
478
|
|
|
} |
479
|
|
|
|
480
|
|
|
return $this; |
481
|
|
|
} |
482
|
|
|
|
483
|
|
|
/** |
484
|
|
|
* @deprecated |
485
|
|
|
*/ |
486
|
|
|
public function preparePharCacert($md5Check = true) |
|
|
|
|
487
|
|
|
{ |
488
|
|
|
return sys_get_temp_dir() . '/guzzle-cacert.pem'; |
489
|
|
|
} |
490
|
|
|
|
491
|
|
|
/** |
492
|
|
|
* Copies the phar cacert from a phar into the temp directory. |
493
|
|
|
* |
494
|
|
|
* @param string $pharCacertPath Path to the phar cacert. For example: |
495
|
|
|
* 'phar://aws.phar/Guzzle/Http/Resources/cacert.pem' |
496
|
|
|
* |
497
|
|
|
* @return string Returns the path to the extracted cacert file. |
498
|
|
|
* @throws \RuntimeException Throws if the phar cacert cannot be found or |
499
|
|
|
* the file cannot be copied to the temp dir. |
500
|
|
|
*/ |
501
|
|
|
public static function extractPharCacert($pharCacertPath) |
502
|
|
|
{ |
503
|
|
|
// Copy the cacert.pem file from the phar if it is not in the temp |
504
|
|
|
// folder. |
505
|
|
|
$certFile = sys_get_temp_dir() . '/guzzle-cacert.pem'; |
506
|
|
|
|
507
|
|
|
if (!file_exists($pharCacertPath)) { |
508
|
|
|
throw new \RuntimeException("Could not find $pharCacertPath"); |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
if (!file_exists($certFile) || |
512
|
|
|
filesize($certFile) != filesize($pharCacertPath) |
513
|
|
|
) { |
514
|
|
|
if (!copy($pharCacertPath, $certFile)) { |
515
|
|
|
throw new \RuntimeException( |
516
|
|
|
"Could not copy {$pharCacertPath} to {$certFile}: " |
517
|
|
|
. var_export(error_get_last(), true) |
518
|
|
|
); |
519
|
|
|
} |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
return $certFile; |
523
|
|
|
} |
524
|
|
|
} |
525
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.