Browse code

added appinfo/info.xml appinfo/signature.json CHANGELOG.txt lib/AppInfo/Application.php css/style.css providers/Plivo

DoubleBastionAdmin authored on 05/11/2025 13:35:09
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,483 @@
1
+<?php
2
+
3
+namespace GuzzleHttp;
4
+
5
+use GuzzleHttp\Cookie\CookieJar;
6
+use GuzzleHttp\Exception\GuzzleException;
7
+use GuzzleHttp\Exception\InvalidArgumentException;
8
+use GuzzleHttp\Promise as P;
9
+use GuzzleHttp\Promise\PromiseInterface;
10
+use Psr\Http\Message\RequestInterface;
11
+use Psr\Http\Message\ResponseInterface;
12
+use Psr\Http\Message\UriInterface;
13
+
14
+/**
15
+ * @final
16
+ */
17
+class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
18
+{
19
+    use ClientTrait;
20
+
21
+    /**
22
+     * @var array Default request options
23
+     */
24
+    private $config;
25
+
26
+    /**
27
+     * Clients accept an array of constructor parameters.
28
+     *
29
+     * Here's an example of creating a client using a base_uri and an array of
30
+     * default request options to apply to each request:
31
+     *
32
+     *     $client = new Client([
33
+     *         'base_uri'        => 'http://www.foo.com/1.0/',
34
+     *         'timeout'         => 0,
35
+     *         'allow_redirects' => false,
36
+     *         'proxy'           => '192.168.16.1:10'
37
+     *     ]);
38
+     *
39
+     * Client configuration settings include the following options:
40
+     *
41
+     * - handler: (callable) Function that transfers HTTP requests over the
42
+     *   wire. The function is called with a Psr7\Http\Message\RequestInterface
43
+     *   and array of transfer options, and must return a
44
+     *   GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
45
+     *   Psr7\Http\Message\ResponseInterface on success.
46
+     *   If no handler is provided, a default handler will be created
47
+     *   that enables all of the request options below by attaching all of the
48
+     *   default middleware to the handler.
49
+     * - base_uri: (string|UriInterface) Base URI of the client that is merged
50
+     *   into relative URIs. Can be a string or instance of UriInterface.
51
+     * - **: any request option
52
+     *
53
+     * @param array $config Client configuration settings.
54
+     *
55
+     * @see RequestOptions for a list of available request options.
56
+     */
57
+    public function __construct(array $config = [])
58
+    {
59
+        if (!isset($config['handler'])) {
60
+            $config['handler'] = HandlerStack::create();
61
+        } elseif (!\is_callable($config['handler'])) {
62
+            throw new InvalidArgumentException('handler must be a callable');
63
+        }
64
+
65
+        // Convert the base_uri to a UriInterface
66
+        if (isset($config['base_uri'])) {
67
+            $config['base_uri'] = Psr7\Utils::uriFor($config['base_uri']);
68
+        }
69
+
70
+        $this->configureDefaults($config);
71
+    }
72
+
73
+    /**
74
+     * @param string $method
75
+     * @param array  $args
76
+     *
77
+     * @return PromiseInterface|ResponseInterface
78
+     *
79
+     * @deprecated Client::__call will be removed in guzzlehttp/guzzle:8.0.
80
+     */
81
+    public function __call($method, $args)
82
+    {
83
+        if (\count($args) < 1) {
84
+            throw new InvalidArgumentException('Magic request methods require a URI and optional options array');
85
+        }
86
+
87
+        $uri = $args[0];
88
+        $opts = $args[1] ?? [];
89
+
90
+        return \substr($method, -5) === 'Async'
91
+            ? $this->requestAsync(\substr($method, 0, -5), $uri, $opts)
92
+            : $this->request($method, $uri, $opts);
93
+    }
94
+
95
+    /**
96
+     * Asynchronously send an HTTP request.
97
+     *
98
+     * @param array $options Request options to apply to the given
99
+     *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
100
+     */
101
+    public function sendAsync(RequestInterface $request, array $options = []): PromiseInterface
102
+    {
103
+        // Merge the base URI into the request URI if needed.
104
+        $options = $this->prepareDefaults($options);
105
+
106
+        return $this->transfer(
107
+            $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')),
108
+            $options
109
+        );
110
+    }
111
+
112
+    /**
113
+     * Send an HTTP request.
114
+     *
115
+     * @param array $options Request options to apply to the given
116
+     *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
117
+     *
118
+     * @throws GuzzleException
119
+     */
120
+    public function send(RequestInterface $request, array $options = []): ResponseInterface
121
+    {
122
+        $options[RequestOptions::SYNCHRONOUS] = true;
123
+
124
+        return $this->sendAsync($request, $options)->wait();
125
+    }
126
+
127
+    /**
128
+     * The HttpClient PSR (PSR-18) specify this method.
129
+     *
130
+     * {@inheritDoc}
131
+     */
132
+    public function sendRequest(RequestInterface $request): ResponseInterface
133
+    {
134
+        $options[RequestOptions::SYNCHRONOUS] = true;
135
+        $options[RequestOptions::ALLOW_REDIRECTS] = false;
136
+        $options[RequestOptions::HTTP_ERRORS] = false;
137
+
138
+        return $this->sendAsync($request, $options)->wait();
139
+    }
140
+
141
+    /**
142
+     * Create and send an asynchronous HTTP request.
143
+     *
144
+     * Use an absolute path to override the base path of the client, or a
145
+     * relative path to append to the base path of the client. The URL can
146
+     * contain the query string as well. Use an array to provide a URL
147
+     * template and additional variables to use in the URL template expansion.
148
+     *
149
+     * @param string              $method  HTTP method
150
+     * @param string|UriInterface $uri     URI object or string.
151
+     * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
152
+     */
153
+    public function requestAsync(string $method, $uri = '', array $options = []): PromiseInterface
154
+    {
155
+        $options = $this->prepareDefaults($options);
156
+        // Remove request modifying parameter because it can be done up-front.
157
+        $headers = $options['headers'] ?? [];
158
+        $body = $options['body'] ?? null;
159
+        $version = $options['version'] ?? '1.1';
160
+        // Merge the URI into the base URI.
161
+        $uri = $this->buildUri(Psr7\Utils::uriFor($uri), $options);
162
+        if (\is_array($body)) {
163
+            throw $this->invalidBody();
164
+        }
165
+        $request = new Psr7\Request($method, $uri, $headers, $body, $version);
166
+        // Remove the option so that they are not doubly-applied.
167
+        unset($options['headers'], $options['body'], $options['version']);
168
+
169
+        return $this->transfer($request, $options);
170
+    }
171
+
172
+    /**
173
+     * Create and send an HTTP request.
174
+     *
175
+     * Use an absolute path to override the base path of the client, or a
176
+     * relative path to append to the base path of the client. The URL can
177
+     * contain the query string as well.
178
+     *
179
+     * @param string              $method  HTTP method.
180
+     * @param string|UriInterface $uri     URI object or string.
181
+     * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
182
+     *
183
+     * @throws GuzzleException
184
+     */
185
+    public function request(string $method, $uri = '', array $options = []): ResponseInterface
186
+    {
187
+        $options[RequestOptions::SYNCHRONOUS] = true;
188
+
189
+        return $this->requestAsync($method, $uri, $options)->wait();
190
+    }
191
+
192
+    /**
193
+     * Get a client configuration option.
194
+     *
195
+     * These options include default request options of the client, a "handler"
196
+     * (if utilized by the concrete client), and a "base_uri" if utilized by
197
+     * the concrete client.
198
+     *
199
+     * @param string|null $option The config option to retrieve.
200
+     *
201
+     * @return mixed
202
+     *
203
+     * @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0.
204
+     */
205
+    public function getConfig(?string $option = null)
206
+    {
207
+        return $option === null
208
+            ? $this->config
209
+            : ($this->config[$option] ?? null);
210
+    }
211
+
212
+    private function buildUri(UriInterface $uri, array $config): UriInterface
213
+    {
214
+        if (isset($config['base_uri'])) {
215
+            $uri = Psr7\UriResolver::resolve(Psr7\Utils::uriFor($config['base_uri']), $uri);
216
+        }
217
+
218
+        if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
219
+            $idnOptions = ($config['idn_conversion'] === true) ? \IDNA_DEFAULT : $config['idn_conversion'];
220
+            $uri = Utils::idnUriConvert($uri, $idnOptions);
221
+        }
222
+
223
+        return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
224
+    }
225
+
226
+    /**
227
+     * Configures the default options for a client.
228
+     */
229
+    private function configureDefaults(array $config): void
230
+    {
231
+        $defaults = [
232
+            'allow_redirects' => RedirectMiddleware::$defaultSettings,
233
+            'http_errors' => true,
234
+            'decode_content' => true,
235
+            'verify' => true,
236
+            'cookies' => false,
237
+            'idn_conversion' => false,
238
+        ];
239
+
240
+        // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
241
+
242
+        // We can only trust the HTTP_PROXY environment variable in a CLI
243
+        // process due to the fact that PHP has no reliable mechanism to
244
+        // get environment variables that start with "HTTP_".
245
+        if (\PHP_SAPI === 'cli' && ($proxy = Utils::getenv('HTTP_PROXY'))) {
246
+            $defaults['proxy']['http'] = $proxy;
247
+        }
248
+
249
+        if ($proxy = Utils::getenv('HTTPS_PROXY')) {
250
+            $defaults['proxy']['https'] = $proxy;
251
+        }
252
+
253
+        if ($noProxy = Utils::getenv('NO_PROXY')) {
254
+            $cleanedNoProxy = \str_replace(' ', '', $noProxy);
255
+            $defaults['proxy']['no'] = \explode(',', $cleanedNoProxy);
256
+        }
257
+
258
+        $this->config = $config + $defaults;
259
+
260
+        if (!empty($config['cookies']) && $config['cookies'] === true) {
261
+            $this->config['cookies'] = new CookieJar();
262
+        }
263
+
264
+        // Add the default user-agent header.
265
+        if (!isset($this->config['headers'])) {
266
+            $this->config['headers'] = ['User-Agent' => Utils::defaultUserAgent()];
267
+        } else {
268
+            // Add the User-Agent header if one was not already set.
269
+            foreach (\array_keys($this->config['headers']) as $name) {
270
+                if (\strtolower($name) === 'user-agent') {
271
+                    return;
272
+                }
273
+            }
274
+            $this->config['headers']['User-Agent'] = Utils::defaultUserAgent();
275
+        }
276
+    }
277
+
278
+    /**
279
+     * Merges default options into the array.
280
+     *
281
+     * @param array $options Options to modify by reference
282
+     */
283
+    private function prepareDefaults(array $options): array
284
+    {
285
+        $defaults = $this->config;
286
+
287
+        if (!empty($defaults['headers'])) {
288
+            // Default headers are only added if they are not present.
289
+            $defaults['_conditional'] = $defaults['headers'];
290
+            unset($defaults['headers']);
291
+        }
292
+
293
+        // Special handling for headers is required as they are added as
294
+        // conditional headers and as headers passed to a request ctor.
295
+        if (\array_key_exists('headers', $options)) {
296
+            // Allows default headers to be unset.
297
+            if ($options['headers'] === null) {
298
+                $defaults['_conditional'] = [];
299
+                unset($options['headers']);
300
+            } elseif (!\is_array($options['headers'])) {
301
+                throw new InvalidArgumentException('headers must be an array');
302
+            }
303
+        }
304
+
305
+        // Shallow merge defaults underneath options.
306
+        $result = $options + $defaults;
307
+
308
+        // Remove null values.
309
+        foreach ($result as $k => $v) {
310
+            if ($v === null) {
311
+                unset($result[$k]);
312
+            }
313
+        }
314
+
315
+        return $result;
316
+    }
317
+
318
+    /**
319
+     * Transfers the given request and applies request options.
320
+     *
321
+     * The URI of the request is not modified and the request options are used
322
+     * as-is without merging in default options.
323
+     *
324
+     * @param array $options See \GuzzleHttp\RequestOptions.
325
+     */
326
+    private function transfer(RequestInterface $request, array $options): PromiseInterface
327
+    {
328
+        $request = $this->applyOptions($request, $options);
329
+        /** @var HandlerStack $handler */
330
+        $handler = $options['handler'];
331
+
332
+        try {
333
+            return P\Create::promiseFor($handler($request, $options));
334
+        } catch (\Exception $e) {
335
+            return P\Create::rejectionFor($e);
336
+        }
337
+    }
338
+
339
+    /**
340
+     * Applies the array of request options to a request.
341
+     */
342
+    private function applyOptions(RequestInterface $request, array &$options): RequestInterface
343
+    {
344
+        $modify = [
345
+            'set_headers' => [],
346
+        ];
347
+
348
+        if (isset($options['headers'])) {
349
+            if (array_keys($options['headers']) === range(0, count($options['headers']) - 1)) {
350
+                throw new InvalidArgumentException('The headers array must have header name as keys.');
351
+            }
352
+            $modify['set_headers'] = $options['headers'];
353
+            unset($options['headers']);
354
+        }
355
+
356
+        if (isset($options['form_params'])) {
357
+            if (isset($options['multipart'])) {
358
+                throw new InvalidArgumentException('You cannot use '
359
+                    .'form_params and multipart at the same time. Use the '
360
+                    .'form_params option if you want to send application/'
361
+                    .'x-www-form-urlencoded requests, and the multipart '
362
+                    .'option to send multipart/form-data requests.');
363
+            }
364
+            $options['body'] = \http_build_query($options['form_params'], '', '&');
365
+            unset($options['form_params']);
366
+            // Ensure that we don't have the header in different case and set the new value.
367
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
368
+            $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
369
+        }
370
+
371
+        if (isset($options['multipart'])) {
372
+            $options['body'] = new Psr7\MultipartStream($options['multipart']);
373
+            unset($options['multipart']);
374
+        }
375
+
376
+        if (isset($options['json'])) {
377
+            $options['body'] = Utils::jsonEncode($options['json']);
378
+            unset($options['json']);
379
+            // Ensure that we don't have the header in different case and set the new value.
380
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
381
+            $options['_conditional']['Content-Type'] = 'application/json';
382
+        }
383
+
384
+        if (!empty($options['decode_content'])
385
+            && $options['decode_content'] !== true
386
+        ) {
387
+            // Ensure that we don't have the header in different case and set the new value.
388
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Accept-Encoding'], $options['_conditional']);
389
+            $modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
390
+        }
391
+
392
+        if (isset($options['body'])) {
393
+            if (\is_array($options['body'])) {
394
+                throw $this->invalidBody();
395
+            }
396
+            $modify['body'] = Psr7\Utils::streamFor($options['body']);
397
+            unset($options['body']);
398
+        }
399
+
400
+        if (!empty($options['auth']) && \is_array($options['auth'])) {
401
+            $value = $options['auth'];
402
+            $type = isset($value[2]) ? \strtolower($value[2]) : 'basic';
403
+            switch ($type) {
404
+                case 'basic':
405
+                    // Ensure that we don't have the header in different case and set the new value.
406
+                    $modify['set_headers'] = Psr7\Utils::caselessRemove(['Authorization'], $modify['set_headers']);
407
+                    $modify['set_headers']['Authorization'] = 'Basic '
408
+                        .\base64_encode("$value[0]:$value[1]");
409
+                    break;
410
+                case 'digest':
411
+                    // @todo: Do not rely on curl
412
+                    $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_DIGEST;
413
+                    $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]";
414
+                    break;
415
+                case 'ntlm':
416
+                    $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_NTLM;
417
+                    $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]";
418
+                    break;
419
+            }
420
+        }
421
+
422
+        if (isset($options['query'])) {
423
+            $value = $options['query'];
424
+            if (\is_array($value)) {
425
+                $value = \http_build_query($value, '', '&', \PHP_QUERY_RFC3986);
426
+            }
427
+            if (!\is_string($value)) {
428
+                throw new InvalidArgumentException('query must be a string or array');
429
+            }
430
+            $modify['query'] = $value;
431
+            unset($options['query']);
432
+        }
433
+
434
+        // Ensure that sink is not an invalid value.
435
+        if (isset($options['sink'])) {
436
+            // TODO: Add more sink validation?
437
+            if (\is_bool($options['sink'])) {
438
+                throw new InvalidArgumentException('sink must not be a boolean');
439
+            }
440
+        }
441
+
442
+        if (isset($options['version'])) {
443
+            $modify['version'] = $options['version'];
444
+        }
445
+
446
+        $request = Psr7\Utils::modifyRequest($request, $modify);
447
+        if ($request->getBody() instanceof Psr7\MultipartStream) {
448
+            // Use a multipart/form-data POST if a Content-Type is not set.
449
+            // Ensure that we don't have the header in different case and set the new value.
450
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
451
+            $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
452
+                .$request->getBody()->getBoundary();
453
+        }
454
+
455
+        // Merge in conditional headers if they are not present.
456
+        if (isset($options['_conditional'])) {
457
+            // Build up the changes so it's in a single clone of the message.
458
+            $modify = [];
459
+            foreach ($options['_conditional'] as $k => $v) {
460
+                if (!$request->hasHeader($k)) {
461
+                    $modify['set_headers'][$k] = $v;
462
+                }
463
+            }
464
+            $request = Psr7\Utils::modifyRequest($request, $modify);
465
+            // Don't pass this internal value along to middleware/handlers.
466
+            unset($options['_conditional']);
467
+        }
468
+
469
+        return $request;
470
+    }
471
+
472
+    /**
473
+     * Return an InvalidArgumentException with pre-set message.
474
+     */
475
+    private function invalidBody(): InvalidArgumentException
476
+    {
477
+        return new InvalidArgumentException('Passing in the "body" request '
478
+            .'option as an array to send a request is not supported. '
479
+            .'Please use the "form_params" request option to send a '
480
+            .'application/x-www-form-urlencoded request, or the "multipart" '
481
+            .'request option to send a multipart/form-data request.');
482
+    }
483
+}
Browse code

