1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Akamai {OPEN} EdgeGrid Auth Client |
4
|
|
|
* |
5
|
|
|
* @author Davey Shafik <[email protected]> |
6
|
|
|
* @copyright Copyright 2016 Akamai Technologies, Inc. All rights reserved. |
7
|
|
|
* @license Apache 2.0 |
8
|
|
|
* @link https://github.com/akamai-open/AkamaiOPEN-edgegrid-php-client |
9
|
|
|
* @link https://developer.akamai.com |
10
|
|
|
* @link https://developer.akamai.com/introduction/Client_Auth.html |
11
|
|
|
*/ |
12
|
|
|
namespace Akamai\Open\EdgeGrid; |
13
|
|
|
|
14
|
|
|
use Akamai\Open\EdgeGrid\Handler\Authentication as AuthenticationHandler; |
15
|
|
|
use Akamai\Open\EdgeGrid\Handler\Debug as DebugHandler; |
16
|
|
|
use Akamai\Open\EdgeGrid\Handler\Verbose as VerboseHandler; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Akamai {OPEN} EdgeGrid Client for PHP |
20
|
|
|
* |
21
|
|
|
* Akamai\Open\EdgeGrid\Client wraps GuzzleHttp\Client |
22
|
|
|
* providing request authentication/signing for Akamai |
23
|
|
|
* {OPEN} APIs. |
24
|
|
|
* |
25
|
|
|
* This client works _identically_ to GuzzleHttp\Client |
26
|
|
|
* |
27
|
|
|
* However, if you try to call an Akamai {OPEN} API you *must* |
28
|
|
|
* first call {@see Akamai\Open\EdgeGrid\Client->setAuth()}. |
29
|
|
|
* |
30
|
|
|
* @package Akamai\Open\EdgeGrid\Client |
31
|
|
|
*/ |
32
|
|
|
class Client extends \GuzzleHttp\Client implements \Psr\Log\LoggerAwareInterface |
33
|
|
|
{ |
34
|
|
|
const VERSION = '0.6.3'; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* @const int Default Timeout in seconds |
38
|
|
|
*/ |
39
|
|
|
const DEFAULT_REQUEST_TIMEOUT = 300; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var bool|array|resource Whether verbose mode is enabled |
43
|
|
|
* |
44
|
|
|
* - true - Use STDERR |
45
|
|
|
* - array - output/error streams (different) |
46
|
|
|
* - resource - output/error stream (same) |
47
|
|
|
*/ |
48
|
|
|
protected static $staticVerbose = false; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @var bool|resource Whether debug mode is enabled |
52
|
|
|
*/ |
53
|
|
|
protected static $staticDebug = false; |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* @var \Akamai\Open\EdgeGrid\Authentication |
57
|
|
|
*/ |
58
|
|
|
protected $authentication; |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* @var \Akamai\Open\EdgeGrid\Handler\Verbose |
62
|
|
|
*/ |
63
|
|
|
protected $verboseHandler; |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* @var \Akamai\Open\EdgeGrid\Handler\Debug |
67
|
|
|
*/ |
68
|
|
|
protected $debugHandler; |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* @var bool|array|resource Whether verbose mode is enabled |
72
|
|
|
* |
73
|
|
|
* - true - Use STDOUT |
74
|
|
|
* - array - output/error streams (different) |
75
|
|
|
* - resource - output/error stream (same) |
76
|
|
|
*/ |
77
|
|
|
protected $verbose = false; |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* @var bool|resource Whether debugging is enabled |
81
|
|
|
*/ |
82
|
|
|
protected $debug = false; |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* @var bool Whether to override the static verbose setting |
86
|
|
|
*/ |
87
|
|
|
protected $verboseOverride = false; |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @var bool Whether to override the static debug setting |
91
|
|
|
*/ |
92
|
|
|
protected $debugOverride = false; |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @var \Closure Logging Handler |
96
|
|
|
*/ |
97
|
|
|
protected $logger; |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* \GuzzleHttp\Client-compatible constructor |
101
|
|
|
* |
102
|
|
|
* @param array $config Config options array |
103
|
|
|
* @param Authentication|null $authentication |
104
|
|
|
*/ |
105
|
131 |
|
public function __construct( |
106
|
|
|
$config = [], |
107
|
|
|
Authentication $authentication = null |
108
|
|
|
) { |
109
|
131 |
|
$config = $this->setAuthenticationHandler($config, $authentication); |
110
|
131 |
|
$config = $this->setBasicOptions($config); |
111
|
131 |
|
$config['headers']['User-Agent'] = 'Akamai-Open-Edgegrid-PHP/' . |
112
|
131 |
|
self::VERSION . ' ' . \GuzzleHttp\default_user_agent(); |
113
|
|
|
|
114
|
131 |
|
parent::__construct($config); |
115
|
131 |
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* Make an Asynchronous request |
119
|
|
|
* |
120
|
|
|
* @param string $method |
121
|
|
|
* @param string $uri |
122
|
|
|
* @param array $options |
123
|
|
|
* @return \GuzzleHttp\Promise\PromiseInterface |
124
|
|
|
* @throws \GuzzleHttp\Exception\GuzzleException |
125
|
|
|
*/ |
126
|
77 |
|
public function requestAsync($method, $uri = null, array $options = []) |
127
|
|
|
{ |
128
|
77 |
|
$options = $this->setRequestOptions($options); |
129
|
|
|
|
130
|
77 |
|
$query = parse_url($uri, PHP_URL_QUERY); |
131
|
77 |
|
if (!empty($query)) { |
132
|
1 |
|
$uri = substr($uri, 0, (strlen($query)+1) * -1); |
133
|
1 |
|
parse_str($query, $options['query']); |
134
|
1 |
|
} |
135
|
|
|
|
136
|
77 |
|
return parent::requestAsync($method, $uri, $options); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Send an Asynchronous HTTP request |
141
|
|
|
* |
142
|
|
|
* @param \Psr\Http\Message\RequestInterface $request The HTTP request |
143
|
|
|
* @param array $options Request options |
144
|
|
|
* |
145
|
|
|
* @return \GuzzleHttp\Promise\PromiseInterface |
146
|
|
|
*/ |
147
|
28 |
|
public function sendAsync(\Psr\Http\Message\RequestInterface $request, array $options = []) |
148
|
|
|
{ |
149
|
28 |
|
$options = $this->setRequestOptions($options); |
150
|
|
|
|
151
|
28 |
|
return parent::sendAsync($request, $options); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Set Akamai {OPEN} Authentication Credentials |
156
|
|
|
* |
157
|
|
|
* @param string $client_token |
158
|
|
|
* @param string $client_secret |
159
|
|
|
* @param string $access_token |
160
|
|
|
* @return $this |
161
|
|
|
*/ |
162
|
60 |
|
public function setAuth($client_token, $client_secret, $access_token) |
163
|
|
|
{ |
164
|
60 |
|
$this->authentication->setAuth($client_token, $client_secret, $access_token); |
165
|
|
|
|
166
|
60 |
|
return $this; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* Specify the headers to include when signing the request |
171
|
|
|
* |
172
|
|
|
* This is specified by the API, currently no APIs use this |
173
|
|
|
* feature. |
174
|
|
|
* |
175
|
|
|
* @param array $headers |
176
|
|
|
* @return $this |
177
|
|
|
*/ |
178
|
42 |
|
public function setHeadersToSign(array $headers) |
179
|
|
|
{ |
180
|
42 |
|
$this->authentication->setHeadersToSign($headers); |
181
|
|
|
|
182
|
42 |
|
return $this; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* Set the max body size |
187
|
|
|
* |
188
|
|
|
* @param int $max_body_size |
189
|
|
|
* @return $this |
190
|
|
|
*/ |
191
|
42 |
|
public function setMaxBodySize($max_body_size) |
192
|
|
|
{ |
193
|
42 |
|
$this->authentication->setMaxBodySize($max_body_size); |
194
|
|
|
|
195
|
42 |
|
return $this; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* Set Request Host |
200
|
|
|
* |
201
|
|
|
* @param string $host |
202
|
|
|
* @return $this |
203
|
|
|
*/ |
204
|
2 |
|
public function setHost($host) |
205
|
|
|
{ |
206
|
2 |
|
if (substr($host, -1) === '/') { |
207
|
2 |
|
$host = substr($host, 0, -1); |
208
|
2 |
|
} |
209
|
|
|
|
210
|
2 |
|
$headers = $this->getConfig('headers'); |
211
|
2 |
|
$headers['Host'] = $host; |
212
|
2 |
|
$this->setConfigOption('headers', $headers); |
213
|
|
|
|
214
|
2 |
|
if (strpos('/', $host) === false) { |
215
|
2 |
|
$host = 'https://' . $host; |
216
|
2 |
|
} |
217
|
2 |
|
$this->setConfigOption('base_uri', $host); |
218
|
|
|
|
219
|
2 |
|
return $this; |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* Set the HTTP request timeout |
224
|
|
|
* |
225
|
|
|
* @param int $timeout_in_seconds |
226
|
|
|
* @return $this |
227
|
|
|
*/ |
228
|
2 |
|
public function setTimeout($timeout_in_seconds) |
229
|
|
|
{ |
230
|
2 |
|
$this->setConfigOption('timeout', $timeout_in_seconds); |
231
|
|
|
|
232
|
2 |
|
return $this; |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/** |
236
|
|
|
* Print formatted JSON responses to output |
237
|
|
|
* |
238
|
|
|
* @param bool|resource $enable |
239
|
|
|
* @return $this |
240
|
|
|
*/ |
241
|
4 |
|
public function setInstanceVerbose($enable) |
242
|
|
|
{ |
243
|
4 |
|
$this->verboseOverride = true; |
244
|
4 |
|
$this->verbose = $enable; |
245
|
4 |
|
return $this; |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* Print HTTP requests/responses to output |
250
|
|
|
* |
251
|
|
|
* @param bool|resource $enable |
252
|
|
|
* @return $this |
253
|
|
|
*/ |
254
|
10 |
|
public function setInstanceDebug($enable) |
255
|
|
|
{ |
256
|
10 |
|
$this->debugOverride = true; |
257
|
10 |
|
$this->debug = $enable; |
258
|
10 |
|
return $this; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* Set a PSR-3 compatible logger (or use monolog by default) |
263
|
|
|
* |
264
|
|
|
* @param \Psr\Log\LoggerInterface $logger |
265
|
|
|
* @param string $messageFormat Message format |
266
|
|
|
* @return $this |
267
|
|
|
*/ |
268
|
24 |
|
public function setLogger( |
269
|
|
|
\Psr\Log\LoggerInterface $logger = null, |
270
|
|
|
$messageFormat = \GuzzleHttp\MessageFormatter::CLF |
271
|
|
|
) { |
272
|
24 |
|
if ($logger === null) { |
273
|
2 |
|
$handler = new \Monolog\Handler\ErrorLogHandler(\Monolog\Handler\ErrorLogHandler::SAPI); |
274
|
2 |
|
$handler->setFormatter(new \Monolog\Formatter\LineFormatter('%message%')); |
275
|
2 |
|
$logger = new \Monolog\Logger('HTTP Log', [$handler]); |
276
|
2 |
|
} |
277
|
|
|
|
278
|
24 |
|
$formatter = new \GuzzleHttp\MessageFormatter($messageFormat); |
279
|
|
|
|
280
|
24 |
|
$handler = \GuzzleHttp\Middleware::log($logger, $formatter); |
281
|
24 |
|
$this->logger = $handler; |
282
|
|
|
|
283
|
24 |
|
$handlerStack = $this->getConfig('handler'); |
284
|
24 |
|
$this->setLogHandler($handlerStack, $handler); |
285
|
|
|
|
286
|
24 |
|
return $this; |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
/** |
290
|
|
|
* Add logger using a given filename/format |
291
|
|
|
* |
292
|
|
|
* @param string $filename |
293
|
|
|
* @param string $format |
294
|
|
|
* @return \Akamai\Open\EdgeGrid\Client|bool |
295
|
|
|
*/ |
296
|
4 |
|
public function setSimpleLog($filename, $format = '{code}') |
297
|
|
|
{ |
298
|
4 |
|
if ($this->logger && !($this->logger instanceof \Monolog\Logger)) { |
299
|
2 |
|
return false; |
300
|
|
|
} |
301
|
|
|
|
302
|
2 |
|
$handler = new \Monolog\Handler\StreamHandler($filename); |
303
|
2 |
|
$handler->setFormatter(new \Monolog\Formatter\LineFormatter('%message%')); |
304
|
2 |
|
$log = new \Monolog\Logger('HTTP Log', [$handler]); |
305
|
|
|
|
306
|
2 |
|
return $this->setLogger($log, $format); |
307
|
|
|
} |
308
|
|
|
|
309
|
10 |
View Code Duplication |
public static function createInstance($section = 'default', $path = null, array $config = []) |
|
|
|
|
310
|
|
|
{ |
311
|
10 |
|
$auth = \Akamai\Open\EdgeGrid\Authentication::createInstance($section, $path); |
312
|
|
|
|
313
|
2 |
|
if ($host = $auth->getHost()) { |
314
|
2 |
|
$config['base_uri'] = 'https://' .$host; |
315
|
2 |
|
} |
316
|
|
|
|
317
|
2 |
|
return new static($config, $auth); |
318
|
|
|
} |
319
|
|
|
|
320
|
12 |
View Code Duplication |
public static function createFromEnv($section = 'default', array $config = []) |
|
|
|
|
321
|
|
|
{ |
322
|
12 |
|
$auth = \Akamai\Open\EdgeGrid\Authentication::createFromEnv($section); |
323
|
|
|
|
324
|
8 |
|
if ($host = $auth->getHost()) { |
325
|
8 |
|
$config['base_uri'] = 'https://' . $host; |
326
|
8 |
|
} |
327
|
|
|
|
328
|
8 |
|
return new static($config, $auth); |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
/** |
332
|
|
|
* Factory method to create a client using credentials from `.edgerc` |
333
|
|
|
* |
334
|
|
|
* Automatically checks your HOME directory, and the current working |
335
|
|
|
* directory for credentials, if no path is supplied. |
336
|
|
|
* |
337
|
|
|
* @param string $section Credential section to use |
338
|
|
|
* @param string $path Path to .edgerc credentials file |
339
|
|
|
* @param array $config Options to pass to the constructor/guzzle |
340
|
|
|
* @return \Akamai\Open\EdgeGrid\Client |
341
|
|
|
*/ |
342
|
8 |
View Code Duplication |
public static function createFromEdgeRcFile($section = 'default', $path = null, array $config = []) |
|
|
|
|
343
|
|
|
{ |
344
|
8 |
|
$auth = \Akamai\Open\EdgeGrid\Authentication::createFromEdgeRcFile($section, $path); |
345
|
|
|
|
346
|
8 |
|
if ($host = $auth->getHost()) { |
347
|
8 |
|
$config['base_uri'] = 'https://' . $host; |
348
|
8 |
|
} |
349
|
|
|
|
350
|
8 |
|
return new static($config, $auth); |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
/** |
354
|
|
|
* Print HTTP requests/responses to STDOUT |
355
|
|
|
* |
356
|
|
|
* @param bool|resource $enable |
357
|
|
|
*/ |
358
|
161 |
|
public static function setDebug($enable) |
359
|
|
|
{ |
360
|
161 |
|
self::$staticDebug = $enable; |
361
|
161 |
|
} |
362
|
|
|
|
363
|
|
|
/** |
364
|
|
|
* Print formatted JSON responses to STDOUT |
365
|
|
|
* |
366
|
|
|
* @param bool|resource|array $enable |
367
|
|
|
*/ |
368
|
169 |
|
public static function setVerbose($enable) |
369
|
|
|
{ |
370
|
169 |
|
self::$staticVerbose = $enable; |
371
|
169 |
|
} |
372
|
|
|
|
373
|
|
|
/** |
374
|
|
|
* Handle debug option |
375
|
|
|
* |
376
|
|
|
* @param array $config |
377
|
|
|
* @return bool|resource |
378
|
|
|
*/ |
379
|
105 |
|
protected function getDebugOption(array $config) |
380
|
|
|
{ |
381
|
105 |
|
if (isset($config['debug'])) { |
382
|
2 |
|
return ($config['debug'] === true) ? fopen('php://stderr', 'ab') : $config['debug']; |
383
|
|
|
} |
384
|
|
|
|
385
|
103 |
|
if ($this->debugOverride && $this->debug) { |
386
|
5 |
|
return ($this->debug === true) ? fopen('php://stderr', 'ab') : $this->debug; |
387
|
98 |
|
} elseif (!$this->debugOverride && static::$staticDebug) { |
388
|
9 |
|
return (static::$staticDebug === true) ? fopen('php://stderr', 'ab') : static::$staticDebug; |
389
|
|
|
} |
390
|
|
|
|
391
|
89 |
|
return false; |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
/** |
395
|
|
|
* Debugging status for the current request |
396
|
|
|
* |
397
|
|
|
* @return bool|resource |
398
|
|
|
*/ |
399
|
105 |
|
protected function isDebug() |
400
|
|
|
{ |
401
|
105 |
|
if (($this->debugOverride && !$this->debug) || (!$this->debugOverride && !static::$staticDebug)) { |
402
|
91 |
|
return false; |
403
|
|
|
} |
404
|
|
|
|
405
|
16 |
|
if ($this->debugOverride && $this->debug) { |
406
|
7 |
|
return $this->debug; |
407
|
|
|
} |
408
|
|
|
|
409
|
11 |
|
return static::$staticDebug; |
410
|
|
|
} |
411
|
|
|
|
412
|
|
|
/** |
413
|
|
|
* Verbose status for the current request |
414
|
|
|
* |
415
|
|
|
* @return array|bool|resource |
416
|
|
|
*/ |
417
|
105 |
|
protected function isVerbose() |
418
|
|
|
{ |
419
|
105 |
|
if (($this->verboseOverride && !$this->verbose) || (!$this->verboseOverride && !static::$staticVerbose)) { |
420
|
91 |
|
return false; |
421
|
|
|
} |
422
|
|
|
|
423
|
14 |
|
if ($this->verboseOverride && $this->verbose) { |
424
|
2 |
|
return $this->verbose; |
425
|
|
|
} |
426
|
|
|
|
427
|
12 |
|
return static::$staticVerbose; |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
/** |
431
|
|
|
* Set the Authentication instance |
432
|
|
|
* |
433
|
|
|
* @param array $config |
434
|
|
|
* @param Authentication|null $authentication |
435
|
|
|
*/ |
436
|
131 |
|
protected function setAuthentication(array $config, Authentication $authentication = null) |
437
|
|
|
{ |
438
|
131 |
|
$this->authentication = $authentication; |
439
|
131 |
|
if ($authentication === null) { |
440
|
113 |
|
$this->authentication = new Authentication(); |
441
|
113 |
|
} |
442
|
|
|
|
443
|
131 |
|
if (isset($config['timestamp'])) { |
444
|
42 |
|
$this->authentication->setTimestamp($config['timestamp']); |
445
|
42 |
|
} |
446
|
|
|
|
447
|
131 |
|
if (isset($config['nonce'])) { |
448
|
42 |
|
$this->authentication->setNonce($config['nonce']); |
449
|
42 |
|
} |
450
|
131 |
|
} |
451
|
|
|
|
452
|
|
|
/** |
453
|
|
|
* Set the Authentication Handler |
454
|
|
|
* |
455
|
|
|
* @param array $config |
456
|
|
|
* @param Authentication|null $authentication |
457
|
|
|
* @return array |
458
|
|
|
*/ |
459
|
131 |
|
protected function setAuthenticationHandler(array $config, Authentication $authentication = null) |
460
|
|
|
{ |
461
|
131 |
|
$this->setAuthentication($config, $authentication); |
462
|
|
|
|
463
|
131 |
|
$authenticationHandler = new AuthenticationHandler(); |
464
|
131 |
|
$authenticationHandler->setSigner($this->authentication); |
465
|
131 |
|
if (!isset($config['handler'])) { |
466
|
29 |
|
$config['handler'] = \GuzzleHttp\HandlerStack::create(); |
467
|
29 |
|
} |
468
|
|
|
try { |
469
|
131 |
|
if (!($config['handler'] instanceof \GuzzleHttp\HandlerStack)) { |
470
|
|
|
$config['handler'] = \GuzzleHttp\HandlerStack::create($config['handler']); |
471
|
|
|
} |
472
|
131 |
|
$config['handler']->before('history', $authenticationHandler, 'authentication'); |
473
|
131 |
|
} catch (\InvalidArgumentException $e) { |
474
|
|
|
// history middleware not added yet |
475
|
29 |
|
$config['handler']->push($authenticationHandler, 'authentication'); |
476
|
|
|
} |
477
|
131 |
|
return $config; |
478
|
|
|
} |
479
|
|
|
|
480
|
|
|
/** |
481
|
|
|
* Set timeout and base_uri options |
482
|
|
|
* |
483
|
|
|
* @param array $config |
484
|
|
|
* @return mixed |
485
|
|
|
*/ |
486
|
131 |
|
protected function setBasicOptions(array $config) |
487
|
|
|
{ |
488
|
131 |
|
if (!isset($config['timeout'])) { |
489
|
129 |
|
$config['timeout'] = static::DEFAULT_REQUEST_TIMEOUT; |
490
|
129 |
|
} |
491
|
|
|
|
492
|
131 |
|
if (isset($config['base_uri']) && strpos($config['base_uri'], 'http') === false) { |
493
|
2 |
|
$config['base_uri'] = 'https://' . $config['base_uri']; |
494
|
2 |
|
return $config; |
495
|
|
|
} |
496
|
129 |
|
return $config; |
497
|
|
|
} |
498
|
|
|
|
499
|
|
|
/** |
500
|
|
|
* Set values on the private \GuzzleHttp\Client->config |
501
|
|
|
* |
502
|
|
|
* This is a terrible hack, and illustrates why making |
503
|
|
|
* anything private makes it difficult to extend, and impossible |
504
|
|
|
* when there is no setter. |
505
|
|
|
* |
506
|
|
|
* @param string $what Config option to set |
507
|
|
|
* @param mixed $value Value to set the option to |
508
|
|
|
* @return void |
509
|
|
|
*/ |
510
|
|
|
protected function setConfigOption($what, $value) |
511
|
|
|
{ |
512
|
4 |
|
$closure = function () use ($what, $value) { |
513
|
|
|
/* @var $this \GuzzleHttp\Client */ |
514
|
4 |
|
$this->config[$what] = $value; |
515
|
4 |
|
}; |
516
|
|
|
|
517
|
4 |
|
$closure = $closure->bindTo($this, \GuzzleHttp\Client::class); |
518
|
4 |
|
$closure(); |
519
|
4 |
|
} |
520
|
|
|
|
521
|
|
|
/** |
522
|
|
|
* Add the Debug handler to the HandlerStack |
523
|
|
|
* |
524
|
|
|
* @param array $options Guzzle Options |
525
|
|
|
* @param bool|resource|null $fp Stream to write to |
526
|
|
|
* @return array |
527
|
|
|
*/ |
528
|
16 |
|
protected function setDebugHandler($options, $fp = null) |
529
|
|
|
{ |
530
|
|
|
try { |
531
|
16 |
|
if (is_bool($fp)) { |
532
|
6 |
|
$fp = null; |
533
|
6 |
|
} |
534
|
|
|
|
535
|
16 |
|
$handler = $this->getConfig('handler'); |
536
|
|
|
// if we have a default handler, and we've already created a DebugHandler |
537
|
|
|
// we can bail out now (or we will add another one to the stack) |
538
|
16 |
|
if ($handler && $this->debugHandler) { |
539
|
1 |
|
return $options; |
540
|
|
|
} |
541
|
|
|
|
542
|
16 |
|
if (isset($options['handler'])) { |
543
|
|
|
$handler = $options['handler']; |
544
|
|
|
} |
545
|
|
|
|
546
|
16 |
|
if ($handler === null) { |
547
|
|
|
$handler = \GuzzleHttp\HandlerStack::create(); |
548
|
|
|
} |
549
|
|
|
|
550
|
16 |
|
if (!$this->debugHandler) { |
551
|
16 |
|
$this->debugHandler = new DebugHandler($fp); |
552
|
16 |
|
} |
553
|
|
|
|
554
|
16 |
|
$handler->after('allow_redirects', $this->debugHandler, 'debug'); |
555
|
16 |
|
} catch (\InvalidArgumentException $e) { |
556
|
|
|
$handler->push($this->debugHandler, 'debug'); |
|
|
|
|
557
|
|
|
} |
558
|
|
|
|
559
|
16 |
|
$options['handler'] = $handler; |
560
|
|
|
|
561
|
16 |
|
return $options; |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
/** |
565
|
|
|
* Add the Log handler to the HandlerStack |
566
|
|
|
* |
567
|
|
|
* @param \GuzzleHttp\HandlerStack $handlerStack |
568
|
|
|
* @param callable $logHandler |
569
|
|
|
* @return $this |
570
|
|
|
*/ |
571
|
24 |
|
protected function setLogHandler(\GuzzleHttp\HandlerStack $handlerStack, callable $logHandler) |
572
|
|
|
{ |
573
|
|
|
try { |
574
|
24 |
|
$handlerStack->after('history', $logHandler, 'logger'); |
575
|
24 |
|
} catch (\InvalidArgumentException $e) { |
576
|
|
|
try { |
577
|
6 |
|
$handlerStack->before('allow_redirects', $logHandler, 'logger'); |
578
|
6 |
|
} catch (\InvalidArgumentException $e) { |
579
|
|
|
$handlerStack->push($logHandler, 'logger'); |
580
|
|
|
} |
581
|
|
|
} |
582
|
|
|
|
583
|
24 |
|
return $this; |
584
|
|
|
} |
585
|
|
|
|
586
|
|
|
/** |
587
|
|
|
* Add the Verbose handler to the HandlerStack |
588
|
|
|
* |
589
|
|
|
* @param array $options Guzzle Options |
590
|
|
|
* @param bool|resource|array|null $fp Stream to write to |
591
|
|
|
* @return array |
592
|
|
|
*/ |
593
|
14 |
|
protected function setVerboseHandler($options, $fp = null) |
594
|
|
|
{ |
595
|
|
|
try { |
596
|
14 |
|
if (is_bool($fp) || $fp === null) { |
597
|
11 |
|
$fp = ['outputStream' => null, 'errorStream' => null]; |
598
|
14 |
|
} elseif (!is_array($fp)) { |
599
|
1 |
|
$fp = ['outputStream' => $fp, 'errorStream' => $fp]; |
600
|
1 |
|
} |
601
|
|
|
|
602
|
14 |
|
$handler = $this->getConfig('handler'); |
603
|
|
|
// if we have a default handler, and we've already created a VerboseHandler |
604
|
|
|
// we can bail out now (or we will add another one to the stack) |
605
|
14 |
|
if ($handler && $this->verboseHandler) { |
606
|
3 |
|
return $options; |
607
|
|
|
} |
608
|
|
|
|
609
|
14 |
|
if (isset($options['handler'])) { |
610
|
1 |
|
$handler = $options['handler']; |
611
|
1 |
|
} |
612
|
|
|
|
613
|
14 |
|
if ($handler === null) { |
614
|
|
|
$handler = \GuzzleHttp\HandlerStack::create(); |
615
|
|
|
} |
616
|
|
|
|
617
|
14 |
|
if (!$this->verboseHandler) { |
618
|
14 |
|
$this->verboseHandler = new VerboseHandler(array_shift($fp), array_shift($fp)); |
619
|
14 |
|
} |
620
|
|
|
|
621
|
14 |
|
$handler->after('allow_redirects', $this->verboseHandler, 'verbose'); |
622
|
14 |
|
} catch (\InvalidArgumentException $e) { |
623
|
|
|
$handler->push($this->verboseHandler, 'verbose'); |
|
|
|
|
624
|
|
|
} |
625
|
|
|
|
626
|
14 |
|
$options['handler'] = $handler; |
627
|
|
|
|
628
|
14 |
|
return $options; |
629
|
|
|
} |
630
|
|
|
|
631
|
|
|
/** |
632
|
|
|
* Set request specific options |
633
|
|
|
* |
634
|
|
|
* @param array $options |
635
|
|
|
* @return array |
636
|
|
|
*/ |
637
|
105 |
|
protected function setRequestOptions(array $options) |
638
|
|
|
{ |
639
|
105 |
|
if (isset($options['timestamp'])) { |
640
|
|
|
$this->authentication->setTimestamp($options['timestamp']); |
641
|
105 |
|
} elseif (!$this->getConfig('timestamp')) { |
642
|
63 |
|
$this->authentication->setTimestamp(); |
643
|
63 |
|
} |
644
|
|
|
|
645
|
105 |
|
if (isset($options['nonce'])) { |
646
|
|
|
$this->authentication->setNonce($options['nonce']); |
647
|
|
|
} |
648
|
|
|
|
649
|
105 |
|
if (isset($options['handler'])) { |
650
|
3 |
|
$options = $this->setAuthenticationHandler($options, $this->authentication); |
651
|
3 |
|
} |
652
|
|
|
|
653
|
105 |
|
if ($fp = $this->isVerbose()) { |
654
|
14 |
|
$options = $this->setVerboseHandler($options, $fp); |
655
|
14 |
|
} |
656
|
|
|
|
657
|
105 |
|
$options['debug'] = $this->getDebugOption($options); |
658
|
105 |
|
if ($fp = $this->isDebug()) { |
659
|
16 |
|
$options = $this->setDebugHandler($options, $fp); |
660
|
16 |
|
} |
661
|
|
|
|
662
|
105 |
|
if ($this->logger && isset($options['handler'])) { |
663
|
2 |
|
$this->setLogHandler($options['handler'], $this->logger); |
664
|
2 |
|
return $options; |
665
|
|
|
} |
666
|
|
|
|
667
|
103 |
|
return $options; |
668
|
|
|
} |
669
|
|
|
} |
670
|
|
|
|
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.