removed appinfo/info.xml appinfo/signature.json CHANGELOG.txt lib/AppInfo/Application.php css/style.css providers/Plivo

DoubleBastionAdmin authored on 05/11/2025 13:12:22
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,474 +0,0 @@
1
-<?php
2
-
3
-namespace GuzzleHttp;
4
-
5
-use GuzzleHttp\Cookie\CookieJar;
6
-use GuzzleHttp\Exception\GuzzleException;
7
-use GuzzleHttp\Exception\InvalidArgumentException;
8
-use GuzzleHttp\Promise as P;
9
-use GuzzleHttp\Promise\PromiseInterface;
10
-use Psr\Http\Message\RequestInterface;
11
-use Psr\Http\Message\ResponseInterface;
12
-use Psr\Http\Message\UriInterface;
13
-
14
-/**
15
- * @final
16
- */
17
-class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
18
-{
19
-    use ClientTrait;
20
-
21
-    /**
22
-     * @var array Default request options
23
-     */
24
-    private $config;
25
-
26
-    /**
27
-     * Clients accept an array of constructor parameters.
28
-     *
29
-     * Here's an example of creating a client using a base_uri and an array of
30
-     * default request options to apply to each request:
31
-     *
32
-     *     $client = new Client([
33
-     *         'base_uri'        => 'http://www.foo.com/1.0/',
34
-     *         'timeout'         => 0,
35
-     *         'allow_redirects' => false,
36
-     *         'proxy'           => '192.168.16.1:10'
37
-     *     ]);
38
-     *
39
-     * Client configuration settings include the following options:
40
-     *
41
-     * - handler: (callable) Function that transfers HTTP requests over the
42
-     *   wire. The function is called with a Psr7\Http\Message\RequestInterface
43
-     *   and array of transfer options, and must return a
44
-     *   GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
45
-     *   Psr7\Http\Message\ResponseInterface on success.
46
-     *   If no handler is provided, a default handler will be created
47
-     *   that enables all of the request options below by attaching all of the
48
-     *   default middleware to the handler.
49
-     * - base_uri: (string|UriInterface) Base URI of the client that is merged
50
-     *   into relative URIs. Can be a string or instance of UriInterface.
51
-     * - **: any request option
52
-     *
53
-     * @param array $config Client configuration settings.
54
-     *
55
-     * @see \GuzzleHttp\RequestOptions for a list of available request options.
56
-     */
57
-    public function __construct(array $config = [])
58
-    {
59
-        if (!isset($config['handler'])) {
60
-            $config['handler'] = HandlerStack::create();
61
-        } elseif (!\is_callable($config['handler'])) {
62
-            throw new InvalidArgumentException('handler must be a callable');
63
-        }
64
-
65
-        // Convert the base_uri to a UriInterface
66
-        if (isset($config['base_uri'])) {
67
-            $config['base_uri'] = Psr7\Utils::uriFor($config['base_uri']);
68
-        }
69
-
70
-        $this->configureDefaults($config);
71
-    }
72
-
73
-    /**
74
-     * @param string $method
75
-     * @param array  $args
76
-     *
77
-     * @return PromiseInterface|ResponseInterface
78
-     *
79
-     * @deprecated Client::__call will be removed in guzzlehttp/guzzle:8.0.
80
-     */
81
-    public function __call($method, $args)
82
-    {
83
-        if (\count($args) < 1) {
84
-            throw new InvalidArgumentException('Magic request methods require a URI and optional options array');
85
-        }
86
-
87
-        $uri = $args[0];
88
-        $opts = $args[1] ?? [];
89
-
90
-        return \substr($method, -5) === 'Async'
91
-            ? $this->requestAsync(\substr($method, 0, -5), $uri, $opts)
92
-            : $this->request($method, $uri, $opts);
93
-    }
94
-
95
-    /**
96
-     * Asynchronously send an HTTP request.
97
-     *
98
-     * @param array $options Request options to apply to the given
99
-     *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
100
-     */
101
-    public function sendAsync(RequestInterface $request, array $options = []): PromiseInterface
102
-    {
103
-        // Merge the base URI into the request URI if needed.
104
-        $options = $this->prepareDefaults($options);
105
-
106
-        return $this->transfer(
107
-            $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')),
108
-            $options
109
-        );
110
-    }
111
-
112
-    /**
113
-     * Send an HTTP request.
114
-     *
115
-     * @param array $options Request options to apply to the given
116
-     *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
117
-     *
118
-     * @throws GuzzleException
119
-     */
120
-    public function send(RequestInterface $request, array $options = []): ResponseInterface
121
-    {
122
-        $options[RequestOptions::SYNCHRONOUS] = true;
123
-        return $this->sendAsync($request, $options)->wait();
124
-    }
125
-
126
-    /**
127
-     * The HttpClient PSR (PSR-18) specify this method.
128
-     *
129
-     * @inheritDoc
130
-     */
131
-    public function sendRequest(RequestInterface $request): ResponseInterface
132
-    {
133
-        $options[RequestOptions::SYNCHRONOUS] = true;
134
-        $options[RequestOptions::ALLOW_REDIRECTS] = false;
135
-        $options[RequestOptions::HTTP_ERRORS] = false;
136
-
137
-        return $this->sendAsync($request, $options)->wait();
138
-    }
139
-
140
-    /**
141
-     * Create and send an asynchronous HTTP request.
142
-     *
143
-     * Use an absolute path to override the base path of the client, or a
144
-     * relative path to append to the base path of the client. The URL can
145
-     * contain the query string as well. Use an array to provide a URL
146
-     * template and additional variables to use in the URL template expansion.
147
-     *
148
-     * @param string              $method  HTTP method
149
-     * @param string|UriInterface $uri     URI object or string.
150
-     * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
151
-     */
152
-    public function requestAsync(string $method, $uri = '', array $options = []): PromiseInterface
153
-    {
154
-        $options = $this->prepareDefaults($options);
155
-        // Remove request modifying parameter because it can be done up-front.
156
-        $headers = $options['headers'] ?? [];
157
-        $body = $options['body'] ?? null;
158
-        $version = $options['version'] ?? '1.1';
159
-        // Merge the URI into the base URI.
160
-        $uri = $this->buildUri(Psr7\Utils::uriFor($uri), $options);
161
-        if (\is_array($body)) {
162
-            throw $this->invalidBody();
163
-        }
164
-        $request = new Psr7\Request($method, $uri, $headers, $body, $version);
165
-        // Remove the option so that they are not doubly-applied.
166
-        unset($options['headers'], $options['body'], $options['version']);
167
-
168
-        return $this->transfer($request, $options);
169
-    }
170
-
171
-    /**
172
-     * Create and send an HTTP request.
173
-     *
174
-     * Use an absolute path to override the base path of the client, or a
175
-     * relative path to append to the base path of the client. The URL can
176
-     * contain the query string as well.
177
-     *
178
-     * @param string              $method  HTTP method.
179
-     * @param string|UriInterface $uri     URI object or string.
180
-     * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
181
-     *
182
-     * @throws GuzzleException
183
-     */
184
-    public function request(string $method, $uri = '', array $options = []): ResponseInterface
185
-    {
186
-        $options[RequestOptions::SYNCHRONOUS] = true;
187
-        return $this->requestAsync($method, $uri, $options)->wait();
188
-    }
189
-
190
-    /**
191
-     * Get a client configuration option.
192
-     *
193
-     * These options include default request options of the client, a "handler"
194
-     * (if utilized by the concrete client), and a "base_uri" if utilized by
195
-     * the concrete client.
196
-     *
197
-     * @param string|null $option The config option to retrieve.
198
-     *
199
-     * @return mixed
200
-     *
201
-     * @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0.
202
-     */
203
-    public function getConfig(?string $option = null)
204
-    {
205
-        return $option === null
206
-            ? $this->config
207
-            : (isset($this->config[$option]) ? $this->config[$option] : null);
208
-    }
209
-
210
-    private function buildUri(UriInterface $uri, array $config): UriInterface
211
-    {
212
-        if (isset($config['base_uri'])) {
213
-            $uri = Psr7\UriResolver::resolve(Psr7\Utils::uriFor($config['base_uri']), $uri);
214
-        }
215
-
216
-        if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
217
-            $idnOptions = ($config['idn_conversion'] === true) ? \IDNA_DEFAULT : $config['idn_conversion'];
218
-            $uri = Utils::idnUriConvert($uri, $idnOptions);
219
-        }
220
-
221
-        return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
222
-    }
223
-
224
-    /**
225
-     * Configures the default options for a client.
226
-     */
227
-    private function configureDefaults(array $config): void
228
-    {
229
-        $defaults = [
230
-            'allow_redirects' => RedirectMiddleware::$defaultSettings,
231
-            'http_errors'     => true,
232
-            'decode_content'  => true,
233
-            'verify'          => true,
234
-            'cookies'         => false,
235
-            'idn_conversion'  => false,
236
-        ];
237
-
238
-        // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
239
-
240
-        // We can only trust the HTTP_PROXY environment variable in a CLI
241
-        // process due to the fact that PHP has no reliable mechanism to
242
-        // get environment variables that start with "HTTP_".
243
-        if (\PHP_SAPI === 'cli' && ($proxy = Utils::getenv('HTTP_PROXY'))) {
244
-            $defaults['proxy']['http'] = $proxy;
245
-        }
246
-
247
-        if ($proxy = Utils::getenv('HTTPS_PROXY')) {
248
-            $defaults['proxy']['https'] = $proxy;
249
-        }
250
-
251
-        if ($noProxy = Utils::getenv('NO_PROXY')) {
252
-            $cleanedNoProxy = \str_replace(' ', '', $noProxy);
253
-            $defaults['proxy']['no'] = \explode(',', $cleanedNoProxy);
254
-        }
255
-
256
-        $this->config = $config + $defaults;
257
-
258
-        if (!empty($config['cookies']) && $config['cookies'] === true) {
259
-            $this->config['cookies'] = new CookieJar();
260
-        }
261
-
262
-        // Add the default user-agent header.
263
-        if (!isset($this->config['headers'])) {
264
-            $this->config['headers'] = ['User-Agent' => Utils::defaultUserAgent()];
265
-        } else {
266
-            // Add the User-Agent header if one was not already set.
267
-            foreach (\array_keys($this->config['headers']) as $name) {
268
-                if (\strtolower($name) === 'user-agent') {
269
-                    return;
270
-                }
271
-            }
272
-            $this->config['headers']['User-Agent'] = Utils::defaultUserAgent();
273
-        }
274
-    }
275
-
276
-    /**
277
-     * Merges default options into the array.
278
-     *
279
-     * @param array $options Options to modify by reference
280
-     */
281
-    private function prepareDefaults(array $options): array
282
-    {
283
-        $defaults = $this->config;
284
-
285
-        if (!empty($defaults['headers'])) {
286
-            // Default headers are only added if they are not present.
287
-            $defaults['_conditional'] = $defaults['headers'];
288
-            unset($defaults['headers']);
289
-        }
290
-
291
-        // Special handling for headers is required as they are added as
292
-        // conditional headers and as headers passed to a request ctor.
293
-        if (\array_key_exists('headers', $options)) {
294
-            // Allows default headers to be unset.
295
-            if ($options['headers'] === null) {
296
-                $defaults['_conditional'] = [];
297
-                unset($options['headers']);
298
-            } elseif (!\is_array($options['headers'])) {
299
-                throw new InvalidArgumentException('headers must be an array');
300
-            }
301
-        }
302
-
303
-        // Shallow merge defaults underneath options.
304
-        $result = $options + $defaults;
305
-
306
-        // Remove null values.
307
-        foreach ($result as $k => $v) {
308
-            if ($v === null) {
309
-                unset($result[$k]);
310
-            }
311
-        }
312
-
313
-        return $result;
314
-    }
315
-
316
-    /**
317
-     * Transfers the given request and applies request options.
318
-     *
319
-     * The URI of the request is not modified and the request options are used
320
-     * as-is without merging in default options.
321
-     *
322
-     * @param array $options See \GuzzleHttp\RequestOptions.
323
-     */
324
-    private function transfer(RequestInterface $request, array $options): PromiseInterface
325
-    {
326
-        $request = $this->applyOptions($request, $options);
327
-        /** @var HandlerStack $handler */
328
-        $handler = $options['handler'];
329
-
330
-        try {
331
-            return P\Create::promiseFor($handler($request, $options));
332
-        } catch (\Exception $e) {
333
-            return P\Create::rejectionFor($e);
334
-        }
335
-    }
336
-
337
-    /**
338
-     * Applies the array of request options to a request.
339
-     */
340
-    private function applyOptions(RequestInterface $request, array &$options): RequestInterface
341
-    {
342
-        $modify = [
343
-            'set_headers' => [],
344
-        ];
345
-
346
-        if (isset($options['headers'])) {
347
-            $modify['set_headers'] = $options['headers'];
348
-            unset($options['headers']);
349
-        }
350
-
351
-        if (isset($options['form_params'])) {
352
-            if (isset($options['multipart'])) {
353
-                throw new InvalidArgumentException('You cannot use '
354
-                    . 'form_params and multipart at the same time. Use the '
355
-                    . 'form_params option if you want to send application/'
356
-                    . 'x-www-form-urlencoded requests, and the multipart '
357
-                    . 'option to send multipart/form-data requests.');
358
-            }
359
-            $options['body'] = \http_build_query($options['form_params'], '', '&');
360
-            unset($options['form_params']);
361
-            // Ensure that we don't have the header in different case and set the new value.
362
-            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
363
-            $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
364
-        }
365
-
366
-        if (isset($options['multipart'])) {
367
-            $options['body'] = new Psr7\MultipartStream($options['multipart']);
368
-            unset($options['multipart']);
369
-        }
370
-
371
-        if (isset($options['json'])) {
372
-            $options['body'] = Utils::jsonEncode($options['json']);
373
-            unset($options['json']);
374
-            // Ensure that we don't have the header in different case and set the new value.
375
-            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
376
-            $options['_conditional']['Content-Type'] = 'application/json';
377
-        }
378
-
379
-        if (!empty($options['decode_content'])
380
-            && $options['decode_content'] !== true
381
-        ) {
382
-            // Ensure that we don't have the header in different case and set the new value.
383
-            $options['_conditional'] = Psr7\Utils::caselessRemove(['Accept-Encoding'], $options['_conditional']);
384
-            $modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
385
-        }
386
-
387
-        if (isset($options['body'])) {
388
-            if (\is_array($options['body'])) {
389
-                throw $this->invalidBody();
390
-            }
391
-            $modify['body'] = Psr7\Utils::streamFor($options['body']);
392
-            unset($options['body']);
393
-        }
394
-
395
-        if (!empty($options['auth']) && \is_array($options['auth'])) {
396
-            $value = $options['auth'];
397
-            $type = isset($value[2]) ? \strtolower($value[2]) : 'basic';
398
-            switch ($type) {
399
-                case 'basic':
400
-                    // Ensure that we don't have the header in different case and set the new value.
401
-                    $modify['set_headers'] = Psr7\Utils::caselessRemove(['Authorization'], $modify['set_headers']);
402
-                    $modify['set_headers']['Authorization'] = 'Basic '
403
-                        . \base64_encode("$value[0]:$value[1]");
404
-                    break;
405
-                case 'digest':
406
-                    // @todo: Do not rely on curl
407
-                    $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_DIGEST;
408
-                    $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]";
409
-                    break;
410
-                case 'ntlm':
411
-                    $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_NTLM;
412
-                    $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]";
413
-                    break;
414
-            }
415
-        }
416
-
417
-        if (isset($options['query'])) {
418
-            $value = $options['query'];
419
-            if (\is_array($value)) {
420
-                $value = \http_build_query($value, '', '&', \PHP_QUERY_RFC3986);
421
-            }
422
-            if (!\is_string($value)) {
423
-                throw new InvalidArgumentException('query must be a string or array');
424
-            }
425
-            $modify['query'] = $value;
426
-            unset($options['query']);
427
-        }
428
-
429
-        // Ensure that sink is not an invalid value.
430
-        if (isset($options['sink'])) {
431
-            // TODO: Add more sink validation?
432
-            if (\is_bool($options['sink'])) {
433
-                throw new InvalidArgumentException('sink must not be a boolean');
434
-            }
435
-        }
436
-
437
-        $request = Psr7\Utils::modifyRequest($request, $modify);
438
-        if ($request->getBody() instanceof Psr7\MultipartStream) {
439
-            // Use a multipart/form-data POST if a Content-Type is not set.
440
-            // Ensure that we don't have the header in different case and set the new value.
441
-            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
442
-            $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
443
-                . $request->getBody()->getBoundary();
444
-        }
445
-
446
-        // Merge in conditional headers if they are not present.
447
-        if (isset($options['_conditional'])) {
448
-            // Build up the changes so it's in a single clone of the message.
449
-            $modify = [];
450
-            foreach ($options['_conditional'] as $k => $v) {
451
-                if (!$request->hasHeader($k)) {
452
-                    $modify['set_headers'][$k] = $v;
453
-                }
454
-            }
455
-            $request = Psr7\Utils::modifyRequest($request, $modify);
456
-            // Don't pass this internal value along to middleware/handlers.
457
-            unset($options['_conditional']);
458
-        }
459
-
460
-        return $request;
461
-    }
462
-
463
-    /**
464
-     * Return an InvalidArgumentException with pre-set message.
465
-     */
466
-    private function invalidBody(): InvalidArgumentException
467
-    {
468
-        return new InvalidArgumentException('Passing in the "body" request '
469
-            . 'option as an array to send a request is not supported. '
470
-            . 'Please use the "form_params" request option to send a '
471
-            . 'application/x-www-form-urlencoded request, or the "multipart" '
472
-            . 'request option to send a multipart/form-data request.');
473
-    }
474
-}
Browse code

Added README.md appinfo/info.xml appinfo/signature.json lib/Controller/AuthorApiController.php and the providers directory

DoubleBastionAdmin authored on 20/08/2022 16:33:00
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,474 @@
1
+<?php
2
+
3
+namespace GuzzleHttp;
4
+
5
+use GuzzleHttp\Cookie\CookieJar;
6
+use GuzzleHttp\Exception\GuzzleException;
7
+use GuzzleHttp\Exception\InvalidArgumentException;
8
+use GuzzleHttp\Promise as P;
9
+use GuzzleHttp\Promise\PromiseInterface;
10
+use Psr\Http\Message\RequestInterface;
11
+use Psr\Http\Message\ResponseInterface;
12
+use Psr\Http\Message\UriInterface;
13
+
14
+/**
15
+ * @final
16
+ */
17
+class Client implements ClientInterface, \Psr\Http\Client\ClientInterface
18
+{
19
+    use ClientTrait;
20
+
21
+    /**
22
+     * @var array Default request options
23
+     */
24
+    private $config;
25
+
26
+    /**
27
+     * Clients accept an array of constructor parameters.
28
+     *
29
+     * Here's an example of creating a client using a base_uri and an array of
30
+     * default request options to apply to each request:
31
+     *
32
+     *     $client = new Client([
33
+     *         'base_uri'        => 'http://www.foo.com/1.0/',
34
+     *         'timeout'         => 0,
35
+     *         'allow_redirects' => false,
36
+     *         'proxy'           => '192.168.16.1:10'
37
+     *     ]);
38
+     *
39
+     * Client configuration settings include the following options:
40
+     *
41
+     * - handler: (callable) Function that transfers HTTP requests over the
42
+     *   wire. The function is called with a Psr7\Http\Message\RequestInterface
43
+     *   and array of transfer options, and must return a
44
+     *   GuzzleHttp\Promise\PromiseInterface that is fulfilled with a
45
+     *   Psr7\Http\Message\ResponseInterface on success.
46
+     *   If no handler is provided, a default handler will be created
47
+     *   that enables all of the request options below by attaching all of the
48
+     *   default middleware to the handler.
49
+     * - base_uri: (string|UriInterface) Base URI of the client that is merged
50
+     *   into relative URIs. Can be a string or instance of UriInterface.
51
+     * - **: any request option
52
+     *
53
+     * @param array $config Client configuration settings.
54
+     *
55
+     * @see \GuzzleHttp\RequestOptions for a list of available request options.
56
+     */
57
+    public function __construct(array $config = [])
58
+    {
59
+        if (!isset($config['handler'])) {
60
+            $config['handler'] = HandlerStack::create();
61
+        } elseif (!\is_callable($config['handler'])) {
62
+            throw new InvalidArgumentException('handler must be a callable');
63
+        }
64
+
65
+        // Convert the base_uri to a UriInterface
66
+        if (isset($config['base_uri'])) {
67
+            $config['base_uri'] = Psr7\Utils::uriFor($config['base_uri']);
68
+        }
69
+
70
+        $this->configureDefaults($config);
71
+    }
72
+
73
+    /**
74
+     * @param string $method
75
+     * @param array  $args
76
+     *
77
+     * @return PromiseInterface|ResponseInterface
78
+     *
79
+     * @deprecated Client::__call will be removed in guzzlehttp/guzzle:8.0.
80
+     */
81
+    public function __call($method, $args)
82
+    {
83
+        if (\count($args) < 1) {
84
+            throw new InvalidArgumentException('Magic request methods require a URI and optional options array');
85
+        }
86
+
87
+        $uri = $args[0];
88
+        $opts = $args[1] ?? [];
89
+
90
+        return \substr($method, -5) === 'Async'
91
+            ? $this->requestAsync(\substr($method, 0, -5), $uri, $opts)
92
+            : $this->request($method, $uri, $opts);
93
+    }
94
+
95
+    /**
96
+     * Asynchronously send an HTTP request.
97
+     *
98
+     * @param array $options Request options to apply to the given
99
+     *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
100
+     */
101
+    public function sendAsync(RequestInterface $request, array $options = []): PromiseInterface
102
+    {
103
+        // Merge the base URI into the request URI if needed.
104
+        $options = $this->prepareDefaults($options);
105
+
106
+        return $this->transfer(
107
+            $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')),
108
+            $options
109
+        );
110
+    }
111
+
112
+    /**
113
+     * Send an HTTP request.
114
+     *
115
+     * @param array $options Request options to apply to the given
116
+     *                       request and to the transfer. See \GuzzleHttp\RequestOptions.
117
+     *
118
+     * @throws GuzzleException
119
+     */
120
+    public function send(RequestInterface $request, array $options = []): ResponseInterface
121
+    {
122
+        $options[RequestOptions::SYNCHRONOUS] = true;
123
+        return $this->sendAsync($request, $options)->wait();
124
+    }
125
+
126
+    /**
127
+     * The HttpClient PSR (PSR-18) specify this method.
128
+     *
129
+     * @inheritDoc
130
+     */
131
+    public function sendRequest(RequestInterface $request): ResponseInterface
132
+    {
133
+        $options[RequestOptions::SYNCHRONOUS] = true;
134
+        $options[RequestOptions::ALLOW_REDIRECTS] = false;
135
+        $options[RequestOptions::HTTP_ERRORS] = false;
136
+
137
+        return $this->sendAsync($request, $options)->wait();
138
+    }
139
+
140
+    /**
141
+     * Create and send an asynchronous HTTP request.
142
+     *
143
+     * Use an absolute path to override the base path of the client, or a
144
+     * relative path to append to the base path of the client. The URL can
145
+     * contain the query string as well. Use an array to provide a URL
146
+     * template and additional variables to use in the URL template expansion.
147
+     *
148
+     * @param string              $method  HTTP method
149
+     * @param string|UriInterface $uri     URI object or string.
150
+     * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
151
+     */
152
+    public function requestAsync(string $method, $uri = '', array $options = []): PromiseInterface
153
+    {
154
+        $options = $this->prepareDefaults($options);
155
+        // Remove request modifying parameter because it can be done up-front.
156
+        $headers = $options['headers'] ?? [];
157
+        $body = $options['body'] ?? null;
158
+        $version = $options['version'] ?? '1.1';
159
+        // Merge the URI into the base URI.
160
+        $uri = $this->buildUri(Psr7\Utils::uriFor($uri), $options);
161
+        if (\is_array($body)) {
162
+            throw $this->invalidBody();
163
+        }
164
+        $request = new Psr7\Request($method, $uri, $headers, $body, $version);
165
+        // Remove the option so that they are not doubly-applied.
166
+        unset($options['headers'], $options['body'], $options['version']);
167
+
168
+        return $this->transfer($request, $options);
169
+    }
170
+
171
+    /**
172
+     * Create and send an HTTP request.
173
+     *
174
+     * Use an absolute path to override the base path of the client, or a
175
+     * relative path to append to the base path of the client. The URL can
176
+     * contain the query string as well.
177
+     *
178
+     * @param string              $method  HTTP method.
179
+     * @param string|UriInterface $uri     URI object or string.
180
+     * @param array               $options Request options to apply. See \GuzzleHttp\RequestOptions.
181
+     *
182
+     * @throws GuzzleException
183
+     */
184
+    public function request(string $method, $uri = '', array $options = []): ResponseInterface
185
+    {
186
+        $options[RequestOptions::SYNCHRONOUS] = true;
187
+        return $this->requestAsync($method, $uri, $options)->wait();
188
+    }
189
+
190
+    /**
191
+     * Get a client configuration option.
192
+     *
193
+     * These options include default request options of the client, a "handler"
194
+     * (if utilized by the concrete client), and a "base_uri" if utilized by
195
+     * the concrete client.
196
+     *
197
+     * @param string|null $option The config option to retrieve.
198
+     *
199
+     * @return mixed
200
+     *
201
+     * @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0.
202
+     */
203
+    public function getConfig(?string $option = null)
204
+    {
205
+        return $option === null
206
+            ? $this->config
207
+            : (isset($this->config[$option]) ? $this->config[$option] : null);
208
+    }
209
+
210
+    private function buildUri(UriInterface $uri, array $config): UriInterface
211
+    {
212
+        if (isset($config['base_uri'])) {
213
+            $uri = Psr7\UriResolver::resolve(Psr7\Utils::uriFor($config['base_uri']), $uri);
214
+        }
215
+
216
+        if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) {
217
+            $idnOptions = ($config['idn_conversion'] === true) ? \IDNA_DEFAULT : $config['idn_conversion'];
218
+            $uri = Utils::idnUriConvert($uri, $idnOptions);
219
+        }
220
+
221
+        return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri;
222
+    }
223
+
224
+    /**
225
+     * Configures the default options for a client.
226
+     */
227
+    private function configureDefaults(array $config): void
228
+    {
229
+        $defaults = [
230
+            'allow_redirects' => RedirectMiddleware::$defaultSettings,
231
+            'http_errors'     => true,
232
+            'decode_content'  => true,
233
+            'verify'          => true,
234
+            'cookies'         => false,
235
+            'idn_conversion'  => false,
236
+        ];
237
+
238
+        // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set.
239
+
240
+        // We can only trust the HTTP_PROXY environment variable in a CLI
241
+        // process due to the fact that PHP has no reliable mechanism to
242
+        // get environment variables that start with "HTTP_".
243
+        if (\PHP_SAPI === 'cli' && ($proxy = Utils::getenv('HTTP_PROXY'))) {
244
+            $defaults['proxy']['http'] = $proxy;
245
+        }
246
+
247
+        if ($proxy = Utils::getenv('HTTPS_PROXY')) {
248
+            $defaults['proxy']['https'] = $proxy;
249
+        }
250
+
251
+        if ($noProxy = Utils::getenv('NO_PROXY')) {
252
+            $cleanedNoProxy = \str_replace(' ', '', $noProxy);
253
+            $defaults['proxy']['no'] = \explode(',', $cleanedNoProxy);
254
+        }
255
+
256
+        $this->config = $config + $defaults;
257
+
258
+        if (!empty($config['cookies']) && $config['cookies'] === true) {
259
+            $this->config['cookies'] = new CookieJar();
260
+        }
261
+
262
+        // Add the default user-agent header.
263
+        if (!isset($this->config['headers'])) {
264
+            $this->config['headers'] = ['User-Agent' => Utils::defaultUserAgent()];
265
+        } else {
266
+            // Add the User-Agent header if one was not already set.
267
+            foreach (\array_keys($this->config['headers']) as $name) {
268
+                if (\strtolower($name) === 'user-agent') {
269
+                    return;
270
+                }
271
+            }
272
+            $this->config['headers']['User-Agent'] = Utils::defaultUserAgent();
273
+        }
274
+    }
275
+
276
+    /**
277
+     * Merges default options into the array.
278
+     *
279
+     * @param array $options Options to modify by reference
280
+     */
281
+    private function prepareDefaults(array $options): array
282
+    {
283
+        $defaults = $this->config;
284
+
285
+        if (!empty($defaults['headers'])) {
286
+            // Default headers are only added if they are not present.
287
+            $defaults['_conditional'] = $defaults['headers'];
288
+            unset($defaults['headers']);
289
+        }
290
+
291
+        // Special handling for headers is required as they are added as
292
+        // conditional headers and as headers passed to a request ctor.
293
+        if (\array_key_exists('headers', $options)) {
294
+            // Allows default headers to be unset.
295
+            if ($options['headers'] === null) {
296
+                $defaults['_conditional'] = [];
297
+                unset($options['headers']);
298
+            } elseif (!\is_array($options['headers'])) {
299
+                throw new InvalidArgumentException('headers must be an array');
300
+            }
301
+        }
302
+
303
+        // Shallow merge defaults underneath options.
304
+        $result = $options + $defaults;
305
+
306
+        // Remove null values.
307
+        foreach ($result as $k => $v) {
308
+            if ($v === null) {
309
+                unset($result[$k]);
310
+            }
311
+        }
312
+
313
+        return $result;
314
+    }
315
+
316
+    /**
317
+     * Transfers the given request and applies request options.
318
+     *
319
+     * The URI of the request is not modified and the request options are used
320
+     * as-is without merging in default options.
321
+     *
322
+     * @param array $options See \GuzzleHttp\RequestOptions.
323
+     */
324
+    private function transfer(RequestInterface $request, array $options): PromiseInterface
325
+    {
326
+        $request = $this->applyOptions($request, $options);
327
+        /** @var HandlerStack $handler */
328
+        $handler = $options['handler'];
329
+
330
+        try {
331
+            return P\Create::promiseFor($handler($request, $options));
332
+        } catch (\Exception $e) {
333
+            return P\Create::rejectionFor($e);
334
+        }
335
+    }
336
+
337
+    /**
338
+     * Applies the array of request options to a request.
339
+     */
340
+    private function applyOptions(RequestInterface $request, array &$options): RequestInterface
341
+    {
342
+        $modify = [
343
+            'set_headers' => [],
344
+        ];
345
+
346
+        if (isset($options['headers'])) {
347
+            $modify['set_headers'] = $options['headers'];
348
+            unset($options['headers']);
349
+        }
350
+
351
+        if (isset($options['form_params'])) {
352
+            if (isset($options['multipart'])) {
353
+                throw new InvalidArgumentException('You cannot use '
354
+                    . 'form_params and multipart at the same time. Use the '
355
+                    . 'form_params option if you want to send application/'
356
+                    . 'x-www-form-urlencoded requests, and the multipart '
357
+                    . 'option to send multipart/form-data requests.');
358
+            }
359
+            $options['body'] = \http_build_query($options['form_params'], '', '&');
360
+            unset($options['form_params']);
361
+            // Ensure that we don't have the header in different case and set the new value.
362
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
363
+            $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded';
364
+        }
365
+
366
+        if (isset($options['multipart'])) {
367
+            $options['body'] = new Psr7\MultipartStream($options['multipart']);
368
+            unset($options['multipart']);
369
+        }
370
+
371
+        if (isset($options['json'])) {
372
+            $options['body'] = Utils::jsonEncode($options['json']);
373
+            unset($options['json']);
374
+            // Ensure that we don't have the header in different case and set the new value.
375
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
376
+            $options['_conditional']['Content-Type'] = 'application/json';
377
+        }
378
+
379
+        if (!empty($options['decode_content'])
380
+            && $options['decode_content'] !== true
381
+        ) {
382
+            // Ensure that we don't have the header in different case and set the new value.
383
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Accept-Encoding'], $options['_conditional']);
384
+            $modify['set_headers']['Accept-Encoding'] = $options['decode_content'];
385
+        }
386
+
387
+        if (isset($options['body'])) {
388
+            if (\is_array($options['body'])) {
389
+                throw $this->invalidBody();
390
+            }
391
+            $modify['body'] = Psr7\Utils::streamFor($options['body']);
392
+            unset($options['body']);
393
+        }
394
+
395
+        if (!empty($options['auth']) && \is_array($options['auth'])) {
396
+            $value = $options['auth'];
397
+            $type = isset($value[2]) ? \strtolower($value[2]) : 'basic';
398
+            switch ($type) {
399
+                case 'basic':
400
+                    // Ensure that we don't have the header in different case and set the new value.
401
+                    $modify['set_headers'] = Psr7\Utils::caselessRemove(['Authorization'], $modify['set_headers']);
402
+                    $modify['set_headers']['Authorization'] = 'Basic '
403
+                        . \base64_encode("$value[0]:$value[1]");
404
+                    break;
405
+                case 'digest':
406
+                    // @todo: Do not rely on curl
407
+                    $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_DIGEST;
408
+                    $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]";
409
+                    break;
410
+                case 'ntlm':
411
+                    $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_NTLM;
412
+                    $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]";
413
+                    break;
414
+            }
415
+        }
416
+
417
+        if (isset($options['query'])) {
418
+            $value = $options['query'];
419
+            if (\is_array($value)) {
420
+                $value = \http_build_query($value, '', '&', \PHP_QUERY_RFC3986);
421
+            }
422
+            if (!\is_string($value)) {
423
+                throw new InvalidArgumentException('query must be a string or array');
424
+            }
425
+            $modify['query'] = $value;
426
+            unset($options['query']);
427
+        }
428
+
429
+        // Ensure that sink is not an invalid value.
430
+        if (isset($options['sink'])) {
431
+            // TODO: Add more sink validation?
432
+            if (\is_bool($options['sink'])) {
433
+                throw new InvalidArgumentException('sink must not be a boolean');
434
+            }
435
+        }
436
+
437
+        $request = Psr7\Utils::modifyRequest($request, $modify);
438
+        if ($request->getBody() instanceof Psr7\MultipartStream) {
439
+            // Use a multipart/form-data POST if a Content-Type is not set.
440
+            // Ensure that we don't have the header in different case and set the new value.
441
+            $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']);
442
+            $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary='
443
+                . $request->getBody()->getBoundary();
444
+        }
445
+
446
+        // Merge in conditional headers if they are not present.
447
+        if (isset($options['_conditional'])) {
448
+            // Build up the changes so it's in a single clone of the message.
449
+            $modify = [];
450
+            foreach ($options['_conditional'] as $k => $v) {
451
+                if (!$request->hasHeader($k)) {
452
+                    $modify['set_headers'][$k] = $v;
453
+                }
454
+            }
455
+            $request = Psr7\Utils::modifyRequest($request, $modify);
456
+            // Don't pass this internal value along to middleware/handlers.
457
+            unset($options['_conditional']);
458
+        }
459
+
460
+        return $request;
461
+    }
462
+
463
+    /**
464
+     * Return an InvalidArgumentException with pre-set message.
465
+     */
466
+    private function invalidBody(): InvalidArgumentException
467
+    {
468
+        return new InvalidArgumentException('Passing in the "body" request '
469
+            . 'option as an array to send a request is not supported. '
470
+            . 'Please use the "form_params" request option to send a '
471
+            . 'application/x-www-form-urlencoded request, or the "multipart" '
472
+            . 'request option to send a multipart/form-data request.');
473
+    }
474
+}