From 75160b12821f7f4299cce7f0b69c83c1502ae071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anton=20Luka=20=C5=A0ijanec?= Date: Mon, 27 May 2024 13:08:29 +0200 Subject: 2024-02-19 upstream --- vendor/guzzlehttp/guzzle/src/Client.php | 1002 ++++++++--------- vendor/guzzlehttp/guzzle/src/ClientInterface.php | 174 +-- vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php | 637 +++++------ .../guzzle/src/Cookie/CookieJarInterface.php | 168 +-- .../guzzlehttp/guzzle/src/Cookie/FileCookieJar.php | 182 +-- .../guzzle/src/Cookie/SessionCookieJar.php | 144 +-- vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php | 813 +++++++------- .../guzzle/src/Exception/BadResponseException.php | 54 +- .../guzzle/src/Exception/ClientException.php | 18 +- .../guzzle/src/Exception/ConnectException.php | 74 +- .../guzzle/src/Exception/GuzzleException.php | 46 +- .../guzzle/src/Exception/RequestException.php | 384 +++---- .../guzzle/src/Exception/SeekException.php | 54 +- .../guzzle/src/Exception/ServerException.php | 18 +- .../src/Exception/TooManyRedirectsException.php | 12 +- .../guzzle/src/Exception/TransferException.php | 12 +- .../guzzlehttp/guzzle/src/Handler/CurlFactory.php | 1170 ++++++++++---------- .../guzzle/src/Handler/CurlFactoryInterface.php | 54 +- .../guzzlehttp/guzzle/src/Handler/CurlHandler.php | 90 +- .../guzzle/src/Handler/CurlMultiHandler.php | 438 ++++---- .../guzzlehttp/guzzle/src/Handler/EasyHandle.php | 184 +-- .../guzzlehttp/guzzle/src/Handler/MockHandler.php | 390 +++---- vendor/guzzlehttp/guzzle/src/Handler/Proxy.php | 110 +- .../guzzle/src/Handler/StreamHandler.php | 1090 +++++++++--------- vendor/guzzlehttp/guzzle/src/HandlerStack.php | 554 ++++----- vendor/guzzlehttp/guzzle/src/MessageFormatter.php | 370 +++---- vendor/guzzlehttp/guzzle/src/Middleware.php | 508 ++++----- vendor/guzzlehttp/guzzle/src/Pool.php | 268 ++--- .../guzzle/src/PrepareBodyMiddleware.php | 222 ++-- .../guzzlehttp/guzzle/src/RedirectMiddleware.php | 519 ++++----- vendor/guzzlehttp/guzzle/src/RequestOptions.php | 526 ++++----- vendor/guzzlehttp/guzzle/src/RetryMiddleware.php | 256 ++--- vendor/guzzlehttp/guzzle/src/TransferStats.php | 252 ++--- vendor/guzzlehttp/guzzle/src/UriTemplate.php | 474 ++++---- vendor/guzzlehttp/guzzle/src/Utils.php | 184 +-- vendor/guzzlehttp/guzzle/src/functions.php | 668 +++++------ vendor/guzzlehttp/guzzle/src/functions_include.php | 12 +- 37 files changed, 6076 insertions(+), 6055 deletions(-) (limited to 'vendor/guzzlehttp/guzzle/src') diff --git a/vendor/guzzlehttp/guzzle/src/Client.php b/vendor/guzzlehttp/guzzle/src/Client.php index 315a022..e8a4c6a 100644 --- a/vendor/guzzlehttp/guzzle/src/Client.php +++ b/vendor/guzzlehttp/guzzle/src/Client.php @@ -1,501 +1,501 @@ - 'http://www.foo.com/1.0/', - * 'timeout' => 0, - * 'allow_redirects' => false, - * 'proxy' => '192.168.16.1:10' - * ]); - * - * Client configuration settings include the following options: - * - * - handler: (callable) Function that transfers HTTP requests over the - * wire. The function is called with a Psr7\Http\Message\RequestInterface - * and array of transfer options, and must return a - * GuzzleHttp\Promise\PromiseInterface that is fulfilled with a - * Psr7\Http\Message\ResponseInterface on success. - * If no handler is provided, a default handler will be created - * that enables all of the request options below by attaching all of the - * default middleware to the handler. - * - base_uri: (string|UriInterface) Base URI of the client that is merged - * into relative URIs. Can be a string or instance of UriInterface. - * - **: any request option - * - * @param array $config Client configuration settings. - * - * @see \GuzzleHttp\RequestOptions for a list of available request options. - */ - public function __construct(array $config = []) - { - if (!isset($config['handler'])) { - $config['handler'] = HandlerStack::create(); - } elseif (!is_callable($config['handler'])) { - throw new \InvalidArgumentException('handler must be a callable'); - } - - // Convert the base_uri to a UriInterface - if (isset($config['base_uri'])) { - $config['base_uri'] = Psr7\uri_for($config['base_uri']); - } - - $this->configureDefaults($config); - } - - /** - * @param string $method - * @param array $args - * - * @return Promise\PromiseInterface - */ - public function __call($method, $args) - { - if (count($args) < 1) { - throw new \InvalidArgumentException('Magic request methods require a URI and optional options array'); - } - - $uri = $args[0]; - $opts = isset($args[1]) ? $args[1] : []; - - return substr($method, -5) === 'Async' - ? $this->requestAsync(substr($method, 0, -5), $uri, $opts) - : $this->request($method, $uri, $opts); - } - - /** - * Asynchronously send an HTTP request. - * - * @param array $options Request options to apply to the given - * request and to the transfer. See \GuzzleHttp\RequestOptions. - * - * @return Promise\PromiseInterface - */ - public function sendAsync(RequestInterface $request, array $options = []) - { - // Merge the base URI into the request URI if needed. - $options = $this->prepareDefaults($options); - - return $this->transfer( - $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')), - $options - ); - } - - /** - * Send an HTTP request. - * - * @param array $options Request options to apply to the given - * request and to the transfer. See \GuzzleHttp\RequestOptions. - * - * @return ResponseInterface - * @throws GuzzleException - */ - public function send(RequestInterface $request, array $options = []) - { - $options[RequestOptions::SYNCHRONOUS] = true; - return $this->sendAsync($request, $options)->wait(); - } - - /** - * Create and send an asynchronous HTTP request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. Use an array to provide a URL - * template and additional variables to use in the URL template expansion. - * - * @param string $method HTTP method - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. - * - * @return Promise\PromiseInterface - */ - public function requestAsync($method, $uri = '', array $options = []) - { - $options = $this->prepareDefaults($options); - // Remove request modifying parameter because it can be done up-front. - $headers = isset($options['headers']) ? $options['headers'] : []; - $body = isset($options['body']) ? $options['body'] : null; - $version = isset($options['version']) ? $options['version'] : '1.1'; - // Merge the URI into the base URI. - $uri = $this->buildUri($uri, $options); - if (is_array($body)) { - $this->invalidBody(); - } - $request = new Psr7\Request($method, $uri, $headers, $body, $version); - // Remove the option so that they are not doubly-applied. - unset($options['headers'], $options['body'], $options['version']); - - return $this->transfer($request, $options); - } - - /** - * Create and send an HTTP request. - * - * Use an absolute path to override the base path of the client, or a - * relative path to append to the base path of the client. The URL can - * contain the query string as well. - * - * @param string $method HTTP method. - * @param string|UriInterface $uri URI object or string. - * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. - * - * @return ResponseInterface - * @throws GuzzleException - */ - public function request($method, $uri = '', array $options = []) - { - $options[RequestOptions::SYNCHRONOUS] = true; - return $this->requestAsync($method, $uri, $options)->wait(); - } - - /** - * Get a client configuration option. - * - * These options include default request options of the client, a "handler" - * (if utilized by the concrete client), and a "base_uri" if utilized by - * the concrete client. - * - * @param string|null $option The config option to retrieve. - * - * @return mixed - */ - public function getConfig($option = null) - { - return $option === null - ? $this->config - : (isset($this->config[$option]) ? $this->config[$option] : null); - } - - /** - * @param string|null $uri - * - * @return UriInterface - */ - private function buildUri($uri, array $config) - { - // for BC we accept null which would otherwise fail in uri_for - $uri = Psr7\uri_for($uri === null ? '' : $uri); - - if (isset($config['base_uri'])) { - $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri); - } - - if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) { - $idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion']; - $uri = Utils::idnUriConvert($uri, $idnOptions); - } - - return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri; - } - - /** - * Configures the default options for a client. - * - * @param array $config - * @return void - */ - private function configureDefaults(array $config) - { - $defaults = [ - 'allow_redirects' => RedirectMiddleware::$defaultSettings, - 'http_errors' => true, - 'decode_content' => true, - 'verify' => true, - 'cookies' => false, - 'idn_conversion' => true, - ]; - - // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. - - // We can only trust the HTTP_PROXY environment variable in a CLI - // process due to the fact that PHP has no reliable mechanism to - // get environment variables that start with "HTTP_". - if (php_sapi_name() === 'cli' && getenv('HTTP_PROXY')) { - $defaults['proxy']['http'] = getenv('HTTP_PROXY'); - } - - if ($proxy = getenv('HTTPS_PROXY')) { - $defaults['proxy']['https'] = $proxy; - } - - if ($noProxy = getenv('NO_PROXY')) { - $cleanedNoProxy = str_replace(' ', '', $noProxy); - $defaults['proxy']['no'] = explode(',', $cleanedNoProxy); - } - - $this->config = $config + $defaults; - - if (!empty($config['cookies']) && $config['cookies'] === true) { - $this->config['cookies'] = new CookieJar(); - } - - // Add the default user-agent header. - if (!isset($this->config['headers'])) { - $this->config['headers'] = ['User-Agent' => default_user_agent()]; - } else { - // Add the User-Agent header if one was not already set. - foreach (array_keys($this->config['headers']) as $name) { - if (strtolower($name) === 'user-agent') { - return; - } - } - $this->config['headers']['User-Agent'] = default_user_agent(); - } - } - - /** - * Merges default options into the array. - * - * @param array $options Options to modify by reference - * - * @return array - */ - private function prepareDefaults(array $options) - { - $defaults = $this->config; - - if (!empty($defaults['headers'])) { - // Default headers are only added if they are not present. - $defaults['_conditional'] = $defaults['headers']; - unset($defaults['headers']); - } - - // Special handling for headers is required as they are added as - // conditional headers and as headers passed to a request ctor. - if (array_key_exists('headers', $options)) { - // Allows default headers to be unset. - if ($options['headers'] === null) { - $defaults['_conditional'] = []; - unset($options['headers']); - } elseif (!is_array($options['headers'])) { - throw new \InvalidArgumentException('headers must be an array'); - } - } - - // Shallow merge defaults underneath options. - $result = $options + $defaults; - - // Remove null values. - foreach ($result as $k => $v) { - if ($v === null) { - unset($result[$k]); - } - } - - return $result; - } - - /** - * Transfers the given request and applies request options. - * - * The URI of the request is not modified and the request options are used - * as-is without merging in default options. - * - * @param array $options See \GuzzleHttp\RequestOptions. - * - * @return Promise\PromiseInterface - */ - private function transfer(RequestInterface $request, array $options) - { - // save_to -> sink - if (isset($options['save_to'])) { - $options['sink'] = $options['save_to']; - unset($options['save_to']); - } - - // exceptions -> http_errors - if (isset($options['exceptions'])) { - $options['http_errors'] = $options['exceptions']; - unset($options['exceptions']); - } - - $request = $this->applyOptions($request, $options); - /** @var HandlerStack $handler */ - $handler = $options['handler']; - - try { - return Promise\promise_for($handler($request, $options)); - } catch (\Exception $e) { - return Promise\rejection_for($e); - } - } - - /** - * Applies the array of request options to a request. - * - * @param RequestInterface $request - * @param array $options - * - * @return RequestInterface - */ - private function applyOptions(RequestInterface $request, array &$options) - { - $modify = [ - 'set_headers' => [], - ]; - - if (isset($options['headers'])) { - $modify['set_headers'] = $options['headers']; - unset($options['headers']); - } - - if (isset($options['form_params'])) { - if (isset($options['multipart'])) { - throw new \InvalidArgumentException('You cannot use ' - . 'form_params and multipart at the same time. Use the ' - . 'form_params option if you want to send application/' - . 'x-www-form-urlencoded requests, and the multipart ' - . 'option to send multipart/form-data requests.'); - } - $options['body'] = http_build_query($options['form_params'], '', '&'); - unset($options['form_params']); - // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']); - $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded'; - } - - if (isset($options['multipart'])) { - $options['body'] = new Psr7\MultipartStream($options['multipart']); - unset($options['multipart']); - } - - if (isset($options['json'])) { - $options['body'] = \GuzzleHttp\json_encode($options['json']); - unset($options['json']); - // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']); - $options['_conditional']['Content-Type'] = 'application/json'; - } - - if (!empty($options['decode_content']) - && $options['decode_content'] !== true - ) { - // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\_caseless_remove(['Accept-Encoding'], $options['_conditional']); - $modify['set_headers']['Accept-Encoding'] = $options['decode_content']; - } - - if (isset($options['body'])) { - if (is_array($options['body'])) { - $this->invalidBody(); - } - $modify['body'] = Psr7\stream_for($options['body']); - unset($options['body']); - } - - if (!empty($options['auth']) && is_array($options['auth'])) { - $value = $options['auth']; - $type = isset($value[2]) ? strtolower($value[2]) : 'basic'; - switch ($type) { - case 'basic': - // Ensure that we don't have the header in different case and set the new value. - $modify['set_headers'] = Psr7\_caseless_remove(['Authorization'], $modify['set_headers']); - $modify['set_headers']['Authorization'] = 'Basic ' - . base64_encode("$value[0]:$value[1]"); - break; - case 'digest': - // @todo: Do not rely on curl - $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST; - $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]"; - break; - case 'ntlm': - $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM; - $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]"; - break; - } - } - - if (isset($options['query'])) { - $value = $options['query']; - if (is_array($value)) { - $value = http_build_query($value, null, '&', PHP_QUERY_RFC3986); - } - if (!is_string($value)) { - throw new \InvalidArgumentException('query must be a string or array'); - } - $modify['query'] = $value; - unset($options['query']); - } - - // Ensure that sink is not an invalid value. - if (isset($options['sink'])) { - // TODO: Add more sink validation? - if (is_bool($options['sink'])) { - throw new \InvalidArgumentException('sink must not be a boolean'); - } - } - - $request = Psr7\modify_request($request, $modify); - if ($request->getBody() instanceof Psr7\MultipartStream) { - // Use a multipart/form-data POST if a Content-Type is not set. - // Ensure that we don't have the header in different case and set the new value. - $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']); - $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary=' - . $request->getBody()->getBoundary(); - } - - // Merge in conditional headers if they are not present. - if (isset($options['_conditional'])) { - // Build up the changes so it's in a single clone of the message. - $modify = []; - foreach ($options['_conditional'] as $k => $v) { - if (!$request->hasHeader($k)) { - $modify['set_headers'][$k] = $v; - } - } - $request = Psr7\modify_request($request, $modify); - // Don't pass this internal value along to middleware/handlers. - unset($options['_conditional']); - } - - return $request; - } - - /** - * Throw Exception with pre-set message. - * @return void - * @throws \InvalidArgumentException Invalid body. - */ - private function invalidBody() - { - throw new \InvalidArgumentException('Passing in the "body" request ' - . 'option as an array to send a POST request has been deprecated. ' - . 'Please use the "form_params" request option to send a ' - . 'application/x-www-form-urlencoded request, or the "multipart" ' - . 'request option to send a multipart/form-data request.'); - } -} + 'http://www.foo.com/1.0/', + * 'timeout' => 0, + * 'allow_redirects' => false, + * 'proxy' => '192.168.16.1:10' + * ]); + * + * Client configuration settings include the following options: + * + * - handler: (callable) Function that transfers HTTP requests over the + * wire. The function is called with a Psr7\Http\Message\RequestInterface + * and array of transfer options, and must return a + * GuzzleHttp\Promise\PromiseInterface that is fulfilled with a + * Psr7\Http\Message\ResponseInterface on success. + * If no handler is provided, a default handler will be created + * that enables all of the request options below by attaching all of the + * default middleware to the handler. + * - base_uri: (string|UriInterface) Base URI of the client that is merged + * into relative URIs. Can be a string or instance of UriInterface. + * - **: any request option + * + * @param array $config Client configuration settings. + * + * @see \GuzzleHttp\RequestOptions for a list of available request options. + */ + public function __construct(array $config = []) + { + if (!isset($config['handler'])) { + $config['handler'] = HandlerStack::create(); + } elseif (!is_callable($config['handler'])) { + throw new \InvalidArgumentException('handler must be a callable'); + } + + // Convert the base_uri to a UriInterface + if (isset($config['base_uri'])) { + $config['base_uri'] = Psr7\uri_for($config['base_uri']); + } + + $this->configureDefaults($config); + } + + /** + * @param string $method + * @param array $args + * + * @return Promise\PromiseInterface + */ + public function __call($method, $args) + { + if (count($args) < 1) { + throw new \InvalidArgumentException('Magic request methods require a URI and optional options array'); + } + + $uri = $args[0]; + $opts = isset($args[1]) ? $args[1] : []; + + return substr($method, -5) === 'Async' + ? $this->requestAsync(substr($method, 0, -5), $uri, $opts) + : $this->request($method, $uri, $opts); + } + + /** + * Asynchronously send an HTTP request. + * + * @param array $options Request options to apply to the given + * request and to the transfer. See \GuzzleHttp\RequestOptions. + * + * @return Promise\PromiseInterface + */ + public function sendAsync(RequestInterface $request, array $options = []) + { + // Merge the base URI into the request URI if needed. + $options = $this->prepareDefaults($options); + + return $this->transfer( + $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')), + $options + ); + } + + /** + * Send an HTTP request. + * + * @param array $options Request options to apply to the given + * request and to the transfer. See \GuzzleHttp\RequestOptions. + * + * @return ResponseInterface + * @throws GuzzleException + */ + public function send(RequestInterface $request, array $options = []) + { + $options[RequestOptions::SYNCHRONOUS] = true; + return $this->sendAsync($request, $options)->wait(); + } + + /** + * Create and send an asynchronous HTTP request. + * + * Use an absolute path to override the base path of the client, or a + * relative path to append to the base path of the client. The URL can + * contain the query string as well. Use an array to provide a URL + * template and additional variables to use in the URL template expansion. + * + * @param string $method HTTP method + * @param string|UriInterface $uri URI object or string. + * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. + * + * @return Promise\PromiseInterface + */ + public function requestAsync($method, $uri = '', array $options = []) + { + $options = $this->prepareDefaults($options); + // Remove request modifying parameter because it can be done up-front. + $headers = isset($options['headers']) ? $options['headers'] : []; + $body = isset($options['body']) ? $options['body'] : null; + $version = isset($options['version']) ? $options['version'] : '1.1'; + // Merge the URI into the base URI. + $uri = $this->buildUri($uri, $options); + if (is_array($body)) { + $this->invalidBody(); + } + $request = new Psr7\Request($method, $uri, $headers, $body, $version); + // Remove the option so that they are not doubly-applied. + unset($options['headers'], $options['body'], $options['version']); + + return $this->transfer($request, $options); + } + + /** + * Create and send an HTTP request. + * + * Use an absolute path to override the base path of the client, or a + * relative path to append to the base path of the client. The URL can + * contain the query string as well. + * + * @param string $method HTTP method. + * @param string|UriInterface $uri URI object or string. + * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. + * + * @return ResponseInterface + * @throws GuzzleException + */ + public function request($method, $uri = '', array $options = []) + { + $options[RequestOptions::SYNCHRONOUS] = true; + return $this->requestAsync($method, $uri, $options)->wait(); + } + + /** + * Get a client configuration option. + * + * These options include default request options of the client, a "handler" + * (if utilized by the concrete client), and a "base_uri" if utilized by + * the concrete client. + * + * @param string|null $option The config option to retrieve. + * + * @return mixed + */ + public function getConfig($option = null) + { + return $option === null + ? $this->config + : (isset($this->config[$option]) ? $this->config[$option] : null); + } + + /** + * @param string|null $uri + * + * @return UriInterface + */ + private function buildUri($uri, array $config) + { + // for BC we accept null which would otherwise fail in uri_for + $uri = Psr7\uri_for($uri === null ? '' : $uri); + + if (isset($config['base_uri'])) { + $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri); + } + + if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) { + $idnOptions = ($config['idn_conversion'] === true) ? IDNA_DEFAULT : $config['idn_conversion']; + $uri = Utils::idnUriConvert($uri, $idnOptions); + } + + return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri; + } + + /** + * Configures the default options for a client. + * + * @param array $config + * @return void + */ + private function configureDefaults(array $config) + { + $defaults = [ + 'allow_redirects' => RedirectMiddleware::$defaultSettings, + 'http_errors' => true, + 'decode_content' => true, + 'verify' => true, + 'cookies' => false, + 'idn_conversion' => true, + ]; + + // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. + + // We can only trust the HTTP_PROXY environment variable in a CLI + // process due to the fact that PHP has no reliable mechanism to + // get environment variables that start with "HTTP_". + if (php_sapi_name() === 'cli' && getenv('HTTP_PROXY')) { + $defaults['proxy']['http'] = getenv('HTTP_PROXY'); + } + + if ($proxy = getenv('HTTPS_PROXY')) { + $defaults['proxy']['https'] = $proxy; + } + + if ($noProxy = getenv('NO_PROXY')) { + $cleanedNoProxy = str_replace(' ', '', $noProxy); + $defaults['proxy']['no'] = explode(',', $cleanedNoProxy); + } + + $this->config = $config + $defaults; + + if (!empty($config['cookies']) && $config['cookies'] === true) { + $this->config['cookies'] = new CookieJar(); + } + + // Add the default user-agent header. + if (!isset($this->config['headers'])) { + $this->config['headers'] = ['User-Agent' => default_user_agent()]; + } else { + // Add the User-Agent header if one was not already set. + foreach (array_keys($this->config['headers']) as $name) { + if (strtolower($name) === 'user-agent') { + return; + } + } + $this->config['headers']['User-Agent'] = default_user_agent(); + } + } + + /** + * Merges default options into the array. + * + * @param array $options Options to modify by reference + * + * @return array + */ + private function prepareDefaults(array $options) + { + $defaults = $this->config; + + if (!empty($defaults['headers'])) { + // Default headers are only added if they are not present. + $defaults['_conditional'] = $defaults['headers']; + unset($defaults['headers']); + } + + // Special handling for headers is required as they are added as + // conditional headers and as headers passed to a request ctor. + if (array_key_exists('headers', $options)) { + // Allows default headers to be unset. + if ($options['headers'] === null) { + $defaults['_conditional'] = []; + unset($options['headers']); + } elseif (!is_array($options['headers'])) { + throw new \InvalidArgumentException('headers must be an array'); + } + } + + // Shallow merge defaults underneath options. + $result = $options + $defaults; + + // Remove null values. + foreach ($result as $k => $v) { + if ($v === null) { + unset($result[$k]); + } + } + + return $result; + } + + /** + * Transfers the given request and applies request options. + * + * The URI of the request is not modified and the request options are used + * as-is without merging in default options. + * + * @param array $options See \GuzzleHttp\RequestOptions. + * + * @return Promise\PromiseInterface + */ + private function transfer(RequestInterface $request, array $options) + { + // save_to -> sink + if (isset($options['save_to'])) { + $options['sink'] = $options['save_to']; + unset($options['save_to']); + } + + // exceptions -> http_errors + if (isset($options['exceptions'])) { + $options['http_errors'] = $options['exceptions']; + unset($options['exceptions']); + } + + $request = $this->applyOptions($request, $options); + /** @var HandlerStack $handler */ + $handler = $options['handler']; + + try { + return Promise\promise_for($handler($request, $options)); + } catch (\Exception $e) { + return Promise\rejection_for($e); + } + } + + /** + * Applies the array of request options to a request. + * + * @param RequestInterface $request + * @param array $options + * + * @return RequestInterface + */ + private function applyOptions(RequestInterface $request, array &$options) + { + $modify = [ + 'set_headers' => [], + ]; + + if (isset($options['headers'])) { + $modify['set_headers'] = $options['headers']; + unset($options['headers']); + } + + if (isset($options['form_params'])) { + if (isset($options['multipart'])) { + throw new \InvalidArgumentException('You cannot use ' + . 'form_params and multipart at the same time. Use the ' + . 'form_params option if you want to send application/' + . 'x-www-form-urlencoded requests, and the multipart ' + . 'option to send multipart/form-data requests.'); + } + $options['body'] = http_build_query($options['form_params'], '', '&'); + unset($options['form_params']); + // Ensure that we don't have the header in different case and set the new value. + $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']); + $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded'; + } + + if (isset($options['multipart'])) { + $options['body'] = new Psr7\MultipartStream($options['multipart']); + unset($options['multipart']); + } + + if (isset($options['json'])) { + $options['body'] = \GuzzleHttp\json_encode($options['json']); + unset($options['json']); + // Ensure that we don't have the header in different case and set the new value. + $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']); + $options['_conditional']['Content-Type'] = 'application/json'; + } + + if (!empty($options['decode_content']) + && $options['decode_content'] !== true + ) { + // Ensure that we don't have the header in different case and set the new value. + $options['_conditional'] = Psr7\_caseless_remove(['Accept-Encoding'], $options['_conditional']); + $modify['set_headers']['Accept-Encoding'] = $options['decode_content']; + } + + if (isset($options['body'])) { + if (is_array($options['body'])) { + $this->invalidBody(); + } + $modify['body'] = Psr7\stream_for($options['body']); + unset($options['body']); + } + + if (!empty($options['auth']) && is_array($options['auth'])) { + $value = $options['auth']; + $type = isset($value[2]) ? strtolower($value[2]) : 'basic'; + switch ($type) { + case 'basic': + // Ensure that we don't have the header in different case and set the new value. + $modify['set_headers'] = Psr7\_caseless_remove(['Authorization'], $modify['set_headers']); + $modify['set_headers']['Authorization'] = 'Basic ' + . base64_encode("$value[0]:$value[1]"); + break; + case 'digest': + // @todo: Do not rely on curl + $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST; + $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]"; + break; + case 'ntlm': + $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_NTLM; + $options['curl'][CURLOPT_USERPWD] = "$value[0]:$value[1]"; + break; + } + } + + if (isset($options['query'])) { + $value = $options['query']; + if (is_array($value)) { + $value = http_build_query($value, null, '&', PHP_QUERY_RFC3986); + } + if (!is_string($value)) { + throw new \InvalidArgumentException('query must be a string or array'); + } + $modify['query'] = $value; + unset($options['query']); + } + + // Ensure that sink is not an invalid value. + if (isset($options['sink'])) { + // TODO: Add more sink validation? + if (is_bool($options['sink'])) { + throw new \InvalidArgumentException('sink must not be a boolean'); + } + } + + $request = Psr7\modify_request($request, $modify); + if ($request->getBody() instanceof Psr7\MultipartStream) { + // Use a multipart/form-data POST if a Content-Type is not set. + // Ensure that we don't have the header in different case and set the new value. + $options['_conditional'] = Psr7\_caseless_remove(['Content-Type'], $options['_conditional']); + $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary=' + . $request->getBody()->getBoundary(); + } + + // Merge in conditional headers if they are not present. + if (isset($options['_conditional'])) { + // Build up the changes so it's in a single clone of the message. + $modify = []; + foreach ($options['_conditional'] as $k => $v) { + if (!$request->hasHeader($k)) { + $modify['set_headers'][$k] = $v; + } + } + $request = Psr7\modify_request($request, $modify); + // Don't pass this internal value along to middleware/handlers. + unset($options['_conditional']); + } + + return $request; + } + + /** + * Throw Exception with pre-set message. + * @return void + * @throws \InvalidArgumentException Invalid body. + */ + private function invalidBody() + { + throw new \InvalidArgumentException('Passing in the "body" request ' + . 'option as an array to send a POST request has been deprecated. ' + . 'Please use the "form_params" request option to send a ' + . 'application/x-www-form-urlencoded request, or the "multipart" ' + . 'request option to send a multipart/form-data request.'); + } +} diff --git a/vendor/guzzlehttp/guzzle/src/ClientInterface.php b/vendor/guzzlehttp/guzzle/src/ClientInterface.php index 638b75d..71e4f65 100644 --- a/vendor/guzzlehttp/guzzle/src/ClientInterface.php +++ b/vendor/guzzlehttp/guzzle/src/ClientInterface.php @@ -1,87 +1,87 @@ -strictMode = $strictMode; - - foreach ($cookieArray as $cookie) { - if (!($cookie instanceof SetCookie)) { - $cookie = new SetCookie($cookie); - } - $this->setCookie($cookie); - } - } - - /** - * Create a new Cookie jar from an associative array and domain. - * - * @param array $cookies Cookies to create the jar from - * @param string $domain Domain to set the cookies to - * - * @return self - */ - public static function fromArray(array $cookies, $domain) - { - $cookieJar = new self(); - foreach ($cookies as $name => $value) { - $cookieJar->setCookie(new SetCookie([ - 'Domain' => $domain, - 'Name' => $name, - 'Value' => $value, - 'Discard' => true - ])); - } - - return $cookieJar; - } - - /** - * @deprecated - */ - public static function getCookieValue($value) - { - return $value; - } - - /** - * Evaluate if this cookie should be persisted to storage - * that survives between requests. - * - * @param SetCookie $cookie Being evaluated. - * @param bool $allowSessionCookies If we should persist session cookies - * @return bool - */ - public static function shouldPersist( - SetCookie $cookie, - $allowSessionCookies = false - ) { - if ($cookie->getExpires() || $allowSessionCookies) { - if (!$cookie->getDiscard()) { - return true; - } - } - - return false; - } - - /** - * Finds and returns the cookie based on the name - * - * @param string $name cookie name to search for - * @return SetCookie|null cookie that was found or null if not found - */ - public function getCookieByName($name) - { - // don't allow a non string name - if ($name === null || !is_scalar($name)) { - return null; - } - foreach ($this->cookies as $cookie) { - if ($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) { - return $cookie; - } - } - - return null; - } - - public function toArray() - { - return array_map(function (SetCookie $cookie) { - return $cookie->toArray(); - }, $this->getIterator()->getArrayCopy()); - } - - public function clear($domain = null, $path = null, $name = null) - { - if (!$domain) { - $this->cookies = []; - return; - } elseif (!$path) { - $this->cookies = array_filter( - $this->cookies, - function (SetCookie $cookie) use ($domain) { - return !$cookie->matchesDomain($domain); - } - ); - } elseif (!$name) { - $this->cookies = array_filter( - $this->cookies, - function (SetCookie $cookie) use ($path, $domain) { - return !($cookie->matchesPath($path) && - $cookie->matchesDomain($domain)); - } - ); - } else { - $this->cookies = array_filter( - $this->cookies, - function (SetCookie $cookie) use ($path, $domain, $name) { - return !($cookie->getName() == $name && - $cookie->matchesPath($path) && - $cookie->matchesDomain($domain)); - } - ); - } - } - - public function clearSessionCookies() - { - $this->cookies = array_filter( - $this->cookies, - function (SetCookie $cookie) { - return !$cookie->getDiscard() && $cookie->getExpires(); - } - ); - } - - public function setCookie(SetCookie $cookie) - { - // If the name string is empty (but not 0), ignore the set-cookie - // string entirely. - $name = $cookie->getName(); - if (!$name && $name !== '0') { - return false; - } - - // Only allow cookies with set and valid domain, name, value - $result = $cookie->validate(); - if ($result !== true) { - if ($this->strictMode) { - throw new \RuntimeException('Invalid cookie: ' . $result); - } else { - $this->removeCookieIfEmpty($cookie); - return false; - } - } - - // Resolve conflicts with previously set cookies - foreach ($this->cookies as $i => $c) { - - // Two cookies are identical, when their path, and domain are - // identical. - if ($c->getPath() != $cookie->getPath() || - $c->getDomain() != $cookie->getDomain() || - $c->getName() != $cookie->getName() - ) { - continue; - } - - // The previously set cookie is a discard cookie and this one is - // not so allow the new cookie to be set - if (!$cookie->getDiscard() && $c->getDiscard()) { - unset($this->cookies[$i]); - continue; - } - - // If the new cookie's expiration is further into the future, then - // replace the old cookie - if ($cookie->getExpires() > $c->getExpires()) { - unset($this->cookies[$i]); - continue; - } - - // If the value has changed, we better change it - if ($cookie->getValue() !== $c->getValue()) { - unset($this->cookies[$i]); - continue; - } - - // The cookie exists, so no need to continue - return false; - } - - $this->cookies[] = $cookie; - - return true; - } - - public function count() - { - return count($this->cookies); - } - - public function getIterator() - { - return new \ArrayIterator(array_values($this->cookies)); - } - - public function extractCookies( - RequestInterface $request, - ResponseInterface $response - ) { - if ($cookieHeader = $response->getHeader('Set-Cookie')) { - foreach ($cookieHeader as $cookie) { - $sc = SetCookie::fromString($cookie); - if (!$sc->getDomain()) { - $sc->setDomain($request->getUri()->getHost()); - } - if (0 !== strpos($sc->getPath(), '/')) { - $sc->setPath($this->getCookiePathFromRequest($request)); - } - $this->setCookie($sc); - } - } - } - - /** - * Computes cookie path following RFC 6265 section 5.1.4 - * - * @link https://tools.ietf.org/html/rfc6265#section-5.1.4 - * - * @param RequestInterface $request - * @return string - */ - private function getCookiePathFromRequest(RequestInterface $request) - { - $uriPath = $request->getUri()->getPath(); - if ('' === $uriPath) { - return '/'; - } - if (0 !== strpos($uriPath, '/')) { - return '/'; - } - if ('/' === $uriPath) { - return '/'; - } - if (0 === $lastSlashPos = strrpos($uriPath, '/')) { - return '/'; - } - - return substr($uriPath, 0, $lastSlashPos); - } - - public function withCookieHeader(RequestInterface $request) - { - $values = []; - $uri = $request->getUri(); - $scheme = $uri->getScheme(); - $host = $uri->getHost(); - $path = $uri->getPath() ?: '/'; - - foreach ($this->cookies as $cookie) { - if ($cookie->matchesPath($path) && - $cookie->matchesDomain($host) && - !$cookie->isExpired() && - (!$cookie->getSecure() || $scheme === 'https') - ) { - $values[] = $cookie->getName() . '=' - . $cookie->getValue(); - } - } - - return $values - ? $request->withHeader('Cookie', implode('; ', $values)) - : $request; - } - - /** - * If a cookie already exists and the server asks to set it again with a - * null value, the cookie must be deleted. - * - * @param SetCookie $cookie - */ - private function removeCookieIfEmpty(SetCookie $cookie) - { - $cookieValue = $cookie->getValue(); - if ($cookieValue === null || $cookieValue === '') { - $this->clear( - $cookie->getDomain(), - $cookie->getPath(), - $cookie->getName() - ); - } - } -} +strictMode = $strictMode; + + foreach ($cookieArray as $cookie) { + if (!($cookie instanceof SetCookie)) { + $cookie = new SetCookie($cookie); + } + $this->setCookie($cookie); + } + } + + /** + * Create a new Cookie jar from an associative array and domain. + * + * @param array $cookies Cookies to create the jar from + * @param string $domain Domain to set the cookies to + * + * @return self + */ + public static function fromArray(array $cookies, $domain) + { + $cookieJar = new self(); + foreach ($cookies as $name => $value) { + $cookieJar->setCookie(new SetCookie([ + 'Domain' => $domain, + 'Name' => $name, + 'Value' => $value, + 'Discard' => true + ])); + } + + return $cookieJar; + } + + /** + * @deprecated + */ + public static function getCookieValue($value) + { + return $value; + } + + /** + * Evaluate if this cookie should be persisted to storage + * that survives between requests. + * + * @param SetCookie $cookie Being evaluated. + * @param bool $allowSessionCookies If we should persist session cookies + * @return bool + */ + public static function shouldPersist( + SetCookie $cookie, + $allowSessionCookies = false + ) { + if ($cookie->getExpires() || $allowSessionCookies) { + if (!$cookie->getDiscard()) { + return true; + } + } + + return false; + } + + /** + * Finds and returns the cookie based on the name + * + * @param string $name cookie name to search for + * @return SetCookie|null cookie that was found or null if not found + */ + public function getCookieByName($name) + { + // don't allow a non string name + if ($name === null || !is_scalar($name)) { + return null; + } + foreach ($this->cookies as $cookie) { + if ($cookie->getName() !== null && strcasecmp($cookie->getName(), $name) === 0) { + return $cookie; + } + } + + return null; + } + + public function toArray() + { + return array_map(function (SetCookie $cookie) { + return $cookie->toArray(); + }, $this->getIterator()->getArrayCopy()); + } + + public function clear($domain = null, $path = null, $name = null) + { + if (!$domain) { + $this->cookies = []; + return; + } elseif (!$path) { + $this->cookies = array_filter( + $this->cookies, + function (SetCookie $cookie) use ($domain) { + return !$cookie->matchesDomain($domain); + } + ); + } elseif (!$name) { + $this->cookies = array_filter( + $this->cookies, + function (SetCookie $cookie) use ($path, $domain) { + return !($cookie->matchesPath($path) && + $cookie->matchesDomain($domain)); + } + ); + } else { + $this->cookies = array_filter( + $this->cookies, + function (SetCookie $cookie) use ($path, $domain, $name) { + return !($cookie->getName() == $name && + $cookie->matchesPath($path) && + $cookie->matchesDomain($domain)); + } + ); + } + } + + public function clearSessionCookies() + { + $this->cookies = array_filter( + $this->cookies, + function (SetCookie $cookie) { + return !$cookie->getDiscard() && $cookie->getExpires(); + } + ); + } + + public function setCookie(SetCookie $cookie) + { + // If the name string is empty (but not 0), ignore the set-cookie + // string entirely. + $name = $cookie->getName(); + if (!$name && $name !== '0') { + return false; + } + + // Only allow cookies with set and valid domain, name, value + $result = $cookie->validate(); + if ($result !== true) { + if ($this->strictMode) { + throw new \RuntimeException('Invalid cookie: ' . $result); + } else { + $this->removeCookieIfEmpty($cookie); + return false; + } + } + + // Resolve conflicts with previously set cookies + foreach ($this->cookies as $i => $c) { + + // Two cookies are identical, when their path, and domain are + // identical. + if ($c->getPath() != $cookie->getPath() || + $c->getDomain() != $cookie->getDomain() || + $c->getName() != $cookie->getName() + ) { + continue; + } + + // The previously set cookie is a discard cookie and this one is + // not so allow the new cookie to be set + if (!$cookie->getDiscard() && $c->getDiscard()) { + unset($this->cookies[$i]); + continue; + } + + // If the new cookie's expiration is further into the future, then + // replace the old cookie + if ($cookie->getExpires() > $c->getExpires()) { + unset($this->cookies[$i]); + continue; + } + + // If the value has changed, we better change it + if ($cookie->getValue() !== $c->getValue()) { + unset($this->cookies[$i]); + continue; + } + + // The cookie exists, so no need to continue + return false; + } + + $this->cookies[] = $cookie; + + return true; + } + + public function count() + { + return count($this->cookies); + } + + public function getIterator() + { + return new \ArrayIterator(array_values($this->cookies)); + } + + public function extractCookies( + RequestInterface $request, + ResponseInterface $response + ) { + if ($cookieHeader = $response->getHeader('Set-Cookie')) { + foreach ($cookieHeader as $cookie) { + $sc = SetCookie::fromString($cookie); + if (!$sc->getDomain()) { + $sc->setDomain($request->getUri()->getHost()); + } + if (0 !== strpos($sc->getPath(), '/')) { + $sc->setPath($this->getCookiePathFromRequest($request)); + } + if (!$sc->matchesDomain($request->getUri()->getHost())) { + continue; + } + // Note: At this point `$sc->getDomain()` being a public suffix should + // be rejected, but we don't want to pull in the full PSL dependency. + $this->setCookie($sc); + } + } + } + + /** + * Computes cookie path following RFC 6265 section 5.1.4 + * + * @link https://tools.ietf.org/html/rfc6265#section-5.1.4 + * + * @param RequestInterface $request + * @return string + */ + private function getCookiePathFromRequest(RequestInterface $request) + { + $uriPath = $request->getUri()->getPath(); + if ('' === $uriPath) { + return '/'; + } + if (0 !== strpos($uriPath, '/')) { + return '/'; + } + if ('/' === $uriPath) { + return '/'; + } + if (0 === $lastSlashPos = strrpos($uriPath, '/')) { + return '/'; + } + + return substr($uriPath, 0, $lastSlashPos); + } + + public function withCookieHeader(RequestInterface $request) + { + $values = []; + $uri = $request->getUri(); + $scheme = $uri->getScheme(); + $host = $uri->getHost(); + $path = $uri->getPath() ?: '/'; + + foreach ($this->cookies as $cookie) { + if ($cookie->matchesPath($path) && + $cookie->matchesDomain($host) && + !$cookie->isExpired() && + (!$cookie->getSecure() || $scheme === 'https') + ) { + $values[] = $cookie->getName() . '=' + . $cookie->getValue(); + } + } + + return $values + ? $request->withHeader('Cookie', implode('; ', $values)) + : $request; + } + + /** + * If a cookie already exists and the server asks to set it again with a + * null value, the cookie must be deleted. + * + * @param SetCookie $cookie + */ + private function removeCookieIfEmpty(SetCookie $cookie) + { + $cookieValue = $cookie->getValue(); + if ($cookieValue === null || $cookieValue === '') { + $this->clear( + $cookie->getDomain(), + $cookie->getPath(), + $cookie->getName() + ); + } + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php b/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php index 6ee1188..315e040 100644 --- a/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php +++ b/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php @@ -1,84 +1,84 @@ -filename = $cookieFile; - $this->storeSessionCookies = $storeSessionCookies; - - if (file_exists($cookieFile)) { - $this->load($cookieFile); - } - } - - /** - * Saves the file when shutting down - */ - public function __destruct() - { - $this->save($this->filename); - } - - /** - * Saves the cookies to a file. - * - * @param string $filename File to save - * @throws \RuntimeException if the file cannot be found or created - */ - public function save($filename) - { - $json = []; - foreach ($this as $cookie) { - /** @var SetCookie $cookie */ - if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { - $json[] = $cookie->toArray(); - } - } - - $jsonStr = \GuzzleHttp\json_encode($json); - if (false === file_put_contents($filename, $jsonStr, LOCK_EX)) { - throw new \RuntimeException("Unable to save file {$filename}"); - } - } - - /** - * Load cookies from a JSON formatted file. - * - * Old cookies are kept unless overwritten by newly loaded ones. - * - * @param string $filename Cookie file to load. - * @throws \RuntimeException if the file cannot be loaded. - */ - public function load($filename) - { - $json = file_get_contents($filename); - if (false === $json) { - throw new \RuntimeException("Unable to load file {$filename}"); - } elseif ($json === '') { - return; - } - - $data = \GuzzleHttp\json_decode($json, true); - if (is_array($data)) { - foreach (json_decode($json, true) as $cookie) { - $this->setCookie(new SetCookie($cookie)); - } - } elseif (strlen($data)) { - throw new \RuntimeException("Invalid cookie file: {$filename}"); - } - } -} +filename = $cookieFile; + $this->storeSessionCookies = $storeSessionCookies; + + if (file_exists($cookieFile)) { + $this->load($cookieFile); + } + } + + /** + * Saves the file when shutting down + */ + public function __destruct() + { + $this->save($this->filename); + } + + /** + * Saves the cookies to a file. + * + * @param string $filename File to save + * @throws \RuntimeException if the file cannot be found or created + */ + public function save($filename) + { + $json = []; + foreach ($this as $cookie) { + /** @var SetCookie $cookie */ + if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { + $json[] = $cookie->toArray(); + } + } + + $jsonStr = \GuzzleHttp\json_encode($json); + if (false === file_put_contents($filename, $jsonStr, LOCK_EX)) { + throw new \RuntimeException("Unable to save file {$filename}"); + } + } + + /** + * Load cookies from a JSON formatted file. + * + * Old cookies are kept unless overwritten by newly loaded ones. + * + * @param string $filename Cookie file to load. + * @throws \RuntimeException if the file cannot be loaded. + */ + public function load($filename) + { + $json = file_get_contents($filename); + if (false === $json) { + throw new \RuntimeException("Unable to load file {$filename}"); + } elseif ($json === '') { + return; + } + + $data = \GuzzleHttp\json_decode($json, true); + if (is_array($data)) { + foreach (json_decode($json, true) as $cookie) { + $this->setCookie(new SetCookie($cookie)); + } + } elseif (strlen($data)) { + throw new \RuntimeException("Invalid cookie file: {$filename}"); + } + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php b/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php index 0224a24..d9b192f 100644 --- a/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php +++ b/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php @@ -1,72 +1,72 @@ -sessionKey = $sessionKey; - $this->storeSessionCookies = $storeSessionCookies; - $this->load(); - } - - /** - * Saves cookies to session when shutting down - */ - public function __destruct() - { - $this->save(); - } - - /** - * Save cookies to the client session - */ - public function save() - { - $json = []; - foreach ($this as $cookie) { - /** @var SetCookie $cookie */ - if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { - $json[] = $cookie->toArray(); - } - } - - $_SESSION[$this->sessionKey] = json_encode($json); - } - - /** - * Load the contents of the client session into the data array - */ - protected function load() - { - if (!isset($_SESSION[$this->sessionKey])) { - return; - } - $data = json_decode($_SESSION[$this->sessionKey], true); - if (is_array($data)) { - foreach ($data as $cookie) { - $this->setCookie(new SetCookie($cookie)); - } - } elseif (strlen($data)) { - throw new \RuntimeException("Invalid cookie data"); - } - } -} +sessionKey = $sessionKey; + $this->storeSessionCookies = $storeSessionCookies; + $this->load(); + } + + /** + * Saves cookies to session when shutting down + */ + public function __destruct() + { + $this->save(); + } + + /** + * Save cookies to the client session + */ + public function save() + { + $json = []; + foreach ($this as $cookie) { + /** @var SetCookie $cookie */ + if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { + $json[] = $cookie->toArray(); + } + } + + $_SESSION[$this->sessionKey] = json_encode($json); + } + + /** + * Load the contents of the client session into the data array + */ + protected function load() + { + if (!isset($_SESSION[$this->sessionKey])) { + return; + } + $data = json_decode($_SESSION[$this->sessionKey], true); + if (is_array($data)) { + foreach ($data as $cookie) { + $this->setCookie(new SetCookie($cookie)); + } + } elseif (strlen($data)) { + throw new \RuntimeException("Invalid cookie data"); + } + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php b/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php index 3d776a7..181ed99 100644 --- a/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php +++ b/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php @@ -1,403 +1,410 @@ - null, - 'Value' => null, - 'Domain' => null, - 'Path' => '/', - 'Max-Age' => null, - 'Expires' => null, - 'Secure' => false, - 'Discard' => false, - 'HttpOnly' => false - ]; - - /** @var array Cookie data */ - private $data; - - /** - * Create a new SetCookie object from a string - * - * @param string $cookie Set-Cookie header string - * - * @return self - */ - public static function fromString($cookie) - { - // Create the default return array - $data = self::$defaults; - // Explode the cookie string using a series of semicolons - $pieces = array_filter(array_map('trim', explode(';', $cookie))); - // The name of the cookie (first kvp) must exist and include an equal sign. - if (empty($pieces[0]) || !strpos($pieces[0], '=')) { - return new self($data); - } - - // Add the cookie pieces into the parsed data array - foreach ($pieces as $part) { - $cookieParts = explode('=', $part, 2); - $key = trim($cookieParts[0]); - $value = isset($cookieParts[1]) - ? trim($cookieParts[1], " \n\r\t\0\x0B") - : true; - - // Only check for non-cookies when cookies have been found - if (empty($data['Name'])) { - $data['Name'] = $key; - $data['Value'] = $value; - } else { - foreach (array_keys(self::$defaults) as $search) { - if (!strcasecmp($search, $key)) { - $data[$search] = $value; - continue 2; - } - } - $data[$key] = $value; - } - } - - return new self($data); - } - - /** - * @param array $data Array of cookie data provided by a Cookie parser - */ - public function __construct(array $data = []) - { - $this->data = array_replace(self::$defaults, $data); - // Extract the Expires value and turn it into a UNIX timestamp if needed - if (!$this->getExpires() && $this->getMaxAge()) { - // Calculate the Expires date - $this->setExpires(time() + $this->getMaxAge()); - } elseif ($this->getExpires() && !is_numeric($this->getExpires())) { - $this->setExpires($this->getExpires()); - } - } - - public function __toString() - { - $str = $this->data['Name'] . '=' . $this->data['Value'] . '; '; - foreach ($this->data as $k => $v) { - if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) { - if ($k === 'Expires') { - $str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; '; - } else { - $str .= ($v === true ? $k : "{$k}={$v}") . '; '; - } - } - } - - return rtrim($str, '; '); - } - - public function toArray() - { - return $this->data; - } - - /** - * Get the cookie name - * - * @return string - */ - public function getName() - { - return $this->data['Name']; - } - - /** - * Set the cookie name - * - * @param string $name Cookie name - */ - public function setName($name) - { - $this->data['Name'] = $name; - } - - /** - * Get the cookie value - * - * @return string - */ - public function getValue() - { - return $this->data['Value']; - } - - /** - * Set the cookie value - * - * @param string $value Cookie value - */ - public function setValue($value) - { - $this->data['Value'] = $value; - } - - /** - * Get the domain - * - * @return string|null - */ - public function getDomain() - { - return $this->data['Domain']; - } - - /** - * Set the domain of the cookie - * - * @param string $domain - */ - public function setDomain($domain) - { - $this->data['Domain'] = $domain; - } - - /** - * Get the path - * - * @return string - */ - public function getPath() - { - return $this->data['Path']; - } - - /** - * Set the path of the cookie - * - * @param string $path Path of the cookie - */ - public function setPath($path) - { - $this->data['Path'] = $path; - } - - /** - * Maximum lifetime of the cookie in seconds - * - * @return int|null - */ - public function getMaxAge() - { - return $this->data['Max-Age']; - } - - /** - * Set the max-age of the cookie - * - * @param int $maxAge Max age of the cookie in seconds - */ - public function setMaxAge($maxAge) - { - $this->data['Max-Age'] = $maxAge; - } - - /** - * The UNIX timestamp when the cookie Expires - * - * @return mixed - */ - public function getExpires() - { - return $this->data['Expires']; - } - - /** - * Set the unix timestamp for which the cookie will expire - * - * @param int $timestamp Unix timestamp - */ - public function setExpires($timestamp) - { - $this->data['Expires'] = is_numeric($timestamp) - ? (int) $timestamp - : strtotime($timestamp); - } - - /** - * Get whether or not this is a secure cookie - * - * @return bool|null - */ - public function getSecure() - { - return $this->data['Secure']; - } - - /** - * Set whether or not the cookie is secure - * - * @param bool $secure Set to true or false if secure - */ - public function setSecure($secure) - { - $this->data['Secure'] = $secure; - } - - /** - * Get whether or not this is a session cookie - * - * @return bool|null - */ - public function getDiscard() - { - return $this->data['Discard']; - } - - /** - * Set whether or not this is a session cookie - * - * @param bool $discard Set to true or false if this is a session cookie - */ - public function setDiscard($discard) - { - $this->data['Discard'] = $discard; - } - - /** - * Get whether or not this is an HTTP only cookie - * - * @return bool - */ - public function getHttpOnly() - { - return $this->data['HttpOnly']; - } - - /** - * Set whether or not this is an HTTP only cookie - * - * @param bool $httpOnly Set to true or false if this is HTTP only - */ - public function setHttpOnly($httpOnly) - { - $this->data['HttpOnly'] = $httpOnly; - } - - /** - * Check if the cookie matches a path value. - * - * A request-path path-matches a given cookie-path if at least one of - * the following conditions holds: - * - * - The cookie-path and the request-path are identical. - * - The cookie-path is a prefix of the request-path, and the last - * character of the cookie-path is %x2F ("/"). - * - The cookie-path is a prefix of the request-path, and the first - * character of the request-path that is not included in the cookie- - * path is a %x2F ("/") character. - * - * @param string $requestPath Path to check against - * - * @return bool - */ - public function matchesPath($requestPath) - { - $cookiePath = $this->getPath(); - - // Match on exact matches or when path is the default empty "/" - if ($cookiePath === '/' || $cookiePath == $requestPath) { - return true; - } - - // Ensure that the cookie-path is a prefix of the request path. - if (0 !== strpos($requestPath, $cookiePath)) { - return false; - } - - // Match if the last character of the cookie-path is "/" - if (substr($cookiePath, -1, 1) === '/') { - return true; - } - - // Match if the first character not included in cookie path is "/" - return substr($requestPath, strlen($cookiePath), 1) === '/'; - } - - /** - * Check if the cookie matches a domain value - * - * @param string $domain Domain to check against - * - * @return bool - */ - public function matchesDomain($domain) - { - // Remove the leading '.' as per spec in RFC 6265. - // http://tools.ietf.org/html/rfc6265#section-5.2.3 - $cookieDomain = ltrim($this->getDomain(), '.'); - - // Domain not set or exact match. - if (!$cookieDomain || !strcasecmp($domain, $cookieDomain)) { - return true; - } - - // Matching the subdomain according to RFC 6265. - // http://tools.ietf.org/html/rfc6265#section-5.1.3 - if (filter_var($domain, FILTER_VALIDATE_IP)) { - return false; - } - - return (bool) preg_match('/\.' . preg_quote($cookieDomain, '/') . '$/', $domain); - } - - /** - * Check if the cookie is expired - * - * @return bool - */ - public function isExpired() - { - return $this->getExpires() !== null && time() > $this->getExpires(); - } - - /** - * Check if the cookie is valid according to RFC 6265 - * - * @return bool|string Returns true if valid or an error message if invalid - */ - public function validate() - { - // Names must not be empty, but can be 0 - $name = $this->getName(); - if (empty($name) && !is_numeric($name)) { - return 'The cookie name must not be empty'; - } - - // Check if any of the invalid characters are present in the cookie name - if (preg_match( - '/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/', - $name - )) { - return 'Cookie name must not contain invalid characters: ASCII ' - . 'Control characters (0-31;127), space, tab and the ' - . 'following characters: ()<>@,;:\"/?={}'; - } - - // Value must not be empty, but can be 0 - $value = $this->getValue(); - if (empty($value) && !is_numeric($value)) { - return 'The cookie value must not be empty'; - } - - // Domains must not be empty, but can be 0 - // A "0" is not a valid internet domain, but may be used as server name - // in a private network. - $domain = $this->getDomain(); - if (empty($domain) && !is_numeric($domain)) { - return 'The cookie domain must not be empty'; - } - - return true; - } -} + null, + 'Value' => null, + 'Domain' => null, + 'Path' => '/', + 'Max-Age' => null, + 'Expires' => null, + 'Secure' => false, + 'Discard' => false, + 'HttpOnly' => false + ]; + + /** @var array Cookie data */ + private $data; + + /** + * Create a new SetCookie object from a string + * + * @param string $cookie Set-Cookie header string + * + * @return self + */ + public static function fromString($cookie) + { + // Create the default return array + $data = self::$defaults; + // Explode the cookie string using a series of semicolons + $pieces = array_filter(array_map('trim', explode(';', $cookie))); + // The name of the cookie (first kvp) must exist and include an equal sign. + if (empty($pieces[0]) || !strpos($pieces[0], '=')) { + return new self($data); + } + + // Add the cookie pieces into the parsed data array + foreach ($pieces as $part) { + $cookieParts = explode('=', $part, 2); + $key = trim($cookieParts[0]); + $value = isset($cookieParts[1]) + ? trim($cookieParts[1], " \n\r\t\0\x0B") + : true; + + // Only check for non-cookies when cookies have been found + if (empty($data['Name'])) { + $data['Name'] = $key; + $data['Value'] = $value; + } else { + foreach (array_keys(self::$defaults) as $search) { + if (!strcasecmp($search, $key)) { + $data[$search] = $value; + continue 2; + } + } + $data[$key] = $value; + } + } + + return new self($data); + } + + /** + * @param array $data Array of cookie data provided by a Cookie parser + */ + public function __construct(array $data = []) + { + $this->data = array_replace(self::$defaults, $data); + // Extract the Expires value and turn it into a UNIX timestamp if needed + if (!$this->getExpires() && $this->getMaxAge()) { + // Calculate the Expires date + $this->setExpires(time() + $this->getMaxAge()); + } elseif ($this->getExpires() && !is_numeric($this->getExpires())) { + $this->setExpires($this->getExpires()); + } + } + + public function __toString() + { + $str = $this->data['Name'] . '=' . $this->data['Value'] . '; '; + foreach ($this->data as $k => $v) { + if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) { + if ($k === 'Expires') { + $str .= 'Expires=' . gmdate('D, d M Y H:i:s \G\M\T', $v) . '; '; + } else { + $str .= ($v === true ? $k : "{$k}={$v}") . '; '; + } + } + } + + return rtrim($str, '; '); + } + + public function toArray() + { + return $this->data; + } + + /** + * Get the cookie name + * + * @return string + */ + public function getName() + { + return $this->data['Name']; + } + + /** + * Set the cookie name + * + * @param string $name Cookie name + */ + public function setName($name) + { + $this->data['Name'] = $name; + } + + /** + * Get the cookie value + * + * @return string + */ + public function getValue() + { + return $this->data['Value']; + } + + /** + * Set the cookie value + * + * @param string $value Cookie value + */ + public function setValue($value) + { + $this->data['Value'] = $value; + } + + /** + * Get the domain + * + * @return string|null + */ + public function getDomain() + { + return $this->data['Domain']; + } + + /** + * Set the domain of the cookie + * + * @param string $domain + */ + public function setDomain($domain) + { + $this->data['Domain'] = $domain; + } + + /** + * Get the path + * + * @return string + */ + public function getPath() + { + return $this->data['Path']; + } + + /** + * Set the path of the cookie + * + * @param string $path Path of the cookie + */ + public function setPath($path) + { + $this->data['Path'] = $path; + } + + /** + * Maximum lifetime of the cookie in seconds + * + * @return int|null + */ + public function getMaxAge() + { + return $this->data['Max-Age']; + } + + /** + * Set the max-age of the cookie + * + * @param int $maxAge Max age of the cookie in seconds + */ + public function setMaxAge($maxAge) + { + $this->data['Max-Age'] = $maxAge; + } + + /** + * The UNIX timestamp when the cookie Expires + * + * @return mixed + */ + public function getExpires() + { + return $this->data['Expires']; + } + + /** + * Set the unix timestamp for which the cookie will expire + * + * @param int $timestamp Unix timestamp + */ + public function setExpires($timestamp) + { + $this->data['Expires'] = is_numeric($timestamp) + ? (int) $timestamp + : strtotime($timestamp); + } + + /** + * Get whether or not this is a secure cookie + * + * @return bool|null + */ + public function getSecure() + { + return $this->data['Secure']; + } + + /** + * Set whether or not the cookie is secure + * + * @param bool $secure Set to true or false if secure + */ + public function setSecure($secure) + { + $this->data['Secure'] = $secure; + } + + /** + * Get whether or not this is a session cookie + * + * @return bool|null + */ + public function getDiscard() + { + return $this->data['Discard']; + } + + /** + * Set whether or not this is a session cookie + * + * @param bool $discard Set to true or false if this is a session cookie + */ + public function setDiscard($discard) + { + $this->data['Discard'] = $discard; + } + + /** + * Get whether or not this is an HTTP only cookie + * + * @return bool + */ + public function getHttpOnly() + { + return $this->data['HttpOnly']; + } + + /** + * Set whether or not this is an HTTP only cookie + * + * @param bool $httpOnly Set to true or false if this is HTTP only + */ + public function setHttpOnly($httpOnly) + { + $this->data['HttpOnly'] = $httpOnly; + } + + /** + * Check if the cookie matches a path value. + * + * A request-path path-matches a given cookie-path if at least one of + * the following conditions holds: + * + * - The cookie-path and the request-path are identical. + * - The cookie-path is a prefix of the request-path, and the last + * character of the cookie-path is %x2F ("/"). + * - The cookie-path is a prefix of the request-path, and the first + * character of the request-path that is not included in the cookie- + * path is a %x2F ("/") character. + * + * @param string $requestPath Path to check against + * + * @return bool + */ + public function matchesPath($requestPath) + { + $cookiePath = $this->getPath(); + + // Match on exact matches or when path is the default empty "/" + if ($cookiePath === '/' || $cookiePath == $requestPath) { + return true; + } + + // Ensure that the cookie-path is a prefix of the request path. + if (0 !== strpos($requestPath, $cookiePath)) { + return false; + } + + // Match if the last character of the cookie-path is "/" + if (substr($cookiePath, -1, 1) === '/') { + return true; + } + + // Match if the first character not included in cookie path is "/" + return substr($requestPath, strlen($cookiePath), 1) === '/'; + } + + /** + * Check if the cookie matches a domain value + * + * @param string $domain Domain to check against + * + * @return bool + */ + public function matchesDomain($domain) + { + $cookieDomain = $this->getDomain(); + if (null === $cookieDomain) { + return true; + } + + // Remove the leading '.' as per spec in RFC 6265. + // http://tools.ietf.org/html/rfc6265#section-5.2.3 + $cookieDomain = ltrim(strtolower($cookieDomain), '.'); + + $domain = strtolower($domain); + + // Domain not set or exact match. + if ('' === $cookieDomain || $domain === $cookieDomain) { + return true; + } + + // Matching the subdomain according to RFC 6265. + // http://tools.ietf.org/html/rfc6265#section-5.1.3 + if (filter_var($domain, FILTER_VALIDATE_IP)) { + return false; + } + + return (bool) preg_match('/\.' . preg_quote($cookieDomain, '/') . '$/', $domain); + } + + /** + * Check if the cookie is expired + * + * @return bool + */ + public function isExpired() + { + return $this->getExpires() !== null && time() > $this->getExpires(); + } + + /** + * Check if the cookie is valid according to RFC 6265 + * + * @return bool|string Returns true if valid or an error message if invalid + */ + public function validate() + { + // Names must not be empty, but can be 0 + $name = $this->getName(); + if (empty($name) && !is_numeric($name)) { + return 'The cookie name must not be empty'; + } + + // Check if any of the invalid characters are present in the cookie name + if (preg_match( + '/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/', + $name + )) { + return 'Cookie name must not contain invalid characters: ASCII ' + . 'Control characters (0-31;127), space, tab and the ' + . 'following characters: ()<>@,;:\"/?={}'; + } + + // Value must not be empty, but can be 0 + $value = $this->getValue(); + if (empty($value) && !is_numeric($value)) { + return 'The cookie value must not be empty'; + } + + // Domains must not be empty, but can be 0 + // A "0" is not a valid internet domain, but may be used as server name + // in a private network. + $domain = $this->getDomain(); + if (empty($domain) && !is_numeric($domain)) { + return 'The cookie domain must not be empty'; + } + + return true; + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php b/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php index 427d896..ffb065c 100644 --- a/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php +++ b/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php @@ -1,27 +1,27 @@ -getStatusCode() - : 0; - parent::__construct($message, $code, $previous); - $this->request = $request; - $this->response = $response; - $this->handlerContext = $handlerContext; - } - - /** - * Wrap non-RequestExceptions with a RequestException - * - * @param RequestInterface $request - * @param \Exception $e - * - * @return RequestException - */ - public static function wrapException(RequestInterface $request, \Exception $e) - { - return $e instanceof RequestException - ? $e - : new RequestException($e->getMessage(), $request, null, $e); - } - - /** - * Factory method to create a new exception with a normalized error message - * - * @param RequestInterface $request Request - * @param ResponseInterface $response Response received - * @param \Exception $previous Previous exception - * @param array $ctx Optional handler context. - * - * @return self - */ - public static function create( - RequestInterface $request, - ResponseInterface $response = null, - \Exception $previous = null, - array $ctx = [] - ) { - if (!$response) { - return new self( - 'Error completing request', - $request, - null, - $previous, - $ctx - ); - } - - $level = (int) floor($response->getStatusCode() / 100); - if ($level === 4) { - $label = 'Client error'; - $className = ClientException::class; - } elseif ($level === 5) { - $label = 'Server error'; - $className = ServerException::class; - } else { - $label = 'Unsuccessful request'; - $className = __CLASS__; - } - - $uri = $request->getUri(); - $uri = static::obfuscateUri($uri); - - // Client Error: `GET /` resulted in a `404 Not Found` response: - // ... (truncated) - $message = sprintf( - '%s: `%s %s` resulted in a `%s %s` response', - $label, - $request->getMethod(), - $uri, - $response->getStatusCode(), - $response->getReasonPhrase() - ); - - $summary = static::getResponseBodySummary($response); - - if ($summary !== null) { - $message .= ":\n{$summary}\n"; - } - - return new $className($message, $request, $response, $previous, $ctx); - } - - /** - * Get a short summary of the response - * - * Will return `null` if the response is not printable. - * - * @param ResponseInterface $response - * - * @return string|null - */ - public static function getResponseBodySummary(ResponseInterface $response) - { - return \GuzzleHttp\Psr7\get_message_body_summary($response); - } - - /** - * Obfuscates URI if there is a username and a password present - * - * @param UriInterface $uri - * - * @return UriInterface - */ - private static function obfuscateUri(UriInterface $uri) - { - $userInfo = $uri->getUserInfo(); - - if (false !== ($pos = strpos($userInfo, ':'))) { - return $uri->withUserInfo(substr($userInfo, 0, $pos), '***'); - } - - return $uri; - } - - /** - * Get the request that caused the exception - * - * @return RequestInterface - */ - public function getRequest() - { - return $this->request; - } - - /** - * Get the associated response - * - * @return ResponseInterface|null - */ - public function getResponse() - { - return $this->response; - } - - /** - * Check if a response was received - * - * @return bool - */ - public function hasResponse() - { - return $this->response !== null; - } - - /** - * Get contextual information about the error from the underlying handler. - * - * The contents of this array will vary depending on which handler you are - * using. It may also be just an empty array. Relying on this data will - * couple you to a specific handler, but can give more debug information - * when needed. - * - * @return array - */ - public function getHandlerContext() - { - return $this->handlerContext; - } -} +getStatusCode() + : 0; + parent::__construct($message, $code, $previous); + $this->request = $request; + $this->response = $response; + $this->handlerContext = $handlerContext; + } + + /** + * Wrap non-RequestExceptions with a RequestException + * + * @param RequestInterface $request + * @param \Exception $e + * + * @return RequestException + */ + public static function wrapException(RequestInterface $request, \Exception $e) + { + return $e instanceof RequestException + ? $e + : new RequestException($e->getMessage(), $request, null, $e); + } + + /** + * Factory method to create a new exception with a normalized error message + * + * @param RequestInterface $request Request + * @param ResponseInterface $response Response received + * @param \Exception $previous Previous exception + * @param array $ctx Optional handler context. + * + * @return self + */ + public static function create( + RequestInterface $request, + ResponseInterface $response = null, + \Exception $previous = null, + array $ctx = [] + ) { + if (!$response) { + return new self( + 'Error completing request', + $request, + null, + $previous, + $ctx + ); + } + + $level = (int) floor($response->getStatusCode() / 100); + if ($level === 4) { + $label = 'Client error'; + $className = ClientException::class; + } elseif ($level === 5) { + $label = 'Server error'; + $className = ServerException::class; + } else { + $label = 'Unsuccessful request'; + $className = __CLASS__; + } + + $uri = $request->getUri(); + $uri = static::obfuscateUri($uri); + + // Client Error: `GET /` resulted in a `404 Not Found` response: + // ... (truncated) + $message = sprintf( + '%s: `%s %s` resulted in a `%s %s` response', + $label, + $request->getMethod(), + $uri, + $response->getStatusCode(), + $response->getReasonPhrase() + ); + + $summary = static::getResponseBodySummary($response); + + if ($summary !== null) { + $message .= ":\n{$summary}\n"; + } + + return new $className($message, $request, $response, $previous, $ctx); + } + + /** + * Get a short summary of the response + * + * Will return `null` if the response is not printable. + * + * @param ResponseInterface $response + * + * @return string|null + */ + public static function getResponseBodySummary(ResponseInterface $response) + { + return \GuzzleHttp\Psr7\get_message_body_summary($response); + } + + /** + * Obfuscates URI if there is a username and a password present + * + * @param UriInterface $uri + * + * @return UriInterface + */ + private static function obfuscateUri(UriInterface $uri) + { + $userInfo = $uri->getUserInfo(); + + if (false !== ($pos = strpos($userInfo, ':'))) { + return $uri->withUserInfo(substr($userInfo, 0, $pos), '***'); + } + + return $uri; + } + + /** + * Get the request that caused the exception + * + * @return RequestInterface + */ + public function getRequest() + { + return $this->request; + } + + /** + * Get the associated response + * + * @return ResponseInterface|null + */ + public function getResponse() + { + return $this->response; + } + + /** + * Check if a response was received + * + * @return bool + */ + public function hasResponse() + { + return $this->response !== null; + } + + /** + * Get contextual information about the error from the underlying handler. + * + * The contents of this array will vary depending on which handler you are + * using. It may also be just an empty array. Relying on this data will + * couple you to a specific handler, but can give more debug information + * when needed. + * + * @return array + */ + public function getHandlerContext() + { + return $this->handlerContext; + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Exception/SeekException.php b/vendor/guzzlehttp/guzzle/src/Exception/SeekException.php index a77c289..cc8e665 100644 --- a/vendor/guzzlehttp/guzzle/src/Exception/SeekException.php +++ b/vendor/guzzlehttp/guzzle/src/Exception/SeekException.php @@ -1,27 +1,27 @@ -stream = $stream; - $msg = $msg ?: 'Could not seek the stream to position ' . $pos; - parent::__construct($msg); - } - - /** - * @return StreamInterface - */ - public function getStream() - { - return $this->stream; - } -} +stream = $stream; + $msg = $msg ?: 'Could not seek the stream to position ' . $pos; + parent::__construct($msg); + } + + /** + * @return StreamInterface + */ + public function getStream() + { + return $this->stream; + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php b/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php index 127094c..a573bc6 100644 --- a/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php +++ b/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php @@ -1,9 +1,9 @@ -maxHandles = $maxHandles; - } - - public function create(RequestInterface $request, array $options) - { - if (isset($options['curl']['body_as_string'])) { - $options['_body_as_string'] = $options['curl']['body_as_string']; - unset($options['curl']['body_as_string']); - } - - $easy = new EasyHandle; - $easy->request = $request; - $easy->options = $options; - $conf = $this->getDefaultConf($easy); - $this->applyMethod($easy, $conf); - $this->applyHandlerOptions($easy, $conf); - $this->applyHeaders($easy, $conf); - unset($conf['_headers']); - - // Add handler options from the request configuration options - if (isset($options['curl'])) { - $conf = array_replace($conf, $options['curl']); - } - - $conf[CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy); - $easy->handle = $this->handles - ? array_pop($this->handles) - : curl_init(); - curl_setopt_array($easy->handle, $conf); - - return $easy; - } - - public function release(EasyHandle $easy) - { - $resource = $easy->handle; - unset($easy->handle); - - if (count($this->handles) >= $this->maxHandles) { - curl_close($resource); - } else { - // Remove all callback functions as they can hold onto references - // and are not cleaned up by curl_reset. Using curl_setopt_array - // does not work for some reason, so removing each one - // individually. - curl_setopt($resource, CURLOPT_HEADERFUNCTION, null); - curl_setopt($resource, CURLOPT_READFUNCTION, null); - curl_setopt($resource, CURLOPT_WRITEFUNCTION, null); - curl_setopt($resource, CURLOPT_PROGRESSFUNCTION, null); - curl_reset($resource); - $this->handles[] = $resource; - } - } - - /** - * Completes a cURL transaction, either returning a response promise or a - * rejected promise. - * - * @param callable $handler - * @param EasyHandle $easy - * @param CurlFactoryInterface $factory Dictates how the handle is released - * - * @return \GuzzleHttp\Promise\PromiseInterface - */ - public static function finish( - callable $handler, - EasyHandle $easy, - CurlFactoryInterface $factory - ) { - if (isset($easy->options['on_stats'])) { - self::invokeStats($easy); - } - - if (!$easy->response || $easy->errno) { - return self::finishError($handler, $easy, $factory); - } - - // Return the response if it is present and there is no error. - $factory->release($easy); - - // Rewind the body of the response if possible. - $body = $easy->response->getBody(); - if ($body->isSeekable()) { - $body->rewind(); - } - - return new FulfilledPromise($easy->response); - } - - private static function invokeStats(EasyHandle $easy) - { - $curlStats = curl_getinfo($easy->handle); - $curlStats['appconnect_time'] = curl_getinfo($easy->handle, CURLINFO_APPCONNECT_TIME); - $stats = new TransferStats( - $easy->request, - $easy->response, - $curlStats['total_time'], - $easy->errno, - $curlStats - ); - call_user_func($easy->options['on_stats'], $stats); - } - - private static function finishError( - callable $handler, - EasyHandle $easy, - CurlFactoryInterface $factory - ) { - // Get error information and release the handle to the factory. - $ctx = [ - 'errno' => $easy->errno, - 'error' => curl_error($easy->handle), - 'appconnect_time' => curl_getinfo($easy->handle, CURLINFO_APPCONNECT_TIME), - ] + curl_getinfo($easy->handle); - $ctx[self::CURL_VERSION_STR] = curl_version()['version']; - $factory->release($easy); - - // Retry when nothing is present or when curl failed to rewind. - if (empty($easy->options['_err_message']) - && (!$easy->errno || $easy->errno == 65) - ) { - return self::retryFailedRewind($handler, $easy, $ctx); - } - - return self::createRejection($easy, $ctx); - } - - private static function createRejection(EasyHandle $easy, array $ctx) - { - static $connectionErrors = [ - CURLE_OPERATION_TIMEOUTED => true, - CURLE_COULDNT_RESOLVE_HOST => true, - CURLE_COULDNT_CONNECT => true, - CURLE_SSL_CONNECT_ERROR => true, - CURLE_GOT_NOTHING => true, - ]; - - // If an exception was encountered during the onHeaders event, then - // return a rejected promise that wraps that exception. - if ($easy->onHeadersException) { - return \GuzzleHttp\Promise\rejection_for( - new RequestException( - 'An error was encountered during the on_headers event', - $easy->request, - $easy->response, - $easy->onHeadersException, - $ctx - ) - ); - } - if (version_compare($ctx[self::CURL_VERSION_STR], self::LOW_CURL_VERSION_NUMBER)) { - $message = sprintf( - 'cURL error %s: %s (%s)', - $ctx['errno'], - $ctx['error'], - 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html' - ); - } else { - $message = sprintf( - 'cURL error %s: %s (%s) for %s', - $ctx['errno'], - $ctx['error'], - 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html', - $easy->request->getUri() - ); - } - - // Create a connection exception if it was a specific error code. - $error = isset($connectionErrors[$easy->errno]) - ? new ConnectException($message, $easy->request, null, $ctx) - : new RequestException($message, $easy->request, $easy->response, null, $ctx); - - return \GuzzleHttp\Promise\rejection_for($error); - } - - private function getDefaultConf(EasyHandle $easy) - { - $conf = [ - '_headers' => $easy->request->getHeaders(), - CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), - CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''), - CURLOPT_RETURNTRANSFER => false, - CURLOPT_HEADER => false, - CURLOPT_CONNECTTIMEOUT => 150, - ]; - - if (defined('CURLOPT_PROTOCOLS')) { - $conf[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; - } - - $version = $easy->request->getProtocolVersion(); - if ($version == 1.1) { - $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1; - } elseif ($version == 2.0) { - $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0; - } else { - $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0; - } - - return $conf; - } - - private function applyMethod(EasyHandle $easy, array &$conf) - { - $body = $easy->request->getBody(); - $size = $body->getSize(); - - if ($size === null || $size > 0) { - $this->applyBody($easy->request, $easy->options, $conf); - return; - } - - $method = $easy->request->getMethod(); - if ($method === 'PUT' || $method === 'POST') { - // See http://tools.ietf.org/html/rfc7230#section-3.3.2 - if (!$easy->request->hasHeader('Content-Length')) { - $conf[CURLOPT_HTTPHEADER][] = 'Content-Length: 0'; - } - } elseif ($method === 'HEAD') { - $conf[CURLOPT_NOBODY] = true; - unset( - $conf[CURLOPT_WRITEFUNCTION], - $conf[CURLOPT_READFUNCTION], - $conf[CURLOPT_FILE], - $conf[CURLOPT_INFILE] - ); - } - } - - private function applyBody(RequestInterface $request, array $options, array &$conf) - { - $size = $request->hasHeader('Content-Length') - ? (int) $request->getHeaderLine('Content-Length') - : null; - - // Send the body as a string if the size is less than 1MB OR if the - // [curl][body_as_string] request value is set. - if (($size !== null && $size < 1000000) || - !empty($options['_body_as_string']) - ) { - $conf[CURLOPT_POSTFIELDS] = (string) $request->getBody(); - // Don't duplicate the Content-Length header - $this->removeHeader('Content-Length', $conf); - $this->removeHeader('Transfer-Encoding', $conf); - } else { - $conf[CURLOPT_UPLOAD] = true; - if ($size !== null) { - $conf[CURLOPT_INFILESIZE] = $size; - $this->removeHeader('Content-Length', $conf); - } - $body = $request->getBody(); - if ($body->isSeekable()) { - $body->rewind(); - } - $conf[CURLOPT_READFUNCTION] = function ($ch, $fd, $length) use ($body) { - return $body->read($length); - }; - } - - // If the Expect header is not present, prevent curl from adding it - if (!$request->hasHeader('Expect')) { - $conf[CURLOPT_HTTPHEADER][] = 'Expect:'; - } - - // cURL sometimes adds a content-type by default. Prevent this. - if (!$request->hasHeader('Content-Type')) { - $conf[CURLOPT_HTTPHEADER][] = 'Content-Type:'; - } - } - - private function applyHeaders(EasyHandle $easy, array &$conf) - { - foreach ($conf['_headers'] as $name => $values) { - foreach ($values as $value) { - $value = (string) $value; - if ($value === '') { - // cURL requires a special format for empty headers. - // See https://github.com/guzzle/guzzle/issues/1882 for more details. - $conf[CURLOPT_HTTPHEADER][] = "$name;"; - } else { - $conf[CURLOPT_HTTPHEADER][] = "$name: $value"; - } - } - } - - // Remove the Accept header if one was not set - if (!$easy->request->hasHeader('Accept')) { - $conf[CURLOPT_HTTPHEADER][] = 'Accept:'; - } - } - - /** - * Remove a header from the options array. - * - * @param string $name Case-insensitive header to remove - * @param array $options Array of options to modify - */ - private function removeHeader($name, array &$options) - { - foreach (array_keys($options['_headers']) as $key) { - if (!strcasecmp($key, $name)) { - unset($options['_headers'][$key]); - return; - } - } - } - - private function applyHandlerOptions(EasyHandle $easy, array &$conf) - { - $options = $easy->options; - if (isset($options['verify'])) { - if ($options['verify'] === false) { - unset($conf[CURLOPT_CAINFO]); - $conf[CURLOPT_SSL_VERIFYHOST] = 0; - $conf[CURLOPT_SSL_VERIFYPEER] = false; - } else { - $conf[CURLOPT_SSL_VERIFYHOST] = 2; - $conf[CURLOPT_SSL_VERIFYPEER] = true; - if (is_string($options['verify'])) { - // Throw an error if the file/folder/link path is not valid or doesn't exist. - if (!file_exists($options['verify'])) { - throw new \InvalidArgumentException( - "SSL CA bundle not found: {$options['verify']}" - ); - } - // If it's a directory or a link to a directory use CURLOPT_CAPATH. - // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO. - if (is_dir($options['verify']) || - (is_link($options['verify']) && is_dir(readlink($options['verify'])))) { - $conf[CURLOPT_CAPATH] = $options['verify']; - } else { - $conf[CURLOPT_CAINFO] = $options['verify']; - } - } - } - } - - if (!empty($options['decode_content'])) { - $accept = $easy->request->getHeaderLine('Accept-Encoding'); - if ($accept) { - $conf[CURLOPT_ENCODING] = $accept; - } else { - $conf[CURLOPT_ENCODING] = ''; - // Don't let curl send the header over the wire - $conf[CURLOPT_HTTPHEADER][] = 'Accept-Encoding:'; - } - } - - if (isset($options['sink'])) { - $sink = $options['sink']; - if (!is_string($sink)) { - $sink = \GuzzleHttp\Psr7\stream_for($sink); - } elseif (!is_dir(dirname($sink))) { - // Ensure that the directory exists before failing in curl. - throw new \RuntimeException(sprintf( - 'Directory %s does not exist for sink value of %s', - dirname($sink), - $sink - )); - } else { - $sink = new LazyOpenStream($sink, 'w+'); - } - $easy->sink = $sink; - $conf[CURLOPT_WRITEFUNCTION] = function ($ch, $write) use ($sink) { - return $sink->write($write); - }; - } else { - // Use a default temp stream if no sink was set. - $conf[CURLOPT_FILE] = fopen('php://temp', 'w+'); - $easy->sink = Psr7\stream_for($conf[CURLOPT_FILE]); - } - $timeoutRequiresNoSignal = false; - if (isset($options['timeout'])) { - $timeoutRequiresNoSignal |= $options['timeout'] < 1; - $conf[CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000; - } - - // CURL default value is CURL_IPRESOLVE_WHATEVER - if (isset($options['force_ip_resolve'])) { - if ('v4' === $options['force_ip_resolve']) { - $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4; - } elseif ('v6' === $options['force_ip_resolve']) { - $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V6; - } - } - - if (isset($options['connect_timeout'])) { - $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1; - $conf[CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000; - } - - if ($timeoutRequiresNoSignal && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { - $conf[CURLOPT_NOSIGNAL] = true; - } - - if (isset($options['proxy'])) { - if (!is_array($options['proxy'])) { - $conf[CURLOPT_PROXY] = $options['proxy']; - } else { - $scheme = $easy->request->getUri()->getScheme(); - if (isset($options['proxy'][$scheme])) { - $host = $easy->request->getUri()->getHost(); - if (!isset($options['proxy']['no']) || - !\GuzzleHttp\is_host_in_noproxy($host, $options['proxy']['no']) - ) { - $conf[CURLOPT_PROXY] = $options['proxy'][$scheme]; - } - } - } - } - - if (isset($options['cert'])) { - $cert = $options['cert']; - if (is_array($cert)) { - $conf[CURLOPT_SSLCERTPASSWD] = $cert[1]; - $cert = $cert[0]; - } - if (!file_exists($cert)) { - throw new \InvalidArgumentException( - "SSL certificate not found: {$cert}" - ); - } - $conf[CURLOPT_SSLCERT] = $cert; - } - - if (isset($options['ssl_key'])) { - if (is_array($options['ssl_key'])) { - if (count($options['ssl_key']) === 2) { - list($sslKey, $conf[CURLOPT_SSLKEYPASSWD]) = $options['ssl_key']; - } else { - list($sslKey) = $options['ssl_key']; - } - } - - $sslKey = isset($sslKey) ? $sslKey: $options['ssl_key']; - - if (!file_exists($sslKey)) { - throw new \InvalidArgumentException( - "SSL private key not found: {$sslKey}" - ); - } - $conf[CURLOPT_SSLKEY] = $sslKey; - } - - if (isset($options['progress'])) { - $progress = $options['progress']; - if (!is_callable($progress)) { - throw new \InvalidArgumentException( - 'progress client option must be callable' - ); - } - $conf[CURLOPT_NOPROGRESS] = false; - $conf[CURLOPT_PROGRESSFUNCTION] = function () use ($progress) { - $args = func_get_args(); - // PHP 5.5 pushed the handle onto the start of the args - if (is_resource($args[0])) { - array_shift($args); - } - call_user_func_array($progress, $args); - }; - } - - if (!empty($options['debug'])) { - $conf[CURLOPT_STDERR] = \GuzzleHttp\debug_resource($options['debug']); - $conf[CURLOPT_VERBOSE] = true; - } - } - - /** - * This function ensures that a response was set on a transaction. If one - * was not set, then the request is retried if possible. This error - * typically means you are sending a payload, curl encountered a - * "Connection died, retrying a fresh connect" error, tried to rewind the - * stream, and then encountered a "necessary data rewind wasn't possible" - * error, causing the request to be sent through curl_multi_info_read() - * without an error status. - */ - private static function retryFailedRewind( - callable $handler, - EasyHandle $easy, - array $ctx - ) { - try { - // Only rewind if the body has been read from. - $body = $easy->request->getBody(); - if ($body->tell() > 0) { - $body->rewind(); - } - } catch (\RuntimeException $e) { - $ctx['error'] = 'The connection unexpectedly failed without ' - . 'providing an error. The request would have been retried, ' - . 'but attempting to rewind the request body failed. ' - . 'Exception: ' . $e; - return self::createRejection($easy, $ctx); - } - - // Retry no more than 3 times before giving up. - if (!isset($easy->options['_curl_retries'])) { - $easy->options['_curl_retries'] = 1; - } elseif ($easy->options['_curl_retries'] == 2) { - $ctx['error'] = 'The cURL request was retried 3 times ' - . 'and did not succeed. The most likely reason for the failure ' - . 'is that cURL was unable to rewind the body of the request ' - . 'and subsequent retries resulted in the same error. Turn on ' - . 'the debug option to see what went wrong. See ' - . 'https://bugs.php.net/bug.php?id=47204 for more information.'; - return self::createRejection($easy, $ctx); - } else { - $easy->options['_curl_retries']++; - } - - return $handler($easy->request, $easy->options); - } - - private function createHeaderFn(EasyHandle $easy) - { - if (isset($easy->options['on_headers'])) { - $onHeaders = $easy->options['on_headers']; - - if (!is_callable($onHeaders)) { - throw new \InvalidArgumentException('on_headers must be callable'); - } - } else { - $onHeaders = null; - } - - return function ($ch, $h) use ( - $onHeaders, - $easy, - &$startingResponse - ) { - $value = trim($h); - if ($value === '') { - $startingResponse = true; - $easy->createResponse(); - if ($onHeaders !== null) { - try { - $onHeaders($easy->response); - } catch (\Exception $e) { - // Associate the exception with the handle and trigger - // a curl header write error by returning 0. - $easy->onHeadersException = $e; - return -1; - } - } - } elseif ($startingResponse) { - $startingResponse = false; - $easy->headers = [$value]; - } else { - $easy->headers[] = $value; - } - return strlen($h); - }; - } -} +maxHandles = $maxHandles; + } + + public function create(RequestInterface $request, array $options) + { + if (isset($options['curl']['body_as_string'])) { + $options['_body_as_string'] = $options['curl']['body_as_string']; + unset($options['curl']['body_as_string']); + } + + $easy = new EasyHandle; + $easy->request = $request; + $easy->options = $options; + $conf = $this->getDefaultConf($easy); + $this->applyMethod($easy, $conf); + $this->applyHandlerOptions($easy, $conf); + $this->applyHeaders($easy, $conf); + unset($conf['_headers']); + + // Add handler options from the request configuration options + if (isset($options['curl'])) { + $conf = array_replace($conf, $options['curl']); + } + + $conf[CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy); + $easy->handle = $this->handles + ? array_pop($this->handles) + : curl_init(); + curl_setopt_array($easy->handle, $conf); + + return $easy; + } + + public function release(EasyHandle $easy) + { + $resource = $easy->handle; + unset($easy->handle); + + if (count($this->handles) >= $this->maxHandles) { + curl_close($resource); + } else { + // Remove all callback functions as they can hold onto references + // and are not cleaned up by curl_reset. Using curl_setopt_array + // does not work for some reason, so removing each one + // individually. + curl_setopt($resource, CURLOPT_HEADERFUNCTION, null); + curl_setopt($resource, CURLOPT_READFUNCTION, null); + curl_setopt($resource, CURLOPT_WRITEFUNCTION, null); + curl_setopt($resource, CURLOPT_PROGRESSFUNCTION, null); + curl_reset($resource); + $this->handles[] = $resource; + } + } + + /** + * Completes a cURL transaction, either returning a response promise or a + * rejected promise. + * + * @param callable $handler + * @param EasyHandle $easy + * @param CurlFactoryInterface $factory Dictates how the handle is released + * + * @return \GuzzleHttp\Promise\PromiseInterface + */ + public static function finish( + callable $handler, + EasyHandle $easy, + CurlFactoryInterface $factory + ) { + if (isset($easy->options['on_stats'])) { + self::invokeStats($easy); + } + + if (!$easy->response || $easy->errno) { + return self::finishError($handler, $easy, $factory); + } + + // Return the response if it is present and there is no error. + $factory->release($easy); + + // Rewind the body of the response if possible. + $body = $easy->response->getBody(); + if ($body->isSeekable()) { + $body->rewind(); + } + + return new FulfilledPromise($easy->response); + } + + private static function invokeStats(EasyHandle $easy) + { + $curlStats = curl_getinfo($easy->handle); + $curlStats['appconnect_time'] = curl_getinfo($easy->handle, CURLINFO_APPCONNECT_TIME); + $stats = new TransferStats( + $easy->request, + $easy->response, + $curlStats['total_time'], + $easy->errno, + $curlStats + ); + call_user_func($easy->options['on_stats'], $stats); + } + + private static function finishError( + callable $handler, + EasyHandle $easy, + CurlFactoryInterface $factory + ) { + // Get error information and release the handle to the factory. + $ctx = [ + 'errno' => $easy->errno, + 'error' => curl_error($easy->handle), + 'appconnect_time' => curl_getinfo($easy->handle, CURLINFO_APPCONNECT_TIME), + ] + curl_getinfo($easy->handle); + $ctx[self::CURL_VERSION_STR] = curl_version()['version']; + $factory->release($easy); + + // Retry when nothing is present or when curl failed to rewind. + if (empty($easy->options['_err_message']) + && (!$easy->errno || $easy->errno == 65) + ) { + return self::retryFailedRewind($handler, $easy, $ctx); + } + + return self::createRejection($easy, $ctx); + } + + private static function createRejection(EasyHandle $easy, array $ctx) + { + static $connectionErrors = [ + CURLE_OPERATION_TIMEOUTED => true, + CURLE_COULDNT_RESOLVE_HOST => true, + CURLE_COULDNT_CONNECT => true, + CURLE_SSL_CONNECT_ERROR => true, + CURLE_GOT_NOTHING => true, + ]; + + // If an exception was encountered during the onHeaders event, then + // return a rejected promise that wraps that exception. + if ($easy->onHeadersException) { + return \GuzzleHttp\Promise\rejection_for( + new RequestException( + 'An error was encountered during the on_headers event', + $easy->request, + $easy->response, + $easy->onHeadersException, + $ctx + ) + ); + } + if (version_compare($ctx[self::CURL_VERSION_STR], self::LOW_CURL_VERSION_NUMBER)) { + $message = sprintf( + 'cURL error %s: %s (%s)', + $ctx['errno'], + $ctx['error'], + 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html' + ); + } else { + $message = sprintf( + 'cURL error %s: %s (%s) for %s', + $ctx['errno'], + $ctx['error'], + 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html', + $easy->request->getUri() + ); + } + + // Create a connection exception if it was a specific error code. + $error = isset($connectionErrors[$easy->errno]) + ? new ConnectException($message, $easy->request, null, $ctx) + : new RequestException($message, $easy->request, $easy->response, null, $ctx); + + return \GuzzleHttp\Promise\rejection_for($error); + } + + private function getDefaultConf(EasyHandle $easy) + { + $conf = [ + '_headers' => $easy->request->getHeaders(), + CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), + CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''), + CURLOPT_RETURNTRANSFER => false, + CURLOPT_HEADER => false, + CURLOPT_CONNECTTIMEOUT => 150, + ]; + + if (defined('CURLOPT_PROTOCOLS')) { + $conf[CURLOPT_PROTOCOLS] = CURLPROTO_HTTP | CURLPROTO_HTTPS; + } + + $version = $easy->request->getProtocolVersion(); + if ($version == 1.1) { + $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1; + } elseif ($version == 2.0) { + $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_2_0; + } else { + $conf[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_0; + } + + return $conf; + } + + private function applyMethod(EasyHandle $easy, array &$conf) + { + $body = $easy->request->getBody(); + $size = $body->getSize(); + + if ($size === null || $size > 0) { + $this->applyBody($easy->request, $easy->options, $conf); + return; + } + + $method = $easy->request->getMethod(); + if ($method === 'PUT' || $method === 'POST') { + // See http://tools.ietf.org/html/rfc7230#section-3.3.2 + if (!$easy->request->hasHeader('Content-Length')) { + $conf[CURLOPT_HTTPHEADER][] = 'Content-Length: 0'; + } + } elseif ($method === 'HEAD') { + $conf[CURLOPT_NOBODY] = true; + unset( + $conf[CURLOPT_WRITEFUNCTION], + $conf[CURLOPT_READFUNCTION], + $conf[CURLOPT_FILE], + $conf[CURLOPT_INFILE] + ); + } + } + + private function applyBody(RequestInterface $request, array $options, array &$conf) + { + $size = $request->hasHeader('Content-Length') + ? (int) $request->getHeaderLine('Content-Length') + : null; + + // Send the body as a string if the size is less than 1MB OR if the + // [curl][body_as_string] request value is set. + if (($size !== null && $size < 1000000) || + !empty($options['_body_as_string']) + ) { + $conf[CURLOPT_POSTFIELDS] = (string) $request->getBody(); + // Don't duplicate the Content-Length header + $this->removeHeader('Content-Length', $conf); + $this->removeHeader('Transfer-Encoding', $conf); + } else { + $conf[CURLOPT_UPLOAD] = true; + if ($size !== null) { + $conf[CURLOPT_INFILESIZE] = $size; + $this->removeHeader('Content-Length', $conf); + } + $body = $request->getBody(); + if ($body->isSeekable()) { + $body->rewind(); + } + $conf[CURLOPT_READFUNCTION] = function ($ch, $fd, $length) use ($body) { + return $body->read($length); + }; + } + + // If the Expect header is not present, prevent curl from adding it + if (!$request->hasHeader('Expect')) { + $conf[CURLOPT_HTTPHEADER][] = 'Expect:'; + } + + // cURL sometimes adds a content-type by default. Prevent this. + if (!$request->hasHeader('Content-Type')) { + $conf[CURLOPT_HTTPHEADER][] = 'Content-Type:'; + } + } + + private function applyHeaders(EasyHandle $easy, array &$conf) + { + foreach ($conf['_headers'] as $name => $values) { + foreach ($values as $value) { + $value = (string) $value; + if ($value === '') { + // cURL requires a special format for empty headers. + // See https://github.com/guzzle/guzzle/issues/1882 for more details. + $conf[CURLOPT_HTTPHEADER][] = "$name;"; + } else { + $conf[CURLOPT_HTTPHEADER][] = "$name: $value"; + } + } + } + + // Remove the Accept header if one was not set + if (!$easy->request->hasHeader('Accept')) { + $conf[CURLOPT_HTTPHEADER][] = 'Accept:'; + } + } + + /** + * Remove a header from the options array. + * + * @param string $name Case-insensitive header to remove + * @param array $options Array of options to modify + */ + private function removeHeader($name, array &$options) + { + foreach (array_keys($options['_headers']) as $key) { + if (!strcasecmp($key, $name)) { + unset($options['_headers'][$key]); + return; + } + } + } + + private function applyHandlerOptions(EasyHandle $easy, array &$conf) + { + $options = $easy->options; + if (isset($options['verify'])) { + if ($options['verify'] === false) { + unset($conf[CURLOPT_CAINFO]); + $conf[CURLOPT_SSL_VERIFYHOST] = 0; + $conf[CURLOPT_SSL_VERIFYPEER] = false; + } else { + $conf[CURLOPT_SSL_VERIFYHOST] = 2; + $conf[CURLOPT_SSL_VERIFYPEER] = true; + if (is_string($options['verify'])) { + // Throw an error if the file/folder/link path is not valid or doesn't exist. + if (!file_exists($options['verify'])) { + throw new \InvalidArgumentException( + "SSL CA bundle not found: {$options['verify']}" + ); + } + // If it's a directory or a link to a directory use CURLOPT_CAPATH. + // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO. + if (is_dir($options['verify']) || + (is_link($options['verify']) && is_dir(readlink($options['verify'])))) { + $conf[CURLOPT_CAPATH] = $options['verify']; + } else { + $conf[CURLOPT_CAINFO] = $options['verify']; + } + } + } + } + + if (!empty($options['decode_content'])) { + $accept = $easy->request->getHeaderLine('Accept-Encoding'); + if ($accept) { + $conf[CURLOPT_ENCODING] = $accept; + } else { + $conf[CURLOPT_ENCODING] = ''; + // Don't let curl send the header over the wire + $conf[CURLOPT_HTTPHEADER][] = 'Accept-Encoding:'; + } + } + + if (isset($options['sink'])) { + $sink = $options['sink']; + if (!is_string($sink)) { + $sink = \GuzzleHttp\Psr7\stream_for($sink); + } elseif (!is_dir(dirname($sink))) { + // Ensure that the directory exists before failing in curl. + throw new \RuntimeException(sprintf( + 'Directory %s does not exist for sink value of %s', + dirname($sink), + $sink + )); + } else { + $sink = new LazyOpenStream($sink, 'w+'); + } + $easy->sink = $sink; + $conf[CURLOPT_WRITEFUNCTION] = function ($ch, $write) use ($sink) { + return $sink->write($write); + }; + } else { + // Use a default temp stream if no sink was set. + $conf[CURLOPT_FILE] = fopen('php://temp', 'w+'); + $easy->sink = Psr7\stream_for($conf[CURLOPT_FILE]); + } + $timeoutRequiresNoSignal = false; + if (isset($options['timeout'])) { + $timeoutRequiresNoSignal |= $options['timeout'] < 1; + $conf[CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000; + } + + // CURL default value is CURL_IPRESOLVE_WHATEVER + if (isset($options['force_ip_resolve'])) { + if ('v4' === $options['force_ip_resolve']) { + $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4; + } elseif ('v6' === $options['force_ip_resolve']) { + $conf[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V6; + } + } + + if (isset($options['connect_timeout'])) { + $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1; + $conf[CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000; + } + + if ($timeoutRequiresNoSignal && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { + $conf[CURLOPT_NOSIGNAL] = true; + } + + if (isset($options['proxy'])) { + if (!is_array($options['proxy'])) { + $conf[CURLOPT_PROXY] = $options['proxy']; + } else { + $scheme = $easy->request->getUri()->getScheme(); + if (isset($options['proxy'][$scheme])) { + $host = $easy->request->getUri()->getHost(); + if (!isset($options['proxy']['no']) || + !\GuzzleHttp\is_host_in_noproxy($host, $options['proxy']['no']) + ) { + $conf[CURLOPT_PROXY] = $options['proxy'][$scheme]; + } + } + } + } + + if (isset($options['cert'])) { + $cert = $options['cert']; + if (is_array($cert)) { + $conf[CURLOPT_SSLCERTPASSWD] = $cert[1]; + $cert = $cert[0]; + } + if (!file_exists($cert)) { + throw new \InvalidArgumentException( + "SSL certificate not found: {$cert}" + ); + } + $conf[CURLOPT_SSLCERT] = $cert; + } + + if (isset($options['ssl_key'])) { + if (is_array($options['ssl_key'])) { + if (count($options['ssl_key']) === 2) { + list($sslKey, $conf[CURLOPT_SSLKEYPASSWD]) = $options['ssl_key']; + } else { + list($sslKey) = $options['ssl_key']; + } + } + + $sslKey = isset($sslKey) ? $sslKey: $options['ssl_key']; + + if (!file_exists($sslKey)) { + throw new \InvalidArgumentException( + "SSL private key not found: {$sslKey}" + ); + } + $conf[CURLOPT_SSLKEY] = $sslKey; + } + + if (isset($options['progress'])) { + $progress = $options['progress']; + if (!is_callable($progress)) { + throw new \InvalidArgumentException( + 'progress client option must be callable' + ); + } + $conf[CURLOPT_NOPROGRESS] = false; + $conf[CURLOPT_PROGRESSFUNCTION] = function () use ($progress) { + $args = func_get_args(); + // PHP 5.5 pushed the handle onto the start of the args + if (is_resource($args[0])) { + array_shift($args); + } + call_user_func_array($progress, $args); + }; + } + + if (!empty($options['debug'])) { + $conf[CURLOPT_STDERR] = \GuzzleHttp\debug_resource($options['debug']); + $conf[CURLOPT_VERBOSE] = true; + } + } + + /** + * This function ensures that a response was set on a transaction. If one + * was not set, then the request is retried if possible. This error + * typically means you are sending a payload, curl encountered a + * "Connection died, retrying a fresh connect" error, tried to rewind the + * stream, and then encountered a "necessary data rewind wasn't possible" + * error, causing the request to be sent through curl_multi_info_read() + * without an error status. + */ + private static function retryFailedRewind( + callable $handler, + EasyHandle $easy, + array $ctx + ) { + try { + // Only rewind if the body has been read from. + $body = $easy->request->getBody(); + if ($body->tell() > 0) { + $body->rewind(); + } + } catch (\RuntimeException $e) { + $ctx['error'] = 'The connection unexpectedly failed without ' + . 'providing an error. The request would have been retried, ' + . 'but attempting to rewind the request body failed. ' + . 'Exception: ' . $e; + return self::createRejection($easy, $ctx); + } + + // Retry no more than 3 times before giving up. + if (!isset($easy->options['_curl_retries'])) { + $easy->options['_curl_retries'] = 1; + } elseif ($easy->options['_curl_retries'] == 2) { + $ctx['error'] = 'The cURL request was retried 3 times ' + . 'and did not succeed. The most likely reason for the failure ' + . 'is that cURL was unable to rewind the body of the request ' + . 'and subsequent retries resulted in the same error. Turn on ' + . 'the debug option to see what went wrong. See ' + . 'https://bugs.php.net/bug.php?id=47204 for more information.'; + return self::createRejection($easy, $ctx); + } else { + $easy->options['_curl_retries']++; + } + + return $handler($easy->request, $easy->options); + } + + private function createHeaderFn(EasyHandle $easy) + { + if (isset($easy->options['on_headers'])) { + $onHeaders = $easy->options['on_headers']; + + if (!is_callable($onHeaders)) { + throw new \InvalidArgumentException('on_headers must be callable'); + } + } else { + $onHeaders = null; + } + + return function ($ch, $h) use ( + $onHeaders, + $easy, + &$startingResponse + ) { + $value = trim($h); + if ($value === '') { + $startingResponse = true; + $easy->createResponse(); + if ($onHeaders !== null) { + try { + $onHeaders($easy->response); + } catch (\Exception $e) { + // Associate the exception with the handle and trigger + // a curl header write error by returning 0. + $easy->onHeadersException = $e; + return -1; + } + } + } elseif ($startingResponse) { + $startingResponse = false; + $easy->headers = [$value]; + } else { + $easy->headers[] = $value; + } + return strlen($h); + }; + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php b/vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php index b0fc236..9f556aa 100644 --- a/vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php +++ b/vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php @@ -1,27 +1,27 @@ -factory = isset($options['handle_factory']) - ? $options['handle_factory'] - : new CurlFactory(3); - } - - public function __invoke(RequestInterface $request, array $options) - { - if (isset($options['delay'])) { - usleep($options['delay'] * 1000); - } - - $easy = $this->factory->create($request, $options); - curl_exec($easy->handle); - $easy->errno = curl_errno($easy->handle); - - return CurlFactory::finish($this, $easy, $this->factory); - } -} +factory = isset($options['handle_factory']) + ? $options['handle_factory'] + : new CurlFactory(3); + } + + public function __invoke(RequestInterface $request, array $options) + { + if (isset($options['delay'])) { + usleep($options['delay'] * 1000); + } + + $easy = $this->factory->create($request, $options); + curl_exec($easy->handle); + $easy->errno = curl_errno($easy->handle); + + return CurlFactory::finish($this, $easy, $this->factory); + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php b/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php index 564c95f..b7a570f 100644 --- a/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php +++ b/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php @@ -1,219 +1,219 @@ -factory = isset($options['handle_factory']) - ? $options['handle_factory'] : new CurlFactory(50); - - if (isset($options['select_timeout'])) { - $this->selectTimeout = $options['select_timeout']; - } elseif ($selectTimeout = getenv('GUZZLE_CURL_SELECT_TIMEOUT')) { - $this->selectTimeout = $selectTimeout; - } else { - $this->selectTimeout = 1; - } - - $this->options = isset($options['options']) ? $options['options'] : []; - } - - public function __get($name) - { - if ($name === '_mh') { - $this->_mh = curl_multi_init(); - - foreach ($this->options as $option => $value) { - // A warning is raised in case of a wrong option. - curl_multi_setopt($this->_mh, $option, $value); - } - - // Further calls to _mh will return the value directly, without entering the - // __get() method at all. - return $this->_mh; - } - - throw new \BadMethodCallException(); - } - - public function __destruct() - { - if (isset($this->_mh)) { - curl_multi_close($this->_mh); - unset($this->_mh); - } - } - - public function __invoke(RequestInterface $request, array $options) - { - $easy = $this->factory->create($request, $options); - $id = (int) $easy->handle; - - $promise = new Promise( - [$this, 'execute'], - function () use ($id) { - return $this->cancel($id); - } - ); - - $this->addRequest(['easy' => $easy, 'deferred' => $promise]); - - return $promise; - } - - /** - * Ticks the curl event loop. - */ - public function tick() - { - // Add any delayed handles if needed. - if ($this->delays) { - $currentTime = Utils::currentTime(); - foreach ($this->delays as $id => $delay) { - if ($currentTime >= $delay) { - unset($this->delays[$id]); - curl_multi_add_handle( - $this->_mh, - $this->handles[$id]['easy']->handle - ); - } - } - } - - // Step through the task queue which may add additional requests. - P\queue()->run(); - - if ($this->active && - curl_multi_select($this->_mh, $this->selectTimeout) === -1 - ) { - // Perform a usleep if a select returns -1. - // See: https://bugs.php.net/bug.php?id=61141 - usleep(250); - } - - while (curl_multi_exec($this->_mh, $this->active) === CURLM_CALL_MULTI_PERFORM); - - $this->processMessages(); - } - - /** - * Runs until all outstanding connections have completed. - */ - public function execute() - { - $queue = P\queue(); - - while ($this->handles || !$queue->isEmpty()) { - // If there are no transfers, then sleep for the next delay - if (!$this->active && $this->delays) { - usleep($this->timeToNext()); - } - $this->tick(); - } - } - - private function addRequest(array $entry) - { - $easy = $entry['easy']; - $id = (int) $easy->handle; - $this->handles[$id] = $entry; - if (empty($easy->options['delay'])) { - curl_multi_add_handle($this->_mh, $easy->handle); - } else { - $this->delays[$id] = Utils::currentTime() + ($easy->options['delay'] / 1000); - } - } - - /** - * Cancels a handle from sending and removes references to it. - * - * @param int $id Handle ID to cancel and remove. - * - * @return bool True on success, false on failure. - */ - private function cancel($id) - { - // Cannot cancel if it has been processed. - if (!isset($this->handles[$id])) { - return false; - } - - $handle = $this->handles[$id]['easy']->handle; - unset($this->delays[$id], $this->handles[$id]); - curl_multi_remove_handle($this->_mh, $handle); - curl_close($handle); - - return true; - } - - private function processMessages() - { - while ($done = curl_multi_info_read($this->_mh)) { - $id = (int) $done['handle']; - curl_multi_remove_handle($this->_mh, $done['handle']); - - if (!isset($this->handles[$id])) { - // Probably was cancelled. - continue; - } - - $entry = $this->handles[$id]; - unset($this->handles[$id], $this->delays[$id]); - $entry['easy']->errno = $done['result']; - $entry['deferred']->resolve( - CurlFactory::finish( - $this, - $entry['easy'], - $this->factory - ) - ); - } - } - - private function timeToNext() - { - $currentTime = Utils::currentTime(); - $nextTime = PHP_INT_MAX; - foreach ($this->delays as $time) { - if ($time < $nextTime) { - $nextTime = $time; - } - } - - return max(0, $nextTime - $currentTime) * 1000000; - } -} +factory = isset($options['handle_factory']) + ? $options['handle_factory'] : new CurlFactory(50); + + if (isset($options['select_timeout'])) { + $this->selectTimeout = $options['select_timeout']; + } elseif ($selectTimeout = getenv('GUZZLE_CURL_SELECT_TIMEOUT')) { + $this->selectTimeout = $selectTimeout; + } else { + $this->selectTimeout = 1; + } + + $this->options = isset($options['options']) ? $options['options'] : []; + } + + public function __get($name) + { + if ($name === '_mh') { + $this->_mh = curl_multi_init(); + + foreach ($this->options as $option => $value) { + // A warning is raised in case of a wrong option. + curl_multi_setopt($this->_mh, $option, $value); + } + + // Further calls to _mh will return the value directly, without entering the + // __get() method at all. + return $this->_mh; + } + + throw new \BadMethodCallException(); + } + + public function __destruct() + { + if (isset($this->_mh)) { + curl_multi_close($this->_mh); + unset($this->_mh); + } + } + + public function __invoke(RequestInterface $request, array $options) + { + $easy = $this->factory->create($request, $options); + $id = (int) $easy->handle; + + $promise = new Promise( + [$this, 'execute'], + function () use ($id) { + return $this->cancel($id); + } + ); + + $this->addRequest(['easy' => $easy, 'deferred' => $promise]); + + return $promise; + } + + /** + * Ticks the curl event loop. + */ + public function tick() + { + // Add any delayed handles if needed. + if ($this->delays) { + $currentTime = Utils::currentTime(); + foreach ($this->delays as $id => $delay) { + if ($currentTime >= $delay) { + unset($this->delays[$id]); + curl_multi_add_handle( + $this->_mh, + $this->handles[$id]['easy']->handle + ); + } + } + } + + // Step through the task queue which may add additional requests. + P\queue()->run(); + + if ($this->active && + curl_multi_select($this->_mh, $this->selectTimeout) === -1 + ) { + // Perform a usleep if a select returns -1. + // See: https://bugs.php.net/bug.php?id=61141 + usleep(250); + } + + while (curl_multi_exec($this->_mh, $this->active) === CURLM_CALL_MULTI_PERFORM); + + $this->processMessages(); + } + + /** + * Runs until all outstanding connections have completed. + */ + public function execute() + { + $queue = P\queue(); + + while ($this->handles || !$queue->isEmpty()) { + // If there are no transfers, then sleep for the next delay + if (!$this->active && $this->delays) { + usleep($this->timeToNext()); + } + $this->tick(); + } + } + + private function addRequest(array $entry) + { + $easy = $entry['easy']; + $id = (int) $easy->handle; + $this->handles[$id] = $entry; + if (empty($easy->options['delay'])) { + curl_multi_add_handle($this->_mh, $easy->handle); + } else { + $this->delays[$id] = Utils::currentTime() + ($easy->options['delay'] / 1000); + } + } + + /** + * Cancels a handle from sending and removes references to it. + * + * @param int $id Handle ID to cancel and remove. + * + * @return bool True on success, false on failure. + */ + private function cancel($id) + { + // Cannot cancel if it has been processed. + if (!isset($this->handles[$id])) { + return false; + } + + $handle = $this->handles[$id]['easy']->handle; + unset($this->delays[$id], $this->handles[$id]); + curl_multi_remove_handle($this->_mh, $handle); + curl_close($handle); + + return true; + } + + private function processMessages() + { + while ($done = curl_multi_info_read($this->_mh)) { + $id = (int) $done['handle']; + curl_multi_remove_handle($this->_mh, $done['handle']); + + if (!isset($this->handles[$id])) { + // Probably was cancelled. + continue; + } + + $entry = $this->handles[$id]; + unset($this->handles[$id], $this->delays[$id]); + $entry['easy']->errno = $done['result']; + $entry['deferred']->resolve( + CurlFactory::finish( + $this, + $entry['easy'], + $this->factory + ) + ); + } + } + + private function timeToNext() + { + $currentTime = Utils::currentTime(); + $nextTime = PHP_INT_MAX; + foreach ($this->delays as $time) { + if ($time < $nextTime) { + $nextTime = $time; + } + } + + return max(0, $nextTime - $currentTime) * 1000000; + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php b/vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php index 7754e91..226d7f4 100644 --- a/vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php +++ b/vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php @@ -1,92 +1,92 @@ -headers)) { - throw new \RuntimeException('No headers have been received'); - } - - // HTTP-version SP status-code SP reason-phrase - $startLine = explode(' ', array_shift($this->headers), 3); - $headers = \GuzzleHttp\headers_from_lines($this->headers); - $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers); - - if (!empty($this->options['decode_content']) - && isset($normalizedKeys['content-encoding']) - ) { - $headers['x-encoded-content-encoding'] - = $headers[$normalizedKeys['content-encoding']]; - unset($headers[$normalizedKeys['content-encoding']]); - if (isset($normalizedKeys['content-length'])) { - $headers['x-encoded-content-length'] - = $headers[$normalizedKeys['content-length']]; - - $bodyLength = (int) $this->sink->getSize(); - if ($bodyLength) { - $headers[$normalizedKeys['content-length']] = $bodyLength; - } else { - unset($headers[$normalizedKeys['content-length']]); - } - } - } - - // Attach a response to the easy handle with the parsed headers. - $this->response = new Response( - $startLine[1], - $headers, - $this->sink, - substr($startLine[0], 5), - isset($startLine[2]) ? (string) $startLine[2] : null - ); - } - - public function __get($name) - { - $msg = $name === 'handle' - ? 'The EasyHandle has been released' - : 'Invalid property: ' . $name; - throw new \BadMethodCallException($msg); - } -} +headers)) { + throw new \RuntimeException('No headers have been received'); + } + + // HTTP-version SP status-code SP reason-phrase + $startLine = explode(' ', array_shift($this->headers), 3); + $headers = \GuzzleHttp\headers_from_lines($this->headers); + $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers); + + if (!empty($this->options['decode_content']) + && isset($normalizedKeys['content-encoding']) + ) { + $headers['x-encoded-content-encoding'] + = $headers[$normalizedKeys['content-encoding']]; + unset($headers[$normalizedKeys['content-encoding']]); + if (isset($normalizedKeys['content-length'])) { + $headers['x-encoded-content-length'] + = $headers[$normalizedKeys['content-length']]; + + $bodyLength = (int) $this->sink->getSize(); + if ($bodyLength) { + $headers[$normalizedKeys['content-length']] = $bodyLength; + } else { + unset($headers[$normalizedKeys['content-length']]); + } + } + } + + // Attach a response to the easy handle with the parsed headers. + $this->response = new Response( + $startLine[1], + $headers, + $this->sink, + substr($startLine[0], 5), + isset($startLine[2]) ? (string) $startLine[2] : null + ); + } + + public function __get($name) + { + $msg = $name === 'handle' + ? 'The EasyHandle has been released' + : 'Invalid property: ' . $name; + throw new \BadMethodCallException($msg); + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php b/vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php index 5b312bc..8fcfc95 100644 --- a/vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php +++ b/vendor/guzzlehttp/guzzle/src/Handler/MockHandler.php @@ -1,195 +1,195 @@ -onFulfilled = $onFulfilled; - $this->onRejected = $onRejected; - - if ($queue) { - call_user_func_array([$this, 'append'], $queue); - } - } - - public function __invoke(RequestInterface $request, array $options) - { - if (!$this->queue) { - throw new \OutOfBoundsException('Mock queue is empty'); - } - - if (isset($options['delay']) && is_numeric($options['delay'])) { - usleep($options['delay'] * 1000); - } - - $this->lastRequest = $request; - $this->lastOptions = $options; - $response = array_shift($this->queue); - - if (isset($options['on_headers'])) { - if (!is_callable($options['on_headers'])) { - throw new \InvalidArgumentException('on_headers must be callable'); - } - try { - $options['on_headers']($response); - } catch (\Exception $e) { - $msg = 'An error was encountered during the on_headers event'; - $response = new RequestException($msg, $request, $response, $e); - } - } - - if (is_callable($response)) { - $response = call_user_func($response, $request, $options); - } - - $response = $response instanceof \Exception - ? \GuzzleHttp\Promise\rejection_for($response) - : \GuzzleHttp\Promise\promise_for($response); - - return $response->then( - function ($value) use ($request, $options) { - $this->invokeStats($request, $options, $value); - if ($this->onFulfilled) { - call_user_func($this->onFulfilled, $value); - } - if (isset($options['sink'])) { - $contents = (string) $value->getBody(); - $sink = $options['sink']; - - if (is_resource($sink)) { - fwrite($sink, $contents); - } elseif (is_string($sink)) { - file_put_contents($sink, $contents); - } elseif ($sink instanceof \Psr\Http\Message\StreamInterface) { - $sink->write($contents); - } - } - - return $value; - }, - function ($reason) use ($request, $options) { - $this->invokeStats($request, $options, null, $reason); - if ($this->onRejected) { - call_user_func($this->onRejected, $reason); - } - return \GuzzleHttp\Promise\rejection_for($reason); - } - ); - } - - /** - * Adds one or more variadic requests, exceptions, callables, or promises - * to the queue. - */ - public function append() - { - foreach (func_get_args() as $value) { - if ($value instanceof ResponseInterface - || $value instanceof \Exception - || $value instanceof PromiseInterface - || is_callable($value) - ) { - $this->queue[] = $value; - } else { - throw new \InvalidArgumentException('Expected a response or ' - . 'exception. Found ' . \GuzzleHttp\describe_type($value)); - } - } - } - - /** - * Get the last received request. - * - * @return RequestInterface - */ - public function getLastRequest() - { - return $this->lastRequest; - } - - /** - * Get the last received request options. - * - * @return array - */ - public function getLastOptions() - { - return $this->lastOptions; - } - - /** - * Returns the number of remaining items in the queue. - * - * @return int - */ - public function count() - { - return count($this->queue); - } - - public function reset() - { - $this->queue = []; - } - - private function invokeStats( - RequestInterface $request, - array $options, - ResponseInterface $response = null, - $reason = null - ) { - if (isset($options['on_stats'])) { - $transferTime = isset($options['transfer_time']) ? $options['transfer_time'] : 0; - $stats = new TransferStats($request, $response, $transferTime, $reason); - call_user_func($options['on_stats'], $stats); - } - } -} +onFulfilled = $onFulfilled; + $this->onRejected = $onRejected; + + if ($queue) { + call_user_func_array([$this, 'append'], $queue); + } + } + + public function __invoke(RequestInterface $request, array $options) + { + if (!$this->queue) { + throw new \OutOfBoundsException('Mock queue is empty'); + } + + if (isset($options['delay']) && is_numeric($options['delay'])) { + usleep($options['delay'] * 1000); + } + + $this->lastRequest = $request; + $this->lastOptions = $options; + $response = array_shift($this->queue); + + if (isset($options['on_headers'])) { + if (!is_callable($options['on_headers'])) { + throw new \InvalidArgumentException('on_headers must be callable'); + } + try { + $options['on_headers']($response); + } catch (\Exception $e) { + $msg = 'An error was encountered during the on_headers event'; + $response = new RequestException($msg, $request, $response, $e); + } + } + + if (is_callable($response)) { + $response = call_user_func($response, $request, $options); + } + + $response = $response instanceof \Exception + ? \GuzzleHttp\Promise\rejection_for($response) + : \GuzzleHttp\Promise\promise_for($response); + + return $response->then( + function ($value) use ($request, $options) { + $this->invokeStats($request, $options, $value); + if ($this->onFulfilled) { + call_user_func($this->onFulfilled, $value); + } + if (isset($options['sink'])) { + $contents = (string) $value->getBody(); + $sink = $options['sink']; + + if (is_resource($sink)) { + fwrite($sink, $contents); + } elseif (is_string($sink)) { + file_put_contents($sink, $contents); + } elseif ($sink instanceof \Psr\Http\Message\StreamInterface) { + $sink->write($contents); + } + } + + return $value; + }, + function ($reason) use ($request, $options) { + $this->invokeStats($request, $options, null, $reason); + if ($this->onRejected) { + call_user_func($this->onRejected, $reason); + } + return \GuzzleHttp\Promise\rejection_for($reason); + } + ); + } + + /** + * Adds one or more variadic requests, exceptions, callables, or promises + * to the queue. + */ + public function append() + { + foreach (func_get_args() as $value) { + if ($value instanceof ResponseInterface + || $value instanceof \Exception + || $value instanceof PromiseInterface + || is_callable($value) + ) { + $this->queue[] = $value; + } else { + throw new \InvalidArgumentException('Expected a response or ' + . 'exception. Found ' . \GuzzleHttp\describe_type($value)); + } + } + } + + /** + * Get the last received request. + * + * @return RequestInterface + */ + public function getLastRequest() + { + return $this->lastRequest; + } + + /** + * Get the last received request options. + * + * @return array + */ + public function getLastOptions() + { + return $this->lastOptions; + } + + /** + * Returns the number of remaining items in the queue. + * + * @return int + */ + public function count() + { + return count($this->queue); + } + + public function reset() + { + $this->queue = []; + } + + private function invokeStats( + RequestInterface $request, + array $options, + ResponseInterface $response = null, + $reason = null + ) { + if (isset($options['on_stats'])) { + $transferTime = isset($options['transfer_time']) ? $options['transfer_time'] : 0; + $stats = new TransferStats($request, $response, $transferTime, $reason); + call_user_func($options['on_stats'], $stats); + } + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php b/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php index f8b00be..7ef5ad4 100644 --- a/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php +++ b/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php @@ -1,55 +1,55 @@ -withoutHeader('Expect'); - - // Append a content-length header if body size is zero to match - // cURL's behavior. - if (0 === $request->getBody()->getSize()) { - $request = $request->withHeader('Content-Length', '0'); - } - - return $this->createResponse( - $request, - $options, - $this->createStream($request, $options), - $startTime - ); - } catch (\InvalidArgumentException $e) { - throw $e; - } catch (\Exception $e) { - // Determine if the error was a networking error. - $message = $e->getMessage(); - // This list can probably get more comprehensive. - if (strpos($message, 'getaddrinfo') // DNS lookup failed - || strpos($message, 'Connection refused') - || strpos($message, "couldn't connect to host") // error on HHVM - || strpos($message, "connection attempt failed") - ) { - $e = new ConnectException($e->getMessage(), $request, $e); - } - $e = RequestException::wrapException($request, $e); - $this->invokeStats($options, $request, $startTime, null, $e); - - return \GuzzleHttp\Promise\rejection_for($e); - } - } - - private function invokeStats( - array $options, - RequestInterface $request, - $startTime, - ResponseInterface $response = null, - $error = null - ) { - if (isset($options['on_stats'])) { - $stats = new TransferStats( - $request, - $response, - Utils::currentTime() - $startTime, - $error, - [] - ); - call_user_func($options['on_stats'], $stats); - } - } - - private function createResponse( - RequestInterface $request, - array $options, - $stream, - $startTime - ) { - $hdrs = $this->lastHeaders; - $this->lastHeaders = []; - $parts = explode(' ', array_shift($hdrs), 3); - $ver = explode('/', $parts[0])[1]; - $status = $parts[1]; - $reason = isset($parts[2]) ? $parts[2] : null; - $headers = \GuzzleHttp\headers_from_lines($hdrs); - list($stream, $headers) = $this->checkDecode($options, $headers, $stream); - $stream = Psr7\stream_for($stream); - $sink = $stream; - - if (strcasecmp('HEAD', $request->getMethod())) { - $sink = $this->createSink($stream, $options); - } - - $response = new Psr7\Response($status, $headers, $sink, $ver, $reason); - - if (isset($options['on_headers'])) { - try { - $options['on_headers']($response); - } catch (\Exception $e) { - $msg = 'An error was encountered during the on_headers event'; - $ex = new RequestException($msg, $request, $response, $e); - return \GuzzleHttp\Promise\rejection_for($ex); - } - } - - // Do not drain when the request is a HEAD request because they have - // no body. - if ($sink !== $stream) { - $this->drain( - $stream, - $sink, - $response->getHeaderLine('Content-Length') - ); - } - - $this->invokeStats($options, $request, $startTime, $response, null); - - return new FulfilledPromise($response); - } - - private function createSink(StreamInterface $stream, array $options) - { - if (!empty($options['stream'])) { - return $stream; - } - - $sink = isset($options['sink']) - ? $options['sink'] - : fopen('php://temp', 'r+'); - - return is_string($sink) - ? new Psr7\LazyOpenStream($sink, 'w+') - : Psr7\stream_for($sink); - } - - private function checkDecode(array $options, array $headers, $stream) - { - // Automatically decode responses when instructed. - if (!empty($options['decode_content'])) { - $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers); - if (isset($normalizedKeys['content-encoding'])) { - $encoding = $headers[$normalizedKeys['content-encoding']]; - if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') { - $stream = new Psr7\InflateStream( - Psr7\stream_for($stream) - ); - $headers['x-encoded-content-encoding'] - = $headers[$normalizedKeys['content-encoding']]; - // Remove content-encoding header - unset($headers[$normalizedKeys['content-encoding']]); - // Fix content-length header - if (isset($normalizedKeys['content-length'])) { - $headers['x-encoded-content-length'] - = $headers[$normalizedKeys['content-length']]; - - $length = (int) $stream->getSize(); - if ($length === 0) { - unset($headers[$normalizedKeys['content-length']]); - } else { - $headers[$normalizedKeys['content-length']] = [$length]; - } - } - } - } - } - - return [$stream, $headers]; - } - - /** - * Drains the source stream into the "sink" client option. - * - * @param StreamInterface $source - * @param StreamInterface $sink - * @param string $contentLength Header specifying the amount of - * data to read. - * - * @return StreamInterface - * @throws \RuntimeException when the sink option is invalid. - */ - private function drain( - StreamInterface $source, - StreamInterface $sink, - $contentLength - ) { - // If a content-length header is provided, then stop reading once - // that number of bytes has been read. This can prevent infinitely - // reading from a stream when dealing with servers that do not honor - // Connection: Close headers. - Psr7\copy_to_stream( - $source, - $sink, - (strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1 - ); - - $sink->seek(0); - $source->close(); - - return $sink; - } - - /** - * Create a resource and check to ensure it was created successfully - * - * @param callable $callback Callable that returns stream resource - * - * @return resource - * @throws \RuntimeException on error - */ - private function createResource(callable $callback) - { - $errors = null; - set_error_handler(function ($_, $msg, $file, $line) use (&$errors) { - $errors[] = [ - 'message' => $msg, - 'file' => $file, - 'line' => $line - ]; - return true; - }); - - $resource = $callback(); - restore_error_handler(); - - if (!$resource) { - $message = 'Error creating resource: '; - foreach ($errors as $err) { - foreach ($err as $key => $value) { - $message .= "[$key] $value" . PHP_EOL; - } - } - throw new \RuntimeException(trim($message)); - } - - return $resource; - } - - private function createStream(RequestInterface $request, array $options) - { - static $methods; - if (!$methods) { - $methods = array_flip(get_class_methods(__CLASS__)); - } - - // HTTP/1.1 streams using the PHP stream wrapper require a - // Connection: close header - if ($request->getProtocolVersion() == '1.1' - && !$request->hasHeader('Connection') - ) { - $request = $request->withHeader('Connection', 'close'); - } - - // Ensure SSL is verified by default - if (!isset($options['verify'])) { - $options['verify'] = true; - } - - $params = []; - $context = $this->getDefaultContext($request); - - if (isset($options['on_headers']) && !is_callable($options['on_headers'])) { - throw new \InvalidArgumentException('on_headers must be callable'); - } - - if (!empty($options)) { - foreach ($options as $key => $value) { - $method = "add_{$key}"; - if (isset($methods[$method])) { - $this->{$method}($request, $context, $value, $params); - } - } - } - - if (isset($options['stream_context'])) { - if (!is_array($options['stream_context'])) { - throw new \InvalidArgumentException('stream_context must be an array'); - } - $context = array_replace_recursive( - $context, - $options['stream_context'] - ); - } - - // Microsoft NTLM authentication only supported with curl handler - if (isset($options['auth']) - && is_array($options['auth']) - && isset($options['auth'][2]) - && 'ntlm' == $options['auth'][2] - ) { - throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler'); - } - - $uri = $this->resolveHost($request, $options); - - $context = $this->createResource( - function () use ($context, $params) { - return stream_context_create($context, $params); - } - ); - - return $this->createResource( - function () use ($uri, &$http_response_header, $context, $options) { - $resource = fopen((string) $uri, 'r', null, $context); - $this->lastHeaders = $http_response_header; - - if (isset($options['read_timeout'])) { - $readTimeout = $options['read_timeout']; - $sec = (int) $readTimeout; - $usec = ($readTimeout - $sec) * 100000; - stream_set_timeout($resource, $sec, $usec); - } - - return $resource; - } - ); - } - - private function resolveHost(RequestInterface $request, array $options) - { - $uri = $request->getUri(); - - if (isset($options['force_ip_resolve']) && !filter_var($uri->getHost(), FILTER_VALIDATE_IP)) { - if ('v4' === $options['force_ip_resolve']) { - $records = dns_get_record($uri->getHost(), DNS_A); - if (!isset($records[0]['ip'])) { - throw new ConnectException( - sprintf( - "Could not resolve IPv4 address for host '%s'", - $uri->getHost() - ), - $request - ); - } - $uri = $uri->withHost($records[0]['ip']); - } elseif ('v6' === $options['force_ip_resolve']) { - $records = dns_get_record($uri->getHost(), DNS_AAAA); - if (!isset($records[0]['ipv6'])) { - throw new ConnectException( - sprintf( - "Could not resolve IPv6 address for host '%s'", - $uri->getHost() - ), - $request - ); - } - $uri = $uri->withHost('[' . $records[0]['ipv6'] . ']'); - } - } - - return $uri; - } - - private function getDefaultContext(RequestInterface $request) - { - $headers = ''; - foreach ($request->getHeaders() as $name => $value) { - foreach ($value as $val) { - $headers .= "$name: $val\r\n"; - } - } - - $context = [ - 'http' => [ - 'method' => $request->getMethod(), - 'header' => $headers, - 'protocol_version' => $request->getProtocolVersion(), - 'ignore_errors' => true, - 'follow_location' => 0, - ], - ]; - - $body = (string) $request->getBody(); - - if (!empty($body)) { - $context['http']['content'] = $body; - // Prevent the HTTP handler from adding a Content-Type header. - if (!$request->hasHeader('Content-Type')) { - $context['http']['header'] .= "Content-Type:\r\n"; - } - } - - $context['http']['header'] = rtrim($context['http']['header']); - - return $context; - } - - private function add_proxy(RequestInterface $request, &$options, $value, &$params) - { - if (!is_array($value)) { - $options['http']['proxy'] = $value; - } else { - $scheme = $request->getUri()->getScheme(); - if (isset($value[$scheme])) { - if (!isset($value['no']) - || !\GuzzleHttp\is_host_in_noproxy( - $request->getUri()->getHost(), - $value['no'] - ) - ) { - $options['http']['proxy'] = $value[$scheme]; - } - } - } - } - - private function add_timeout(RequestInterface $request, &$options, $value, &$params) - { - if ($value > 0) { - $options['http']['timeout'] = $value; - } - } - - private function add_verify(RequestInterface $request, &$options, $value, &$params) - { - if ($value === true) { - // PHP 5.6 or greater will find the system cert by default. When - // < 5.6, use the Guzzle bundled cacert. - if (PHP_VERSION_ID < 50600) { - $options['ssl']['cafile'] = \GuzzleHttp\default_ca_bundle(); - } - } elseif (is_string($value)) { - $options['ssl']['cafile'] = $value; - if (!file_exists($value)) { - throw new \RuntimeException("SSL CA bundle not found: $value"); - } - } elseif ($value === false) { - $options['ssl']['verify_peer'] = false; - $options['ssl']['verify_peer_name'] = false; - return; - } else { - throw new \InvalidArgumentException('Invalid verify request option'); - } - - $options['ssl']['verify_peer'] = true; - $options['ssl']['verify_peer_name'] = true; - $options['ssl']['allow_self_signed'] = false; - } - - private function add_cert(RequestInterface $request, &$options, $value, &$params) - { - if (is_array($value)) { - $options['ssl']['passphrase'] = $value[1]; - $value = $value[0]; - } - - if (!file_exists($value)) { - throw new \RuntimeException("SSL certificate not found: {$value}"); - } - - $options['ssl']['local_cert'] = $value; - } - - private function add_progress(RequestInterface $request, &$options, $value, &$params) - { - $this->addNotification( - $params, - function ($code, $a, $b, $c, $transferred, $total) use ($value) { - if ($code == STREAM_NOTIFY_PROGRESS) { - $value($total, $transferred, null, null); - } - } - ); - } - - private function add_debug(RequestInterface $request, &$options, $value, &$params) - { - if ($value === false) { - return; - } - - static $map = [ - STREAM_NOTIFY_CONNECT => 'CONNECT', - STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED', - STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT', - STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS', - STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS', - STREAM_NOTIFY_REDIRECTED => 'REDIRECTED', - STREAM_NOTIFY_PROGRESS => 'PROGRESS', - STREAM_NOTIFY_FAILURE => 'FAILURE', - STREAM_NOTIFY_COMPLETED => 'COMPLETED', - STREAM_NOTIFY_RESOLVE => 'RESOLVE', - ]; - static $args = ['severity', 'message', 'message_code', - 'bytes_transferred', 'bytes_max']; - - $value = \GuzzleHttp\debug_resource($value); - $ident = $request->getMethod() . ' ' . $request->getUri()->withFragment(''); - $this->addNotification( - $params, - function () use ($ident, $value, $map, $args) { - $passed = func_get_args(); - $code = array_shift($passed); - fprintf($value, '<%s> [%s] ', $ident, $map[$code]); - foreach (array_filter($passed) as $i => $v) { - fwrite($value, $args[$i] . ': "' . $v . '" '); - } - fwrite($value, "\n"); - } - ); - } - - private function addNotification(array &$params, callable $notify) - { - // Wrap the existing function if needed. - if (!isset($params['notification'])) { - $params['notification'] = $notify; - } else { - $params['notification'] = $this->callArray([ - $params['notification'], - $notify - ]); - } - } - - private function callArray(array $functions) - { - return function () use ($functions) { - $args = func_get_args(); - foreach ($functions as $fn) { - call_user_func_array($fn, $args); - } - }; - } -} +withoutHeader('Expect'); + + // Append a content-length header if body size is zero to match + // cURL's behavior. + if (0 === $request->getBody()->getSize()) { + $request = $request->withHeader('Content-Length', '0'); + } + + return $this->createResponse( + $request, + $options, + $this->createStream($request, $options), + $startTime + ); + } catch (\InvalidArgumentException $e) { + throw $e; + } catch (\Exception $e) { + // Determine if the error was a networking error. + $message = $e->getMessage(); + // This list can probably get more comprehensive. + if (strpos($message, 'getaddrinfo') // DNS lookup failed + || strpos($message, 'Connection refused') + || strpos($message, "couldn't connect to host") // error on HHVM + || strpos($message, "connection attempt failed") + ) { + $e = new ConnectException($e->getMessage(), $request, $e); + } + $e = RequestException::wrapException($request, $e); + $this->invokeStats($options, $request, $startTime, null, $e); + + return \GuzzleHttp\Promise\rejection_for($e); + } + } + + private function invokeStats( + array $options, + RequestInterface $request, + $startTime, + ResponseInterface $response = null, + $error = null + ) { + if (isset($options['on_stats'])) { + $stats = new TransferStats( + $request, + $response, + Utils::currentTime() - $startTime, + $error, + [] + ); + call_user_func($options['on_stats'], $stats); + } + } + + private function createResponse( + RequestInterface $request, + array $options, + $stream, + $startTime + ) { + $hdrs = $this->lastHeaders; + $this->lastHeaders = []; + $parts = explode(' ', array_shift($hdrs), 3); + $ver = explode('/', $parts[0])[1]; + $status = $parts[1]; + $reason = isset($parts[2]) ? $parts[2] : null; + $headers = \GuzzleHttp\headers_from_lines($hdrs); + list($stream, $headers) = $this->checkDecode($options, $headers, $stream); + $stream = Psr7\stream_for($stream); + $sink = $stream; + + if (strcasecmp('HEAD', $request->getMethod())) { + $sink = $this->createSink($stream, $options); + } + + $response = new Psr7\Response($status, $headers, $sink, $ver, $reason); + + if (isset($options['on_headers'])) { + try { + $options['on_headers']($response); + } catch (\Exception $e) { + $msg = 'An error was encountered during the on_headers event'; + $ex = new RequestException($msg, $request, $response, $e); + return \GuzzleHttp\Promise\rejection_for($ex); + } + } + + // Do not drain when the request is a HEAD request because they have + // no body. + if ($sink !== $stream) { + $this->drain( + $stream, + $sink, + $response->getHeaderLine('Content-Length') + ); + } + + $this->invokeStats($options, $request, $startTime, $response, null); + + return new FulfilledPromise($response); + } + + private function createSink(StreamInterface $stream, array $options) + { + if (!empty($options['stream'])) { + return $stream; + } + + $sink = isset($options['sink']) + ? $options['sink'] + : fopen('php://temp', 'r+'); + + return is_string($sink) + ? new Psr7\LazyOpenStream($sink, 'w+') + : Psr7\stream_for($sink); + } + + private function checkDecode(array $options, array $headers, $stream) + { + // Automatically decode responses when instructed. + if (!empty($options['decode_content'])) { + $normalizedKeys = \GuzzleHttp\normalize_header_keys($headers); + if (isset($normalizedKeys['content-encoding'])) { + $encoding = $headers[$normalizedKeys['content-encoding']]; + if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') { + $stream = new Psr7\InflateStream( + Psr7\stream_for($stream) + ); + $headers['x-encoded-content-encoding'] + = $headers[$normalizedKeys['content-encoding']]; + // Remove content-encoding header + unset($headers[$normalizedKeys['content-encoding']]); + // Fix content-length header + if (isset($normalizedKeys['content-length'])) { + $headers['x-encoded-content-length'] + = $headers[$normalizedKeys['content-length']]; + + $length = (int) $stream->getSize(); + if ($length === 0) { + unset($headers[$normalizedKeys['content-length']]); + } else { + $headers[$normalizedKeys['content-length']] = [$length]; + } + } + } + } + } + + return [$stream, $headers]; + } + + /** + * Drains the source stream into the "sink" client option. + * + * @param StreamInterface $source + * @param StreamInterface $sink + * @param string $contentLength Header specifying the amount of + * data to read. + * + * @return StreamInterface + * @throws \RuntimeException when the sink option is invalid. + */ + private function drain( + StreamInterface $source, + StreamInterface $sink, + $contentLength + ) { + // If a content-length header is provided, then stop reading once + // that number of bytes has been read. This can prevent infinitely + // reading from a stream when dealing with servers that do not honor + // Connection: Close headers. + Psr7\copy_to_stream( + $source, + $sink, + (strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1 + ); + + $sink->seek(0); + $source->close(); + + return $sink; + } + + /** + * Create a resource and check to ensure it was created successfully + * + * @param callable $callback Callable that returns stream resource + * + * @return resource + * @throws \RuntimeException on error + */ + private function createResource(callable $callback) + { + $errors = null; + set_error_handler(function ($_, $msg, $file, $line) use (&$errors) { + $errors[] = [ + 'message' => $msg, + 'file' => $file, + 'line' => $line + ]; + return true; + }); + + $resource = $callback(); + restore_error_handler(); + + if (!$resource) { + $message = 'Error creating resource: '; + foreach ($errors as $err) { + foreach ($err as $key => $value) { + $message .= "[$key] $value" . PHP_EOL; + } + } + throw new \RuntimeException(trim($message)); + } + + return $resource; + } + + private function createStream(RequestInterface $request, array $options) + { + static $methods; + if (!$methods) { + $methods = array_flip(get_class_methods(__CLASS__)); + } + + // HTTP/1.1 streams using the PHP stream wrapper require a + // Connection: close header + if ($request->getProtocolVersion() == '1.1' + && !$request->hasHeader('Connection') + ) { + $request = $request->withHeader('Connection', 'close'); + } + + // Ensure SSL is verified by default + if (!isset($options['verify'])) { + $options['verify'] = true; + } + + $params = []; + $context = $this->getDefaultContext($request); + + if (isset($options['on_headers']) && !is_callable($options['on_headers'])) { + throw new \InvalidArgumentException('on_headers must be callable'); + } + + if (!empty($options)) { + foreach ($options as $key => $value) { + $method = "add_{$key}"; + if (isset($methods[$method])) { + $this->{$method}($request, $context, $value, $params); + } + } + } + + if (isset($options['stream_context'])) { + if (!is_array($options['stream_context'])) { + throw new \InvalidArgumentException('stream_context must be an array'); + } + $context = array_replace_recursive( + $context, + $options['stream_context'] + ); + } + + // Microsoft NTLM authentication only supported with curl handler + if (isset($options['auth']) + && is_array($options['auth']) + && isset($options['auth'][2]) + && 'ntlm' == $options['auth'][2] + ) { + throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler'); + } + + $uri = $this->resolveHost($request, $options); + + $context = $this->createResource( + function () use ($context, $params) { + return stream_context_create($context, $params); + } + ); + + return $this->createResource( + function () use ($uri, &$http_response_header, $context, $options) { + $resource = fopen((string) $uri, 'r', null, $context); + $this->lastHeaders = $http_response_header; + + if (isset($options['read_timeout'])) { + $readTimeout = $options['read_timeout']; + $sec = (int) $readTimeout; + $usec = ($readTimeout - $sec) * 100000; + stream_set_timeout($resource, $sec, $usec); + } + + return $resource; + } + ); + } + + private function resolveHost(RequestInterface $request, array $options) + { + $uri = $request->getUri(); + + if (isset($options['force_ip_resolve']) && !filter_var($uri->getHost(), FILTER_VALIDATE_IP)) { + if ('v4' === $options['force_ip_resolve']) { + $records = dns_get_record($uri->getHost(), DNS_A); + if (!isset($records[0]['ip'])) { + throw new ConnectException( + sprintf( + "Could not resolve IPv4 address for host '%s'", + $uri->getHost() + ), + $request + ); + } + $uri = $uri->withHost($records[0]['ip']); + } elseif ('v6' === $options['force_ip_resolve']) { + $records = dns_get_record($uri->getHost(), DNS_AAAA); + if (!isset($records[0]['ipv6'])) { + throw new ConnectException( + sprintf( + "Could not resolve IPv6 address for host '%s'", + $uri->getHost() + ), + $request + ); + } + $uri = $uri->withHost('[' . $records[0]['ipv6'] . ']'); + } + } + + return $uri; + } + + private function getDefaultContext(RequestInterface $request) + { + $headers = ''; + foreach ($request->getHeaders() as $name => $value) { + foreach ($value as $val) { + $headers .= "$name: $val\r\n"; + } + } + + $context = [ + 'http' => [ + 'method' => $request->getMethod(), + 'header' => $headers, + 'protocol_version' => $request->getProtocolVersion(), + 'ignore_errors' => true, + 'follow_location' => 0, + ], + ]; + + $body = (string) $request->getBody(); + + if (!empty($body)) { + $context['http']['content'] = $body; + // Prevent the HTTP handler from adding a Content-Type header. + if (!$request->hasHeader('Content-Type')) { + $context['http']['header'] .= "Content-Type:\r\n"; + } + } + + $context['http']['header'] = rtrim($context['http']['header']); + + return $context; + } + + private function add_proxy(RequestInterface $request, &$options, $value, &$params) + { + if (!is_array($value)) { + $options['http']['proxy'] = $value; + } else { + $scheme = $request->getUri()->getScheme(); + if (isset($value[$scheme])) { + if (!isset($value['no']) + || !\GuzzleHttp\is_host_in_noproxy( + $request->getUri()->getHost(), + $value['no'] + ) + ) { + $options['http']['proxy'] = $value[$scheme]; + } + } + } + } + + private function add_timeout(RequestInterface $request, &$options, $value, &$params) + { + if ($value > 0) { + $options['http']['timeout'] = $value; + } + } + + private function add_verify(RequestInterface $request, &$options, $value, &$params) + { + if ($value === true) { + // PHP 5.6 or greater will find the system cert by default. When + // < 5.6, use the Guzzle bundled cacert. + if (PHP_VERSION_ID < 50600) { + $options['ssl']['cafile'] = \GuzzleHttp\default_ca_bundle(); + } + } elseif (is_string($value)) { + $options['ssl']['cafile'] = $value; + if (!file_exists($value)) { + throw new \RuntimeException("SSL CA bundle not found: $value"); + } + } elseif ($value === false) { + $options['ssl']['verify_peer'] = false; + $options['ssl']['verify_peer_name'] = false; + return; + } else { + throw new \InvalidArgumentException('Invalid verify request option'); + } + + $options['ssl']['verify_peer'] = true; + $options['ssl']['verify_peer_name'] = true; + $options['ssl']['allow_self_signed'] = false; + } + + private function add_cert(RequestInterface $request, &$options, $value, &$params) + { + if (is_array($value)) { + $options['ssl']['passphrase'] = $value[1]; + $value = $value[0]; + } + + if (!file_exists($value)) { + throw new \RuntimeException("SSL certificate not found: {$value}"); + } + + $options['ssl']['local_cert'] = $value; + } + + private function add_progress(RequestInterface $request, &$options, $value, &$params) + { + $this->addNotification( + $params, + function ($code, $a, $b, $c, $transferred, $total) use ($value) { + if ($code == STREAM_NOTIFY_PROGRESS) { + $value($total, $transferred, null, null); + } + } + ); + } + + private function add_debug(RequestInterface $request, &$options, $value, &$params) + { + if ($value === false) { + return; + } + + static $map = [ + STREAM_NOTIFY_CONNECT => 'CONNECT', + STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED', + STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT', + STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS', + STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS', + STREAM_NOTIFY_REDIRECTED => 'REDIRECTED', + STREAM_NOTIFY_PROGRESS => 'PROGRESS', + STREAM_NOTIFY_FAILURE => 'FAILURE', + STREAM_NOTIFY_COMPLETED => 'COMPLETED', + STREAM_NOTIFY_RESOLVE => 'RESOLVE', + ]; + static $args = ['severity', 'message', 'message_code', + 'bytes_transferred', 'bytes_max']; + + $value = \GuzzleHttp\debug_resource($value); + $ident = $request->getMethod() . ' ' . $request->getUri()->withFragment(''); + $this->addNotification( + $params, + function () use ($ident, $value, $map, $args) { + $passed = func_get_args(); + $code = array_shift($passed); + fprintf($value, '<%s> [%s] ', $ident, $map[$code]); + foreach (array_filter($passed) as $i => $v) { + fwrite($value, $args[$i] . ': "' . $v . '" '); + } + fwrite($value, "\n"); + } + ); + } + + private function addNotification(array &$params, callable $notify) + { + // Wrap the existing function if needed. + if (!isset($params['notification'])) { + $params['notification'] = $notify; + } else { + $params['notification'] = $this->callArray([ + $params['notification'], + $notify + ]); + } + } + + private function callArray(array $functions) + { + return function () use ($functions) { + $args = func_get_args(); + foreach ($functions as $fn) { + call_user_func_array($fn, $args); + } + }; + } +} diff --git a/vendor/guzzlehttp/guzzle/src/HandlerStack.php b/vendor/guzzlehttp/guzzle/src/HandlerStack.php index 6a49cc0..a1a492b 100644 --- a/vendor/guzzlehttp/guzzle/src/HandlerStack.php +++ b/vendor/guzzlehttp/guzzle/src/HandlerStack.php @@ -1,277 +1,277 @@ -push(Middleware::httpErrors(), 'http_errors'); - $stack->push(Middleware::redirect(), 'allow_redirects'); - $stack->push(Middleware::cookies(), 'cookies'); - $stack->push(Middleware::prepareBody(), 'prepare_body'); - - return $stack; - } - - /** - * @param callable $handler Underlying HTTP handler. - */ - public function __construct(callable $handler = null) - { - $this->handler = $handler; - } - - /** - * Invokes the handler stack as a composed handler - * - * @param RequestInterface $request - * @param array $options - * - * @return ResponseInterface|PromiseInterface - */ - public function __invoke(RequestInterface $request, array $options) - { - $handler = $this->resolve(); - - return $handler($request, $options); - } - - /** - * Dumps a string representation of the stack. - * - * @return string - */ - public function __toString() - { - $depth = 0; - $stack = []; - if ($this->handler) { - $stack[] = "0) Handler: " . $this->debugCallable($this->handler); - } - - $result = ''; - foreach (array_reverse($this->stack) as $tuple) { - $depth++; - $str = "{$depth}) Name: '{$tuple[1]}', "; - $str .= "Function: " . $this->debugCallable($tuple[0]); - $result = "> {$str}\n{$result}"; - $stack[] = $str; - } - - foreach (array_keys($stack) as $k) { - $result .= "< {$stack[$k]}\n"; - } - - return $result; - } - - /** - * Set the HTTP handler that actually returns a promise. - * - * @param callable $handler Accepts a request and array of options and - * returns a Promise. - */ - public function setHandler(callable $handler) - { - $this->handler = $handler; - $this->cached = null; - } - - /** - * Returns true if the builder has a handler. - * - * @return bool - */ - public function hasHandler() - { - return (bool) $this->handler; - } - - /** - * Unshift a middleware to the bottom of the stack. - * - * @param callable $middleware Middleware function - * @param string $name Name to register for this middleware. - */ - public function unshift(callable $middleware, $name = null) - { - array_unshift($this->stack, [$middleware, $name]); - $this->cached = null; - } - - /** - * Push a middleware to the top of the stack. - * - * @param callable $middleware Middleware function - * @param string $name Name to register for this middleware. - */ - public function push(callable $middleware, $name = '') - { - $this->stack[] = [$middleware, $name]; - $this->cached = null; - } - - /** - * Add a middleware before another middleware by name. - * - * @param string $findName Middleware to find - * @param callable $middleware Middleware function - * @param string $withName Name to register for this middleware. - */ - public function before($findName, callable $middleware, $withName = '') - { - $this->splice($findName, $withName, $middleware, true); - } - - /** - * Add a middleware after another middleware by name. - * - * @param string $findName Middleware to find - * @param callable $middleware Middleware function - * @param string $withName Name to register for this middleware. - */ - public function after($findName, callable $middleware, $withName = '') - { - $this->splice($findName, $withName, $middleware, false); - } - - /** - * Remove a middleware by instance or name from the stack. - * - * @param callable|string $remove Middleware to remove by instance or name. - */ - public function remove($remove) - { - $this->cached = null; - $idx = is_callable($remove) ? 0 : 1; - $this->stack = array_values(array_filter( - $this->stack, - function ($tuple) use ($idx, $remove) { - return $tuple[$idx] !== $remove; - } - )); - } - - /** - * Compose the middleware and handler into a single callable function. - * - * @return callable - */ - public function resolve() - { - if (!$this->cached) { - if (!($prev = $this->handler)) { - throw new \LogicException('No handler has been specified'); - } - - foreach (array_reverse($this->stack) as $fn) { - $prev = $fn[0]($prev); - } - - $this->cached = $prev; - } - - return $this->cached; - } - - /** - * @param string $name - * @return int - */ - private function findByName($name) - { - foreach ($this->stack as $k => $v) { - if ($v[1] === $name) { - return $k; - } - } - - throw new \InvalidArgumentException("Middleware not found: $name"); - } - - /** - * Splices a function into the middleware list at a specific position. - * - * @param string $findName - * @param string $withName - * @param callable $middleware - * @param bool $before - */ - private function splice($findName, $withName, callable $middleware, $before) - { - $this->cached = null; - $idx = $this->findByName($findName); - $tuple = [$middleware, $withName]; - - if ($before) { - if ($idx === 0) { - array_unshift($this->stack, $tuple); - } else { - $replacement = [$tuple, $this->stack[$idx]]; - array_splice($this->stack, $idx, 1, $replacement); - } - } elseif ($idx === count($this->stack) - 1) { - $this->stack[] = $tuple; - } else { - $replacement = [$this->stack[$idx], $tuple]; - array_splice($this->stack, $idx, 1, $replacement); - } - } - - /** - * Provides a debug string for a given callable. - * - * @param array|callable $fn Function to write as a string. - * - * @return string - */ - private function debugCallable($fn) - { - if (is_string($fn)) { - return "callable({$fn})"; - } - - if (is_array($fn)) { - return is_string($fn[0]) - ? "callable({$fn[0]}::{$fn[1]})" - : "callable(['" . get_class($fn[0]) . "', '{$fn[1]}'])"; - } - - return 'callable(' . spl_object_hash($fn) . ')'; - } -} +push(Middleware::httpErrors(), 'http_errors'); + $stack->push(Middleware::redirect(), 'allow_redirects'); + $stack->push(Middleware::cookies(), 'cookies'); + $stack->push(Middleware::prepareBody(), 'prepare_body'); + + return $stack; + } + + /** + * @param callable $handler Underlying HTTP handler. + */ + public function __construct(callable $handler = null) + { + $this->handler = $handler; + } + + /** + * Invokes the handler stack as a composed handler + * + * @param RequestInterface $request + * @param array $options + * + * @return ResponseInterface|PromiseInterface + */ + public function __invoke(RequestInterface $request, array $options) + { + $handler = $this->resolve(); + + return $handler($request, $options); + } + + /** + * Dumps a string representation of the stack. + * + * @return string + */ + public function __toString() + { + $depth = 0; + $stack = []; + if ($this->handler) { + $stack[] = "0) Handler: " . $this->debugCallable($this->handler); + } + + $result = ''; + foreach (array_reverse($this->stack) as $tuple) { + $depth++; + $str = "{$depth}) Name: '{$tuple[1]}', "; + $str .= "Function: " . $this->debugCallable($tuple[0]); + $result = "> {$str}\n{$result}"; + $stack[] = $str; + } + + foreach (array_keys($stack) as $k) { + $result .= "< {$stack[$k]}\n"; + } + + return $result; + } + + /** + * Set the HTTP handler that actually returns a promise. + * + * @param callable $handler Accepts a request and array of options and + * returns a Promise. + */ + public function setHandler(callable $handler) + { + $this->handler = $handler; + $this->cached = null; + } + + /** + * Returns true if the builder has a handler. + * + * @return bool + */ + public function hasHandler() + { + return (bool) $this->handler; + } + + /** + * Unshift a middleware to the bottom of the stack. + * + * @param callable $middleware Middleware function + * @param string $name Name to register for this middleware. + */ + public function unshift(callable $middleware, $name = null) + { + array_unshift($this->stack, [$middleware, $name]); + $this->cached = null; + } + + /** + * Push a middleware to the top of the stack. + * + * @param callable $middleware Middleware function + * @param string $name Name to register for this middleware. + */ + public function push(callable $middleware, $name = '') + { + $this->stack[] = [$middleware, $name]; + $this->cached = null; + } + + /** + * Add a middleware before another middleware by name. + * + * @param string $findName Middleware to find + * @param callable $middleware Middleware function + * @param string $withName Name to register for this middleware. + */ + public function before($findName, callable $middleware, $withName = '') + { + $this->splice($findName, $withName, $middleware, true); + } + + /** + * Add a middleware after another middleware by name. + * + * @param string $findName Middleware to find + * @param callable $middleware Middleware function + * @param string $withName Name to register for this middleware. + */ + public function after($findName, callable $middleware, $withName = '') + { + $this->splice($findName, $withName, $middleware, false); + } + + /** + * Remove a middleware by instance or name from the stack. + * + * @param callable|string $remove Middleware to remove by instance or name. + */ + public function remove($remove) + { + $this->cached = null; + $idx = is_callable($remove) ? 0 : 1; + $this->stack = array_values(array_filter( + $this->stack, + function ($tuple) use ($idx, $remove) { + return $tuple[$idx] !== $remove; + } + )); + } + + /** + * Compose the middleware and handler into a single callable function. + * + * @return callable + */ + public function resolve() + { + if (!$this->cached) { + if (!($prev = $this->handler)) { + throw new \LogicException('No handler has been specified'); + } + + foreach (array_reverse($this->stack) as $fn) { + $prev = $fn[0]($prev); + } + + $this->cached = $prev; + } + + return $this->cached; + } + + /** + * @param string $name + * @return int + */ + private function findByName($name) + { + foreach ($this->stack as $k => $v) { + if ($v[1] === $name) { + return $k; + } + } + + throw new \InvalidArgumentException("Middleware not found: $name"); + } + + /** + * Splices a function into the middleware list at a specific position. + * + * @param string $findName + * @param string $withName + * @param callable $middleware + * @param bool $before + */ + private function splice($findName, $withName, callable $middleware, $before) + { + $this->cached = null; + $idx = $this->findByName($findName); + $tuple = [$middleware, $withName]; + + if ($before) { + if ($idx === 0) { + array_unshift($this->stack, $tuple); + } else { + $replacement = [$tuple, $this->stack[$idx]]; + array_splice($this->stack, $idx, 1, $replacement); + } + } elseif ($idx === count($this->stack) - 1) { + $this->stack[] = $tuple; + } else { + $replacement = [$this->stack[$idx], $tuple]; + array_splice($this->stack, $idx, 1, $replacement); + } + } + + /** + * Provides a debug string for a given callable. + * + * @param array|callable $fn Function to write as a string. + * + * @return string + */ + private function debugCallable($fn) + { + if (is_string($fn)) { + return "callable({$fn})"; + } + + if (is_array($fn)) { + return is_string($fn[0]) + ? "callable({$fn[0]}::{$fn[1]})" + : "callable(['" . get_class($fn[0]) . "', '{$fn[1]}'])"; + } + + return 'callable(' . spl_object_hash($fn) . ')'; + } +} diff --git a/vendor/guzzlehttp/guzzle/src/MessageFormatter.php b/vendor/guzzlehttp/guzzle/src/MessageFormatter.php index dc36bb5..03879bb 100644 --- a/vendor/guzzlehttp/guzzle/src/MessageFormatter.php +++ b/vendor/guzzlehttp/guzzle/src/MessageFormatter.php @@ -1,185 +1,185 @@ ->>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}"; - const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}'; - - /** @var string Template used to format log messages */ - private $template; - - /** - * @param string $template Log message template - */ - public function __construct($template = self::CLF) - { - $this->template = $template ?: self::CLF; - } - - /** - * Returns a formatted message string. - * - * @param RequestInterface $request Request that was sent - * @param ResponseInterface $response Response that was received - * @param \Exception $error Exception that was received - * - * @return string - */ - public function format( - RequestInterface $request, - ResponseInterface $response = null, - \Exception $error = null - ) { - $cache = []; - - return preg_replace_callback( - '/{\s*([A-Za-z_\-\.0-9]+)\s*}/', - function (array $matches) use ($request, $response, $error, &$cache) { - if (isset($cache[$matches[1]])) { - return $cache[$matches[1]]; - } - - $result = ''; - switch ($matches[1]) { - case 'request': - $result = Psr7\str($request); - break; - case 'response': - $result = $response ? Psr7\str($response) : ''; - break; - case 'req_headers': - $result = trim($request->getMethod() - . ' ' . $request->getRequestTarget()) - . ' HTTP/' . $request->getProtocolVersion() . "\r\n" - . $this->headers($request); - break; - case 'res_headers': - $result = $response ? - sprintf( - 'HTTP/%s %d %s', - $response->getProtocolVersion(), - $response->getStatusCode(), - $response->getReasonPhrase() - ) . "\r\n" . $this->headers($response) - : 'NULL'; - break; - case 'req_body': - $result = $request->getBody(); - break; - case 'res_body': - $result = $response ? $response->getBody() : 'NULL'; - break; - case 'ts': - case 'date_iso_8601': - $result = gmdate('c'); - break; - case 'date_common_log': - $result = date('d/M/Y:H:i:s O'); - break; - case 'method': - $result = $request->getMethod(); - break; - case 'version': - $result = $request->getProtocolVersion(); - break; - case 'uri': - case 'url': - $result = $request->getUri(); - break; - case 'target': - $result = $request->getRequestTarget(); - break; - case 'req_version': - $result = $request->getProtocolVersion(); - break; - case 'res_version': - $result = $response - ? $response->getProtocolVersion() - : 'NULL'; - break; - case 'host': - $result = $request->getHeaderLine('Host'); - break; - case 'hostname': - $result = gethostname(); - break; - case 'code': - $result = $response ? $response->getStatusCode() : 'NULL'; - break; - case 'phrase': - $result = $response ? $response->getReasonPhrase() : 'NULL'; - break; - case 'error': - $result = $error ? $error->getMessage() : 'NULL'; - break; - default: - // handle prefixed dynamic headers - if (strpos($matches[1], 'req_header_') === 0) { - $result = $request->getHeaderLine(substr($matches[1], 11)); - } elseif (strpos($matches[1], 'res_header_') === 0) { - $result = $response - ? $response->getHeaderLine(substr($matches[1], 11)) - : 'NULL'; - } - } - - $cache[$matches[1]] = $result; - return $result; - }, - $this->template - ); - } - - /** - * Get headers from message as string - * - * @return string - */ - private function headers(MessageInterface $message) - { - $result = ''; - foreach ($message->getHeaders() as $name => $values) { - $result .= $name . ': ' . implode(', ', $values) . "\r\n"; - } - - return trim($result); - } -} +>>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}"; + const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}'; + + /** @var string Template used to format log messages */ + private $template; + + /** + * @param string $template Log message template + */ + public function __construct($template = self::CLF) + { + $this->template = $template ?: self::CLF; + } + + /** + * Returns a formatted message string. + * + * @param RequestInterface $request Request that was sent + * @param ResponseInterface $response Response that was received + * @param \Exception $error Exception that was received + * + * @return string + */ + public function format( + RequestInterface $request, + ResponseInterface $response = null, + \Exception $error = null + ) { + $cache = []; + + return preg_replace_callback( + '/{\s*([A-Za-z_\-\.0-9]+)\s*}/', + function (array $matches) use ($request, $response, $error, &$cache) { + if (isset($cache[$matches[1]])) { + return $cache[$matches[1]]; + } + + $result = ''; + switch ($matches[1]) { + case 'request': + $result = Psr7\str($request); + break; + case 'response': + $result = $response ? Psr7\str($response) : ''; + break; + case 'req_headers': + $result = trim($request->getMethod() + . ' ' . $request->getRequestTarget()) + . ' HTTP/' . $request->getProtocolVersion() . "\r\n" + . $this->headers($request); + break; + case 'res_headers': + $result = $response ? + sprintf( + 'HTTP/%s %d %s', + $response->getProtocolVersion(), + $response->getStatusCode(), + $response->getReasonPhrase() + ) . "\r\n" . $this->headers($response) + : 'NULL'; + break; + case 'req_body': + $result = $request->getBody(); + break; + case 'res_body': + $result = $response ? $response->getBody() : 'NULL'; + break; + case 'ts': + case 'date_iso_8601': + $result = gmdate('c'); + break; + case 'date_common_log': + $result = date('d/M/Y:H:i:s O'); + break; + case 'method': + $result = $request->getMethod(); + break; + case 'version': + $result = $request->getProtocolVersion(); + break; + case 'uri': + case 'url': + $result = $request->getUri(); + break; + case 'target': + $result = $request->getRequestTarget(); + break; + case 'req_version': + $result = $request->getProtocolVersion(); + break; + case 'res_version': + $result = $response + ? $response->getProtocolVersion() + : 'NULL'; + break; + case 'host': + $result = $request->getHeaderLine('Host'); + break; + case 'hostname': + $result = gethostname(); + break; + case 'code': + $result = $response ? $response->getStatusCode() : 'NULL'; + break; + case 'phrase': + $result = $response ? $response->getReasonPhrase() : 'NULL'; + break; + case 'error': + $result = $error ? $error->getMessage() : 'NULL'; + break; + default: + // handle prefixed dynamic headers + if (strpos($matches[1], 'req_header_') === 0) { + $result = $request->getHeaderLine(substr($matches[1], 11)); + } elseif (strpos($matches[1], 'res_header_') === 0) { + $result = $response + ? $response->getHeaderLine(substr($matches[1], 11)) + : 'NULL'; + } + } + + $cache[$matches[1]] = $result; + return $result; + }, + $this->template + ); + } + + /** + * Get headers from message as string + * + * @return string + */ + private function headers(MessageInterface $message) + { + $result = ''; + foreach ($message->getHeaders() as $name => $values) { + $result .= $name . ': ' . implode(', ', $values) . "\r\n"; + } + + return trim($result); + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Middleware.php b/vendor/guzzlehttp/guzzle/src/Middleware.php index bffc197..98f7f48 100644 --- a/vendor/guzzlehttp/guzzle/src/Middleware.php +++ b/vendor/guzzlehttp/guzzle/src/Middleware.php @@ -1,254 +1,254 @@ -withCookieHeader($request); - return $handler($request, $options) - ->then( - function ($response) use ($cookieJar, $request) { - $cookieJar->extractCookies($request, $response); - return $response; - } - ); - }; - }; - } - - /** - * Middleware that throws exceptions for 4xx or 5xx responses when the - * "http_error" request option is set to true. - * - * @return callable Returns a function that accepts the next handler. - */ - public static function httpErrors() - { - return function (callable $handler) { - return function ($request, array $options) use ($handler) { - if (empty($options['http_errors'])) { - return $handler($request, $options); - } - return $handler($request, $options)->then( - function (ResponseInterface $response) use ($request) { - $code = $response->getStatusCode(); - if ($code < 400) { - return $response; - } - throw RequestException::create($request, $response); - } - ); - }; - }; - } - - /** - * Middleware that pushes history data to an ArrayAccess container. - * - * @param array|\ArrayAccess $container Container to hold the history (by reference). - * - * @return callable Returns a function that accepts the next handler. - * @throws \InvalidArgumentException if container is not an array or ArrayAccess. - */ - public static function history(&$container) - { - if (!is_array($container) && !$container instanceof \ArrayAccess) { - throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess'); - } - - return function (callable $handler) use (&$container) { - return function ($request, array $options) use ($handler, &$container) { - return $handler($request, $options)->then( - function ($value) use ($request, &$container, $options) { - $container[] = [ - 'request' => $request, - 'response' => $value, - 'error' => null, - 'options' => $options - ]; - return $value; - }, - function ($reason) use ($request, &$container, $options) { - $container[] = [ - 'request' => $request, - 'response' => null, - 'error' => $reason, - 'options' => $options - ]; - return \GuzzleHttp\Promise\rejection_for($reason); - } - ); - }; - }; - } - - /** - * Middleware that invokes a callback before and after sending a request. - * - * The provided listener cannot modify or alter the response. It simply - * "taps" into the chain to be notified before returning the promise. The - * before listener accepts a request and options array, and the after - * listener accepts a request, options array, and response promise. - * - * @param callable $before Function to invoke before forwarding the request. - * @param callable $after Function invoked after forwarding. - * - * @return callable Returns a function that accepts the next handler. - */ - public static function tap(callable $before = null, callable $after = null) - { - return function (callable $handler) use ($before, $after) { - return function ($request, array $options) use ($handler, $before, $after) { - if ($before) { - $before($request, $options); - } - $response = $handler($request, $options); - if ($after) { - $after($request, $options, $response); - } - return $response; - }; - }; - } - - /** - * Middleware that handles request redirects. - * - * @return callable Returns a function that accepts the next handler. - */ - public static function redirect() - { - return function (callable $handler) { - return new RedirectMiddleware($handler); - }; - } - - /** - * Middleware that retries requests based on the boolean result of - * invoking the provided "decider" function. - * - * If no delay function is provided, a simple implementation of exponential - * backoff will be utilized. - * - * @param callable $decider Function that accepts the number of retries, - * a request, [response], and [exception] and - * returns true if the request is to be retried. - * @param callable $delay Function that accepts the number of retries and - * returns the number of milliseconds to delay. - * - * @return callable Returns a function that accepts the next handler. - */ - public static function retry(callable $decider, callable $delay = null) - { - return function (callable $handler) use ($decider, $delay) { - return new RetryMiddleware($decider, $handler, $delay); - }; - } - - /** - * Middleware that logs requests, responses, and errors using a message - * formatter. - * - * @param LoggerInterface $logger Logs messages. - * @param MessageFormatter $formatter Formatter used to create message strings. - * @param string $logLevel Level at which to log requests. - * - * @return callable Returns a function that accepts the next handler. - */ - public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = 'info' /* \Psr\Log\LogLevel::INFO */) - { - return function (callable $handler) use ($logger, $formatter, $logLevel) { - return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) { - return $handler($request, $options)->then( - function ($response) use ($logger, $request, $formatter, $logLevel) { - $message = $formatter->format($request, $response); - $logger->log($logLevel, $message); - return $response; - }, - function ($reason) use ($logger, $request, $formatter) { - $response = $reason instanceof RequestException - ? $reason->getResponse() - : null; - $message = $formatter->format($request, $response, $reason); - $logger->notice($message); - return \GuzzleHttp\Promise\rejection_for($reason); - } - ); - }; - }; - } - - /** - * This middleware adds a default content-type if possible, a default - * content-length or transfer-encoding header, and the expect header. - * - * @return callable - */ - public static function prepareBody() - { - return function (callable $handler) { - return new PrepareBodyMiddleware($handler); - }; - } - - /** - * Middleware that applies a map function to the request before passing to - * the next handler. - * - * @param callable $fn Function that accepts a RequestInterface and returns - * a RequestInterface. - * @return callable - */ - public static function mapRequest(callable $fn) - { - return function (callable $handler) use ($fn) { - return function ($request, array $options) use ($handler, $fn) { - return $handler($fn($request), $options); - }; - }; - } - - /** - * Middleware that applies a map function to the resolved promise's - * response. - * - * @param callable $fn Function that accepts a ResponseInterface and - * returns a ResponseInterface. - * @return callable - */ - public static function mapResponse(callable $fn) - { - return function (callable $handler) use ($fn) { - return function ($request, array $options) use ($handler, $fn) { - return $handler($request, $options)->then($fn); - }; - }; - } -} +withCookieHeader($request); + return $handler($request, $options) + ->then( + function ($response) use ($cookieJar, $request) { + $cookieJar->extractCookies($request, $response); + return $response; + } + ); + }; + }; + } + + /** + * Middleware that throws exceptions for 4xx or 5xx responses when the + * "http_error" request option is set to true. + * + * @return callable Returns a function that accepts the next handler. + */ + public static function httpErrors() + { + return function (callable $handler) { + return function ($request, array $options) use ($handler) { + if (empty($options['http_errors'])) { + return $handler($request, $options); + } + return $handler($request, $options)->then( + function (ResponseInterface $response) use ($request) { + $code = $response->getStatusCode(); + if ($code < 400) { + return $response; + } + throw RequestException::create($request, $response); + } + ); + }; + }; + } + + /** + * Middleware that pushes history data to an ArrayAccess container. + * + * @param array|\ArrayAccess $container Container to hold the history (by reference). + * + * @return callable Returns a function that accepts the next handler. + * @throws \InvalidArgumentException if container is not an array or ArrayAccess. + */ + public static function history(&$container) + { + if (!is_array($container) && !$container instanceof \ArrayAccess) { + throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess'); + } + + return function (callable $handler) use (&$container) { + return function ($request, array $options) use ($handler, &$container) { + return $handler($request, $options)->then( + function ($value) use ($request, &$container, $options) { + $container[] = [ + 'request' => $request, + 'response' => $value, + 'error' => null, + 'options' => $options + ]; + return $value; + }, + function ($reason) use ($request, &$container, $options) { + $container[] = [ + 'request' => $request, + 'response' => null, + 'error' => $reason, + 'options' => $options + ]; + return \GuzzleHttp\Promise\rejection_for($reason); + } + ); + }; + }; + } + + /** + * Middleware that invokes a callback before and after sending a request. + * + * The provided listener cannot modify or alter the response. It simply + * "taps" into the chain to be notified before returning the promise. The + * before listener accepts a request and options array, and the after + * listener accepts a request, options array, and response promise. + * + * @param callable $before Function to invoke before forwarding the request. + * @param callable $after Function invoked after forwarding. + * + * @return callable Returns a function that accepts the next handler. + */ + public static function tap(callable $before = null, callable $after = null) + { + return function (callable $handler) use ($before, $after) { + return function ($request, array $options) use ($handler, $before, $after) { + if ($before) { + $before($request, $options); + } + $response = $handler($request, $options); + if ($after) { + $after($request, $options, $response); + } + return $response; + }; + }; + } + + /** + * Middleware that handles request redirects. + * + * @return callable Returns a function that accepts the next handler. + */ + public static function redirect() + { + return function (callable $handler) { + return new RedirectMiddleware($handler); + }; + } + + /** + * Middleware that retries requests based on the boolean result of + * invoking the provided "decider" function. + * + * If no delay function is provided, a simple implementation of exponential + * backoff will be utilized. + * + * @param callable $decider Function that accepts the number of retries, + * a request, [response], and [exception] and + * returns true if the request is to be retried. + * @param callable $delay Function that accepts the number of retries and + * returns the number of milliseconds to delay. + * + * @return callable Returns a function that accepts the next handler. + */ + public static function retry(callable $decider, callable $delay = null) + { + return function (callable $handler) use ($decider, $delay) { + return new RetryMiddleware($decider, $handler, $delay); + }; + } + + /** + * Middleware that logs requests, responses, and errors using a message + * formatter. + * + * @param LoggerInterface $logger Logs messages. + * @param MessageFormatter $formatter Formatter used to create message strings. + * @param string $logLevel Level at which to log requests. + * + * @return callable Returns a function that accepts the next handler. + */ + public static function log(LoggerInterface $logger, MessageFormatter $formatter, $logLevel = 'info' /* \Psr\Log\LogLevel::INFO */) + { + return function (callable $handler) use ($logger, $formatter, $logLevel) { + return function ($request, array $options) use ($handler, $logger, $formatter, $logLevel) { + return $handler($request, $options)->then( + function ($response) use ($logger, $request, $formatter, $logLevel) { + $message = $formatter->format($request, $response); + $logger->log($logLevel, $message); + return $response; + }, + function ($reason) use ($logger, $request, $formatter) { + $response = $reason instanceof RequestException + ? $reason->getResponse() + : null; + $message = $formatter->format($request, $response, $reason); + $logger->notice($message); + return \GuzzleHttp\Promise\rejection_for($reason); + } + ); + }; + }; + } + + /** + * This middleware adds a default content-type if possible, a default + * content-length or transfer-encoding header, and the expect header. + * + * @return callable + */ + public static function prepareBody() + { + return function (callable $handler) { + return new PrepareBodyMiddleware($handler); + }; + } + + /** + * Middleware that applies a map function to the request before passing to + * the next handler. + * + * @param callable $fn Function that accepts a RequestInterface and returns + * a RequestInterface. + * @return callable + */ + public static function mapRequest(callable $fn) + { + return function (callable $handler) use ($fn) { + return function ($request, array $options) use ($handler, $fn) { + return $handler($fn($request), $options); + }; + }; + } + + /** + * Middleware that applies a map function to the resolved promise's + * response. + * + * @param callable $fn Function that accepts a ResponseInterface and + * returns a ResponseInterface. + * @return callable + */ + public static function mapResponse(callable $fn) + { + return function (callable $handler) use ($fn) { + return function ($request, array $options) use ($handler, $fn) { + return $handler($request, $options)->then($fn); + }; + }; + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Pool.php b/vendor/guzzlehttp/guzzle/src/Pool.php index 5838db4..e185fdb 100644 --- a/vendor/guzzlehttp/guzzle/src/Pool.php +++ b/vendor/guzzlehttp/guzzle/src/Pool.php @@ -1,134 +1,134 @@ - $rfn) { - if ($rfn instanceof RequestInterface) { - yield $key => $client->sendAsync($rfn, $opts); - } elseif (is_callable($rfn)) { - yield $key => $rfn($opts); - } else { - throw new \InvalidArgumentException('Each value yielded by ' - . 'the iterator must be a Psr7\Http\Message\RequestInterface ' - . 'or a callable that returns a promise that fulfills ' - . 'with a Psr7\Message\Http\ResponseInterface object.'); - } - } - }; - - $this->each = new EachPromise($requests(), $config); - } - - /** - * Get promise - * - * @return PromiseInterface - */ - public function promise() - { - return $this->each->promise(); - } - - /** - * Sends multiple requests concurrently and returns an array of responses - * and exceptions that uses the same ordering as the provided requests. - * - * IMPORTANT: This method keeps every request and response in memory, and - * as such, is NOT recommended when sending a large number or an - * indeterminate number of requests concurrently. - * - * @param ClientInterface $client Client used to send the requests - * @param array|\Iterator $requests Requests to send concurrently. - * @param array $options Passes through the options available in - * {@see GuzzleHttp\Pool::__construct} - * - * @return array Returns an array containing the response or an exception - * in the same order that the requests were sent. - * @throws \InvalidArgumentException if the event format is incorrect. - */ - public static function batch( - ClientInterface $client, - $requests, - array $options = [] - ) { - $res = []; - self::cmpCallback($options, 'fulfilled', $res); - self::cmpCallback($options, 'rejected', $res); - $pool = new static($client, $requests, $options); - $pool->promise()->wait(); - ksort($res); - - return $res; - } - - /** - * Execute callback(s) - * - * @return void - */ - private static function cmpCallback(array &$options, $name, array &$results) - { - if (!isset($options[$name])) { - $options[$name] = function ($v, $k) use (&$results) { - $results[$k] = $v; - }; - } else { - $currentFn = $options[$name]; - $options[$name] = function ($v, $k) use (&$results, $currentFn) { - $currentFn($v, $k); - $results[$k] = $v; - }; - } - } -} + $rfn) { + if ($rfn instanceof RequestInterface) { + yield $key => $client->sendAsync($rfn, $opts); + } elseif (is_callable($rfn)) { + yield $key => $rfn($opts); + } else { + throw new \InvalidArgumentException('Each value yielded by ' + . 'the iterator must be a Psr7\Http\Message\RequestInterface ' + . 'or a callable that returns a promise that fulfills ' + . 'with a Psr7\Message\Http\ResponseInterface object.'); + } + } + }; + + $this->each = new EachPromise($requests(), $config); + } + + /** + * Get promise + * + * @return PromiseInterface + */ + public function promise() + { + return $this->each->promise(); + } + + /** + * Sends multiple requests concurrently and returns an array of responses + * and exceptions that uses the same ordering as the provided requests. + * + * IMPORTANT: This method keeps every request and response in memory, and + * as such, is NOT recommended when sending a large number or an + * indeterminate number of requests concurrently. + * + * @param ClientInterface $client Client used to send the requests + * @param array|\Iterator $requests Requests to send concurrently. + * @param array $options Passes through the options available in + * {@see GuzzleHttp\Pool::__construct} + * + * @return array Returns an array containing the response or an exception + * in the same order that the requests were sent. + * @throws \InvalidArgumentException if the event format is incorrect. + */ + public static function batch( + ClientInterface $client, + $requests, + array $options = [] + ) { + $res = []; + self::cmpCallback($options, 'fulfilled', $res); + self::cmpCallback($options, 'rejected', $res); + $pool = new static($client, $requests, $options); + $pool->promise()->wait(); + ksort($res); + + return $res; + } + + /** + * Execute callback(s) + * + * @return void + */ + private static function cmpCallback(array &$options, $name, array &$results) + { + if (!isset($options[$name])) { + $options[$name] = function ($v, $k) use (&$results) { + $results[$k] = $v; + }; + } else { + $currentFn = $options[$name]; + $options[$name] = function ($v, $k) use (&$results, $currentFn) { + $currentFn($v, $k); + $results[$k] = $v; + }; + } + } +} diff --git a/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php b/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php index 568a1e9..28b50ca 100644 --- a/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php +++ b/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php @@ -1,111 +1,111 @@ -nextHandler = $nextHandler; - } - - /** - * @param RequestInterface $request - * @param array $options - * - * @return PromiseInterface - */ - public function __invoke(RequestInterface $request, array $options) - { - $fn = $this->nextHandler; - - // Don't do anything if the request has no body. - if ($request->getBody()->getSize() === 0) { - return $fn($request, $options); - } - - $modify = []; - - // Add a default content-type if possible. - if (!$request->hasHeader('Content-Type')) { - if ($uri = $request->getBody()->getMetadata('uri')) { - if ($type = Psr7\mimetype_from_filename($uri)) { - $modify['set_headers']['Content-Type'] = $type; - } - } - } - - // Add a default content-length or transfer-encoding header. - if (!$request->hasHeader('Content-Length') - && !$request->hasHeader('Transfer-Encoding') - ) { - $size = $request->getBody()->getSize(); - if ($size !== null) { - $modify['set_headers']['Content-Length'] = $size; - } else { - $modify['set_headers']['Transfer-Encoding'] = 'chunked'; - } - } - - // Add the expect header if needed. - $this->addExpectHeader($request, $options, $modify); - - return $fn(Psr7\modify_request($request, $modify), $options); - } - - /** - * Add expect header - * - * @return void - */ - private function addExpectHeader( - RequestInterface $request, - array $options, - array &$modify - ) { - // Determine if the Expect header should be used - if ($request->hasHeader('Expect')) { - return; - } - - $expect = isset($options['expect']) ? $options['expect'] : null; - - // Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0 - if ($expect === false || $request->getProtocolVersion() < 1.1) { - return; - } - - // The expect header is unconditionally enabled - if ($expect === true) { - $modify['set_headers']['Expect'] = '100-Continue'; - return; - } - - // By default, send the expect header when the payload is > 1mb - if ($expect === null) { - $expect = 1048576; - } - - // Always add if the body cannot be rewound, the size cannot be - // determined, or the size is greater than the cutoff threshold - $body = $request->getBody(); - $size = $body->getSize(); - - if ($size === null || $size >= (int) $expect || !$body->isSeekable()) { - $modify['set_headers']['Expect'] = '100-Continue'; - } - } -} +nextHandler = $nextHandler; + } + + /** + * @param RequestInterface $request + * @param array $options + * + * @return PromiseInterface + */ + public function __invoke(RequestInterface $request, array $options) + { + $fn = $this->nextHandler; + + // Don't do anything if the request has no body. + if ($request->getBody()->getSize() === 0) { + return $fn($request, $options); + } + + $modify = []; + + // Add a default content-type if possible. + if (!$request->hasHeader('Content-Type')) { + if ($uri = $request->getBody()->getMetadata('uri')) { + if ($type = Psr7\mimetype_from_filename($uri)) { + $modify['set_headers']['Content-Type'] = $type; + } + } + } + + // Add a default content-length or transfer-encoding header. + if (!$request->hasHeader('Content-Length') + && !$request->hasHeader('Transfer-Encoding') + ) { + $size = $request->getBody()->getSize(); + if ($size !== null) { + $modify['set_headers']['Content-Length'] = $size; + } else { + $modify['set_headers']['Transfer-Encoding'] = 'chunked'; + } + } + + // Add the expect header if needed. + $this->addExpectHeader($request, $options, $modify); + + return $fn(Psr7\modify_request($request, $modify), $options); + } + + /** + * Add expect header + * + * @return void + */ + private function addExpectHeader( + RequestInterface $request, + array $options, + array &$modify + ) { + // Determine if the Expect header should be used + if ($request->hasHeader('Expect')) { + return; + } + + $expect = isset($options['expect']) ? $options['expect'] : null; + + // Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0 + if ($expect === false || $request->getProtocolVersion() < 1.1) { + return; + } + + // The expect header is unconditionally enabled + if ($expect === true) { + $modify['set_headers']['Expect'] = '100-Continue'; + return; + } + + // By default, send the expect header when the payload is > 1mb + if ($expect === null) { + $expect = 1048576; + } + + // Always add if the body cannot be rewound, the size cannot be + // determined, or the size is greater than the cutoff threshold + $body = $request->getBody(); + $size = $body->getSize(); + + if ($size === null || $size >= (int) $expect || !$body->isSeekable()) { + $modify['set_headers']['Expect'] = '100-Continue'; + } + } +} diff --git a/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php b/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php index e4644b7..0464b56 100644 --- a/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php +++ b/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php @@ -1,255 +1,264 @@ - 5, - 'protocols' => ['http', 'https'], - 'strict' => false, - 'referer' => false, - 'track_redirects' => false, - ]; - - /** @var callable */ - private $nextHandler; - - /** - * @param callable $nextHandler Next handler to invoke. - */ - public function __construct(callable $nextHandler) - { - $this->nextHandler = $nextHandler; - } - - /** - * @param RequestInterface $request - * @param array $options - * - * @return PromiseInterface - */ - public function __invoke(RequestInterface $request, array $options) - { - $fn = $this->nextHandler; - - if (empty($options['allow_redirects'])) { - return $fn($request, $options); - } - - if ($options['allow_redirects'] === true) { - $options['allow_redirects'] = self::$defaultSettings; - } elseif (!is_array($options['allow_redirects'])) { - throw new \InvalidArgumentException('allow_redirects must be true, false, or array'); - } else { - // Merge the default settings with the provided settings - $options['allow_redirects'] += self::$defaultSettings; - } - - if (empty($options['allow_redirects']['max'])) { - return $fn($request, $options); - } - - return $fn($request, $options) - ->then(function (ResponseInterface $response) use ($request, $options) { - return $this->checkRedirect($request, $options, $response); - }); - } - - /** - * @param RequestInterface $request - * @param array $options - * @param ResponseInterface $response - * - * @return ResponseInterface|PromiseInterface - */ - public function checkRedirect( - RequestInterface $request, - array $options, - ResponseInterface $response - ) { - if (substr($response->getStatusCode(), 0, 1) != '3' - || !$response->hasHeader('Location') - ) { - return $response; - } - - $this->guardMax($request, $options); - $nextRequest = $this->modifyRequest($request, $options, $response); - - if (isset($options['allow_redirects']['on_redirect'])) { - call_user_func( - $options['allow_redirects']['on_redirect'], - $request, - $response, - $nextRequest->getUri() - ); - } - - /** @var PromiseInterface|ResponseInterface $promise */ - $promise = $this($nextRequest, $options); - - // Add headers to be able to track history of redirects. - if (!empty($options['allow_redirects']['track_redirects'])) { - return $this->withTracking( - $promise, - (string) $nextRequest->getUri(), - $response->getStatusCode() - ); - } - - return $promise; - } - - /** - * Enable tracking on promise. - * - * @return PromiseInterface - */ - private function withTracking(PromiseInterface $promise, $uri, $statusCode) - { - return $promise->then( - function (ResponseInterface $response) use ($uri, $statusCode) { - // Note that we are pushing to the front of the list as this - // would be an earlier response than what is currently present - // in the history header. - $historyHeader = $response->getHeader(self::HISTORY_HEADER); - $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER); - array_unshift($historyHeader, $uri); - array_unshift($statusHeader, $statusCode); - return $response->withHeader(self::HISTORY_HEADER, $historyHeader) - ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader); - } - ); - } - - /** - * Check for too many redirects - * - * @return void - * - * @throws TooManyRedirectsException Too many redirects. - */ - private function guardMax(RequestInterface $request, array &$options) - { - $current = isset($options['__redirect_count']) - ? $options['__redirect_count'] - : 0; - $options['__redirect_count'] = $current + 1; - $max = $options['allow_redirects']['max']; - - if ($options['__redirect_count'] > $max) { - throw new TooManyRedirectsException( - "Will not follow more than {$max} redirects", - $request - ); - } - } - - /** - * @param RequestInterface $request - * @param array $options - * @param ResponseInterface $response - * - * @return RequestInterface - */ - public function modifyRequest( - RequestInterface $request, - array $options, - ResponseInterface $response - ) { - // Request modifications to apply. - $modify = []; - $protocols = $options['allow_redirects']['protocols']; - - // Use a GET request if this is an entity enclosing request and we are - // not forcing RFC compliance, but rather emulating what all browsers - // would do. - $statusCode = $response->getStatusCode(); - if ($statusCode == 303 || - ($statusCode <= 302 && !$options['allow_redirects']['strict']) - ) { - $modify['method'] = 'GET'; - $modify['body'] = ''; - } - - $uri = $this->redirectUri($request, $response, $protocols); - if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) { - $idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion']; - $uri = Utils::idnUriConvert($uri, $idnOptions); - } - - $modify['uri'] = $uri; - Psr7\rewind_body($request); - - // Add the Referer header if it is told to do so and only - // add the header if we are not redirecting from https to http. - if ($options['allow_redirects']['referer'] - && $modify['uri']->getScheme() === $request->getUri()->getScheme() - ) { - $uri = $request->getUri()->withUserInfo(''); - $modify['set_headers']['Referer'] = (string) $uri; - } else { - $modify['remove_headers'][] = 'Referer'; - } - - // Remove Authorization header if host is different. - if ($request->getUri()->getHost() !== $modify['uri']->getHost()) { - $modify['remove_headers'][] = 'Authorization'; - } - - return Psr7\modify_request($request, $modify); - } - - /** - * Set the appropriate URL on the request based on the location header - * - * @param RequestInterface $request - * @param ResponseInterface $response - * @param array $protocols - * - * @return UriInterface - */ - private function redirectUri( - RequestInterface $request, - ResponseInterface $response, - array $protocols - ) { - $location = Psr7\UriResolver::resolve( - $request->getUri(), - new Psr7\Uri($response->getHeaderLine('Location')) - ); - - // Ensure that the redirect URI is allowed based on the protocols. - if (!in_array($location->getScheme(), $protocols)) { - throw new BadResponseException( - sprintf( - 'Redirect URI, %s, does not use one of the allowed redirect protocols: %s', - $location, - implode(', ', $protocols) - ), - $request, - $response - ); - } - - return $location; - } -} + 5, + 'protocols' => ['http', 'https'], + 'strict' => false, + 'referer' => false, + 'track_redirects' => false, + ]; + + /** @var callable */ + private $nextHandler; + + /** + * @param callable $nextHandler Next handler to invoke. + */ + public function __construct(callable $nextHandler) + { + $this->nextHandler = $nextHandler; + } + + /** + * @param RequestInterface $request + * @param array $options + * + * @return PromiseInterface + */ + public function __invoke(RequestInterface $request, array $options) + { + $fn = $this->nextHandler; + + if (empty($options['allow_redirects'])) { + return $fn($request, $options); + } + + if ($options['allow_redirects'] === true) { + $options['allow_redirects'] = self::$defaultSettings; + } elseif (!is_array($options['allow_redirects'])) { + throw new \InvalidArgumentException('allow_redirects must be true, false, or array'); + } else { + // Merge the default settings with the provided settings + $options['allow_redirects'] += self::$defaultSettings; + } + + if (empty($options['allow_redirects']['max'])) { + return $fn($request, $options); + } + + return $fn($request, $options) + ->then(function (ResponseInterface $response) use ($request, $options) { + return $this->checkRedirect($request, $options, $response); + }); + } + + /** + * @param RequestInterface $request + * @param array $options + * @param ResponseInterface $response + * + * @return ResponseInterface|PromiseInterface + */ + public function checkRedirect( + RequestInterface $request, + array $options, + ResponseInterface $response + ) { + if (substr($response->getStatusCode(), 0, 1) != '3' + || !$response->hasHeader('Location') + ) { + return $response; + } + + $this->guardMax($request, $options); + $nextRequest = $this->modifyRequest($request, $options, $response); + + // If authorization is handled by curl, unset it if URI is cross-origin. + if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $nextRequest->getUri()) && defined('\CURLOPT_HTTPAUTH')) { + unset( + $options['curl'][\CURLOPT_HTTPAUTH], + $options['curl'][\CURLOPT_USERPWD] + ); + } + + if (isset($options['allow_redirects']['on_redirect'])) { + call_user_func( + $options['allow_redirects']['on_redirect'], + $request, + $response, + $nextRequest->getUri() + ); + } + + /** @var PromiseInterface|ResponseInterface $promise */ + $promise = $this($nextRequest, $options); + + // Add headers to be able to track history of redirects. + if (!empty($options['allow_redirects']['track_redirects'])) { + return $this->withTracking( + $promise, + (string) $nextRequest->getUri(), + $response->getStatusCode() + ); + } + + return $promise; + } + + /** + * Enable tracking on promise. + * + * @return PromiseInterface + */ + private function withTracking(PromiseInterface $promise, $uri, $statusCode) + { + return $promise->then( + function (ResponseInterface $response) use ($uri, $statusCode) { + // Note that we are pushing to the front of the list as this + // would be an earlier response than what is currently present + // in the history header. + $historyHeader = $response->getHeader(self::HISTORY_HEADER); + $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER); + array_unshift($historyHeader, $uri); + array_unshift($statusHeader, $statusCode); + return $response->withHeader(self::HISTORY_HEADER, $historyHeader) + ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader); + } + ); + } + + /** + * Check for too many redirects. + * + * @return void + * + * @throws TooManyRedirectsException Too many redirects. + */ + private function guardMax(RequestInterface $request, array &$options) + { + $current = isset($options['__redirect_count']) + ? $options['__redirect_count'] + : 0; + $options['__redirect_count'] = $current + 1; + $max = $options['allow_redirects']['max']; + + if ($options['__redirect_count'] > $max) { + throw new TooManyRedirectsException( + "Will not follow more than {$max} redirects", + $request + ); + } + } + + /** + * @param RequestInterface $request + * @param array $options + * @param ResponseInterface $response + * + * @return RequestInterface + */ + public function modifyRequest( + RequestInterface $request, + array $options, + ResponseInterface $response + ) { + // Request modifications to apply. + $modify = []; + $protocols = $options['allow_redirects']['protocols']; + + // Use a GET request if this is an entity enclosing request and we are + // not forcing RFC compliance, but rather emulating what all browsers + // would do. + $statusCode = $response->getStatusCode(); + if ($statusCode == 303 || + ($statusCode <= 302 && !$options['allow_redirects']['strict']) + ) { + $modify['method'] = 'GET'; + $modify['body'] = ''; + } + + $uri = self::redirectUri($request, $response, $protocols); + if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) { + $idnOptions = ($options['idn_conversion'] === true) ? IDNA_DEFAULT : $options['idn_conversion']; + $uri = Utils::idnUriConvert($uri, $idnOptions); + } + + $modify['uri'] = $uri; + Psr7\rewind_body($request); + + // Add the Referer header if it is told to do so and only + // add the header if we are not redirecting from https to http. + if ($options['allow_redirects']['referer'] + && $modify['uri']->getScheme() === $request->getUri()->getScheme() + ) { + $uri = $request->getUri()->withUserInfo(''); + $modify['set_headers']['Referer'] = (string) $uri; + } else { + $modify['remove_headers'][] = 'Referer'; + } + + // Remove Authorization and Cookie headers if URI is cross-origin. + if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $modify['uri'])) { + $modify['remove_headers'][] = 'Authorization'; + $modify['remove_headers'][] = 'Cookie'; + } + + return Psr7\modify_request($request, $modify); + } + + /** + * Set the appropriate URL on the request based on the location header. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @param array $protocols + * + * @return UriInterface + */ + private static function redirectUri( + RequestInterface $request, + ResponseInterface $response, + array $protocols + ) { + $location = Psr7\UriResolver::resolve( + $request->getUri(), + new Psr7\Uri($response->getHeaderLine('Location')) + ); + + // Ensure that the redirect URI is allowed based on the protocols. + if (!in_array($location->getScheme(), $protocols)) { + throw new BadResponseException( + sprintf( + 'Redirect URI, %s, does not use one of the allowed redirect protocols: %s', + $location, + implode(', ', $protocols) + ), + $request, + $response + ); + } + + return $location; + } +} diff --git a/vendor/guzzlehttp/guzzle/src/RequestOptions.php b/vendor/guzzlehttp/guzzle/src/RequestOptions.php index 355f658..e90fc0c 100644 --- a/vendor/guzzlehttp/guzzle/src/RequestOptions.php +++ b/vendor/guzzlehttp/guzzle/src/RequestOptions.php @@ -1,263 +1,263 @@ -decider = $decider; - $this->nextHandler = $nextHandler; - $this->delay = $delay ?: __CLASS__ . '::exponentialDelay'; - } - - /** - * Default exponential backoff delay function. - * - * @param int $retries - * - * @return int milliseconds. - */ - public static function exponentialDelay($retries) - { - return (int) pow(2, $retries - 1) * 1000; - } - - /** - * @param RequestInterface $request - * @param array $options - * - * @return PromiseInterface - */ - public function __invoke(RequestInterface $request, array $options) - { - if (!isset($options['retries'])) { - $options['retries'] = 0; - } - - $fn = $this->nextHandler; - return $fn($request, $options) - ->then( - $this->onFulfilled($request, $options), - $this->onRejected($request, $options) - ); - } - - /** - * Execute fulfilled closure - * - * @return mixed - */ - private function onFulfilled(RequestInterface $req, array $options) - { - return function ($value) use ($req, $options) { - if (!call_user_func( - $this->decider, - $options['retries'], - $req, - $value, - null - )) { - return $value; - } - return $this->doRetry($req, $options, $value); - }; - } - - /** - * Execute rejected closure - * - * @return callable - */ - private function onRejected(RequestInterface $req, array $options) - { - return function ($reason) use ($req, $options) { - if (!call_user_func( - $this->decider, - $options['retries'], - $req, - null, - $reason - )) { - return \GuzzleHttp\Promise\rejection_for($reason); - } - return $this->doRetry($req, $options); - }; - } - - /** - * @return self - */ - private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null) - { - $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response); - - return $this($request, $options); - } -} +decider = $decider; + $this->nextHandler = $nextHandler; + $this->delay = $delay ?: __CLASS__ . '::exponentialDelay'; + } + + /** + * Default exponential backoff delay function. + * + * @param int $retries + * + * @return int milliseconds. + */ + public static function exponentialDelay($retries) + { + return (int) pow(2, $retries - 1) * 1000; + } + + /** + * @param RequestInterface $request + * @param array $options + * + * @return PromiseInterface + */ + public function __invoke(RequestInterface $request, array $options) + { + if (!isset($options['retries'])) { + $options['retries'] = 0; + } + + $fn = $this->nextHandler; + return $fn($request, $options) + ->then( + $this->onFulfilled($request, $options), + $this->onRejected($request, $options) + ); + } + + /** + * Execute fulfilled closure + * + * @return mixed + */ + private function onFulfilled(RequestInterface $req, array $options) + { + return function ($value) use ($req, $options) { + if (!call_user_func( + $this->decider, + $options['retries'], + $req, + $value, + null + )) { + return $value; + } + return $this->doRetry($req, $options, $value); + }; + } + + /** + * Execute rejected closure + * + * @return callable + */ + private function onRejected(RequestInterface $req, array $options) + { + return function ($reason) use ($req, $options) { + if (!call_user_func( + $this->decider, + $options['retries'], + $req, + null, + $reason + )) { + return \GuzzleHttp\Promise\rejection_for($reason); + } + return $this->doRetry($req, $options); + }; + } + + /** + * @return self + */ + private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null) + { + $options['delay'] = call_user_func($this->delay, ++$options['retries'], $response); + + return $this($request, $options); + } +} diff --git a/vendor/guzzlehttp/guzzle/src/TransferStats.php b/vendor/guzzlehttp/guzzle/src/TransferStats.php index 87fb3c0..240e392 100644 --- a/vendor/guzzlehttp/guzzle/src/TransferStats.php +++ b/vendor/guzzlehttp/guzzle/src/TransferStats.php @@ -1,126 +1,126 @@ -request = $request; - $this->response = $response; - $this->transferTime = $transferTime; - $this->handlerErrorData = $handlerErrorData; - $this->handlerStats = $handlerStats; - } - - /** - * @return RequestInterface - */ - public function getRequest() - { - return $this->request; - } - - /** - * Returns the response that was received (if any). - * - * @return ResponseInterface|null - */ - public function getResponse() - { - return $this->response; - } - - /** - * Returns true if a response was received. - * - * @return bool - */ - public function hasResponse() - { - return $this->response !== null; - } - - /** - * Gets handler specific error data. - * - * This might be an exception, a integer representing an error code, or - * anything else. Relying on this value assumes that you know what handler - * you are using. - * - * @return mixed - */ - public function getHandlerErrorData() - { - return $this->handlerErrorData; - } - - /** - * Get the effective URI the request was sent to. - * - * @return UriInterface - */ - public function getEffectiveUri() - { - return $this->request->getUri(); - } - - /** - * Get the estimated time the request was being transferred by the handler. - * - * @return float|null Time in seconds. - */ - public function getTransferTime() - { - return $this->transferTime; - } - - /** - * Gets an array of all of the handler specific transfer data. - * - * @return array - */ - public function getHandlerStats() - { - return $this->handlerStats; - } - - /** - * Get a specific handler statistic from the handler by name. - * - * @param string $stat Handler specific transfer stat to retrieve. - * - * @return mixed|null - */ - public function getHandlerStat($stat) - { - return isset($this->handlerStats[$stat]) - ? $this->handlerStats[$stat] - : null; - } -} +request = $request; + $this->response = $response; + $this->transferTime = $transferTime; + $this->handlerErrorData = $handlerErrorData; + $this->handlerStats = $handlerStats; + } + + /** + * @return RequestInterface + */ + public function getRequest() + { + return $this->request; + } + + /** + * Returns the response that was received (if any). + * + * @return ResponseInterface|null + */ + public function getResponse() + { + return $this->response; + } + + /** + * Returns true if a response was received. + * + * @return bool + */ + public function hasResponse() + { + return $this->response !== null; + } + + /** + * Gets handler specific error data. + * + * This might be an exception, a integer representing an error code, or + * anything else. Relying on this value assumes that you know what handler + * you are using. + * + * @return mixed + */ + public function getHandlerErrorData() + { + return $this->handlerErrorData; + } + + /** + * Get the effective URI the request was sent to. + * + * @return UriInterface + */ + public function getEffectiveUri() + { + return $this->request->getUri(); + } + + /** + * Get the estimated time the request was being transferred by the handler. + * + * @return float|null Time in seconds. + */ + public function getTransferTime() + { + return $this->transferTime; + } + + /** + * Gets an array of all of the handler specific transfer data. + * + * @return array + */ + public function getHandlerStats() + { + return $this->handlerStats; + } + + /** + * Get a specific handler statistic from the handler by name. + * + * @param string $stat Handler specific transfer stat to retrieve. + * + * @return mixed|null + */ + public function getHandlerStat($stat) + { + return isset($this->handlerStats[$stat]) + ? $this->handlerStats[$stat] + : null; + } +} diff --git a/vendor/guzzlehttp/guzzle/src/UriTemplate.php b/vendor/guzzlehttp/guzzle/src/UriTemplate.php index 96dcfd0..643a20c 100644 --- a/vendor/guzzlehttp/guzzle/src/UriTemplate.php +++ b/vendor/guzzlehttp/guzzle/src/UriTemplate.php @@ -1,237 +1,237 @@ - ['prefix' => '', 'joiner' => ',', 'query' => false], - '+' => ['prefix' => '', 'joiner' => ',', 'query' => false], - '#' => ['prefix' => '#', 'joiner' => ',', 'query' => false], - '.' => ['prefix' => '.', 'joiner' => '.', 'query' => false], - '/' => ['prefix' => '/', 'joiner' => '/', 'query' => false], - ';' => ['prefix' => ';', 'joiner' => ';', 'query' => true], - '?' => ['prefix' => '?', 'joiner' => '&', 'query' => true], - '&' => ['prefix' => '&', 'joiner' => '&', 'query' => true] - ]; - - /** @var array Delimiters */ - private static $delims = [':', '/', '?', '#', '[', ']', '@', '!', '$', - '&', '\'', '(', ')', '*', '+', ',', ';', '=']; - - /** @var array Percent encoded delimiters */ - private static $delimsPct = ['%3A', '%2F', '%3F', '%23', '%5B', '%5D', - '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', - '%3B', '%3D']; - - public function expand($template, array $variables) - { - if (false === strpos($template, '{')) { - return $template; - } - - $this->template = $template; - $this->variables = $variables; - - return preg_replace_callback( - '/\{([^\}]+)\}/', - [$this, 'expandMatch'], - $this->template - ); - } - - /** - * Parse an expression into parts - * - * @param string $expression Expression to parse - * - * @return array Returns an associative array of parts - */ - private function parseExpression($expression) - { - $result = []; - - if (isset(self::$operatorHash[$expression[0]])) { - $result['operator'] = $expression[0]; - $expression = substr($expression, 1); - } else { - $result['operator'] = ''; - } - - foreach (explode(',', $expression) as $value) { - $value = trim($value); - $varspec = []; - if ($colonPos = strpos($value, ':')) { - $varspec['value'] = substr($value, 0, $colonPos); - $varspec['modifier'] = ':'; - $varspec['position'] = (int) substr($value, $colonPos + 1); - } elseif (substr($value, -1) === '*') { - $varspec['modifier'] = '*'; - $varspec['value'] = substr($value, 0, -1); - } else { - $varspec['value'] = (string) $value; - $varspec['modifier'] = ''; - } - $result['values'][] = $varspec; - } - - return $result; - } - - /** - * Process an expansion - * - * @param array $matches Matches met in the preg_replace_callback - * - * @return string Returns the replacement string - */ - private function expandMatch(array $matches) - { - static $rfc1738to3986 = ['+' => '%20', '%7e' => '~']; - - $replacements = []; - $parsed = self::parseExpression($matches[1]); - $prefix = self::$operatorHash[$parsed['operator']]['prefix']; - $joiner = self::$operatorHash[$parsed['operator']]['joiner']; - $useQuery = self::$operatorHash[$parsed['operator']]['query']; - - foreach ($parsed['values'] as $value) { - if (!isset($this->variables[$value['value']])) { - continue; - } - - $variable = $this->variables[$value['value']]; - $actuallyUseQuery = $useQuery; - $expanded = ''; - - if (is_array($variable)) { - $isAssoc = $this->isAssoc($variable); - $kvp = []; - foreach ($variable as $key => $var) { - if ($isAssoc) { - $key = rawurlencode($key); - $isNestedArray = is_array($var); - } else { - $isNestedArray = false; - } - - if (!$isNestedArray) { - $var = rawurlencode($var); - if ($parsed['operator'] === '+' || - $parsed['operator'] === '#' - ) { - $var = $this->decodeReserved($var); - } - } - - if ($value['modifier'] === '*') { - if ($isAssoc) { - if ($isNestedArray) { - // Nested arrays must allow for deeply nested - // structures. - $var = strtr( - http_build_query([$key => $var]), - $rfc1738to3986 - ); - } else { - $var = $key . '=' . $var; - } - } elseif ($key > 0 && $actuallyUseQuery) { - $var = $value['value'] . '=' . $var; - } - } - - $kvp[$key] = $var; - } - - if (empty($variable)) { - $actuallyUseQuery = false; - } elseif ($value['modifier'] === '*') { - $expanded = implode($joiner, $kvp); - if ($isAssoc) { - // Don't prepend the value name when using the explode - // modifier with an associative array. - $actuallyUseQuery = false; - } - } else { - if ($isAssoc) { - // When an associative array is encountered and the - // explode modifier is not set, then the result must be - // a comma separated list of keys followed by their - // respective values. - foreach ($kvp as $k => &$v) { - $v = $k . ',' . $v; - } - } - $expanded = implode(',', $kvp); - } - } else { - if ($value['modifier'] === ':') { - $variable = substr($variable, 0, $value['position']); - } - $expanded = rawurlencode($variable); - if ($parsed['operator'] === '+' || $parsed['operator'] === '#') { - $expanded = $this->decodeReserved($expanded); - } - } - - if ($actuallyUseQuery) { - if (!$expanded && $joiner !== '&') { - $expanded = $value['value']; - } else { - $expanded = $value['value'] . '=' . $expanded; - } - } - - $replacements[] = $expanded; - } - - $ret = implode($joiner, $replacements); - if ($ret && $prefix) { - return $prefix . $ret; - } - - return $ret; - } - - /** - * Determines if an array is associative. - * - * This makes the assumption that input arrays are sequences or hashes. - * This assumption is a tradeoff for accuracy in favor of speed, but it - * should work in almost every case where input is supplied for a URI - * template. - * - * @param array $array Array to check - * - * @return bool - */ - private function isAssoc(array $array) - { - return $array && array_keys($array)[0] !== 0; - } - - /** - * Removes percent encoding on reserved characters (used with + and # - * modifiers). - * - * @param string $string String to fix - * - * @return string - */ - private function decodeReserved($string) - { - return str_replace(self::$delimsPct, self::$delims, $string); - } -} + ['prefix' => '', 'joiner' => ',', 'query' => false], + '+' => ['prefix' => '', 'joiner' => ',', 'query' => false], + '#' => ['prefix' => '#', 'joiner' => ',', 'query' => false], + '.' => ['prefix' => '.', 'joiner' => '.', 'query' => false], + '/' => ['prefix' => '/', 'joiner' => '/', 'query' => false], + ';' => ['prefix' => ';', 'joiner' => ';', 'query' => true], + '?' => ['prefix' => '?', 'joiner' => '&', 'query' => true], + '&' => ['prefix' => '&', 'joiner' => '&', 'query' => true] + ]; + + /** @var array Delimiters */ + private static $delims = [':', '/', '?', '#', '[', ']', '@', '!', '$', + '&', '\'', '(', ')', '*', '+', ',', ';', '=']; + + /** @var array Percent encoded delimiters */ + private static $delimsPct = ['%3A', '%2F', '%3F', '%23', '%5B', '%5D', + '%40', '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', + '%3B', '%3D']; + + public function expand($template, array $variables) + { + if (false === strpos($template, '{')) { + return $template; + } + + $this->template = $template; + $this->variables = $variables; + + return preg_replace_callback( + '/\{([^\}]+)\}/', + [$this, 'expandMatch'], + $this->template + ); + } + + /** + * Parse an expression into parts + * + * @param string $expression Expression to parse + * + * @return array Returns an associative array of parts + */ + private function parseExpression($expression) + { + $result = []; + + if (isset(self::$operatorHash[$expression[0]])) { + $result['operator'] = $expression[0]; + $expression = substr($expression, 1); + } else { + $result['operator'] = ''; + } + + foreach (explode(',', $expression) as $value) { + $value = trim($value); + $varspec = []; + if ($colonPos = strpos($value, ':')) { + $varspec['value'] = substr($value, 0, $colonPos); + $varspec['modifier'] = ':'; + $varspec['position'] = (int) substr($value, $colonPos + 1); + } elseif (substr($value, -1) === '*') { + $varspec['modifier'] = '*'; + $varspec['value'] = substr($value, 0, -1); + } else { + $varspec['value'] = (string) $value; + $varspec['modifier'] = ''; + } + $result['values'][] = $varspec; + } + + return $result; + } + + /** + * Process an expansion + * + * @param array $matches Matches met in the preg_replace_callback + * + * @return string Returns the replacement string + */ + private function expandMatch(array $matches) + { + static $rfc1738to3986 = ['+' => '%20', '%7e' => '~']; + + $replacements = []; + $parsed = self::parseExpression($matches[1]); + $prefix = self::$operatorHash[$parsed['operator']]['prefix']; + $joiner = self::$operatorHash[$parsed['operator']]['joiner']; + $useQuery = self::$operatorHash[$parsed['operator']]['query']; + + foreach ($parsed['values'] as $value) { + if (!isset($this->variables[$value['value']])) { + continue; + } + + $variable = $this->variables[$value['value']]; + $actuallyUseQuery = $useQuery; + $expanded = ''; + + if (is_array($variable)) { + $isAssoc = $this->isAssoc($variable); + $kvp = []; + foreach ($variable as $key => $var) { + if ($isAssoc) { + $key = rawurlencode($key); + $isNestedArray = is_array($var); + } else { + $isNestedArray = false; + } + + if (!$isNestedArray) { + $var = rawurlencode($var); + if ($parsed['operator'] === '+' || + $parsed['operator'] === '#' + ) { + $var = $this->decodeReserved($var); + } + } + + if ($value['modifier'] === '*') { + if ($isAssoc) { + if ($isNestedArray) { + // Nested arrays must allow for deeply nested + // structures. + $var = strtr( + http_build_query([$key => $var]), + $rfc1738to3986 + ); + } else { + $var = $key . '=' . $var; + } + } elseif ($key > 0 && $actuallyUseQuery) { + $var = $value['value'] . '=' . $var; + } + } + + $kvp[$key] = $var; + } + + if (empty($variable)) { + $actuallyUseQuery = false; + } elseif ($value['modifier'] === '*') { + $expanded = implode($joiner, $kvp); + if ($isAssoc) { + // Don't prepend the value name when using the explode + // modifier with an associative array. + $actuallyUseQuery = false; + } + } else { + if ($isAssoc) { + // When an associative array is encountered and the + // explode modifier is not set, then the result must be + // a comma separated list of keys followed by their + // respective values. + foreach ($kvp as $k => &$v) { + $v = $k . ',' . $v; + } + } + $expanded = implode(',', $kvp); + } + } else { + if ($value['modifier'] === ':') { + $variable = substr($variable, 0, $value['position']); + } + $expanded = rawurlencode($variable); + if ($parsed['operator'] === '+' || $parsed['operator'] === '#') { + $expanded = $this->decodeReserved($expanded); + } + } + + if ($actuallyUseQuery) { + if (!$expanded && $joiner !== '&') { + $expanded = $value['value']; + } else { + $expanded = $value['value'] . '=' . $expanded; + } + } + + $replacements[] = $expanded; + } + + $ret = implode($joiner, $replacements); + if ($ret && $prefix) { + return $prefix . $ret; + } + + return $ret; + } + + /** + * Determines if an array is associative. + * + * This makes the assumption that input arrays are sequences or hashes. + * This assumption is a tradeoff for accuracy in favor of speed, but it + * should work in almost every case where input is supplied for a URI + * template. + * + * @param array $array Array to check + * + * @return bool + */ + private function isAssoc(array $array) + { + return $array && array_keys($array)[0] !== 0; + } + + /** + * Removes percent encoding on reserved characters (used with + and # + * modifiers). + * + * @param string $string String to fix + * + * @return string + */ + private function decodeReserved($string) + { + return str_replace(self::$delimsPct, self::$delims, $string); + } +} diff --git a/vendor/guzzlehttp/guzzle/src/Utils.php b/vendor/guzzlehttp/guzzle/src/Utils.php index c698acb..238162e 100644 --- a/vendor/guzzlehttp/guzzle/src/Utils.php +++ b/vendor/guzzlehttp/guzzle/src/Utils.php @@ -1,92 +1,92 @@ -getHost()) { - $asciiHost = self::idnToAsci($uri->getHost(), $options, $info); - if ($asciiHost === false) { - $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; - - $errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) { - return substr($name, 0, 11) === 'IDNA_ERROR_'; - }); - - $errors = []; - foreach ($errorConstants as $errorConstant) { - if ($errorBitSet & constant($errorConstant)) { - $errors[] = $errorConstant; - } - } - - $errorMessage = 'IDN conversion failed'; - if ($errors) { - $errorMessage .= ' (errors: ' . implode(', ', $errors) . ')'; - } - - throw new InvalidArgumentException($errorMessage); - } else { - if ($uri->getHost() !== $asciiHost) { - // Replace URI only if the ASCII version is different - $uri = $uri->withHost($asciiHost); - } - } - } - - return $uri; - } - - /** - * @param string $domain - * @param int $options - * @param array $info - * - * @return string|false - */ - private static function idnToAsci($domain, $options, &$info = []) - { - if (\preg_match('%^[ -~]+$%', $domain) === 1) { - return $domain; - } - - if (\extension_loaded('intl') && defined('INTL_IDNA_VARIANT_UTS46')) { - return \idn_to_ascii($domain, $options, INTL_IDNA_VARIANT_UTS46, $info); - } - - /* - * The Idn class is marked as @internal. Verify that class and method exists. - */ - if (method_exists(Idn::class, 'idn_to_ascii')) { - return Idn::idn_to_ascii($domain, $options, Idn::INTL_IDNA_VARIANT_UTS46, $info); - } - - throw new \RuntimeException('ext-intl or symfony/polyfill-intl-idn not loaded or too old'); - } -} +getHost()) { + $asciiHost = self::idnToAsci($uri->getHost(), $options, $info); + if ($asciiHost === false) { + $errorBitSet = isset($info['errors']) ? $info['errors'] : 0; + + $errorConstants = array_filter(array_keys(get_defined_constants()), function ($name) { + return substr($name, 0, 11) === 'IDNA_ERROR_'; + }); + + $errors = []; + foreach ($errorConstants as $errorConstant) { + if ($errorBitSet & constant($errorConstant)) { + $errors[] = $errorConstant; + } + } + + $errorMessage = 'IDN conversion failed'; + if ($errors) { + $errorMessage .= ' (errors: ' . implode(', ', $errors) . ')'; + } + + throw new InvalidArgumentException($errorMessage); + } else { + if ($uri->getHost() !== $asciiHost) { + // Replace URI only if the ASCII version is different + $uri = $uri->withHost($asciiHost); + } + } + } + + return $uri; + } + + /** + * @param string $domain + * @param int $options + * @param array $info + * + * @return string|false + */ + private static function idnToAsci($domain, $options, &$info = []) + { + if (\preg_match('%^[ -~]+$%', $domain) === 1) { + return $domain; + } + + if (\extension_loaded('intl') && defined('INTL_IDNA_VARIANT_UTS46')) { + return \idn_to_ascii($domain, $options, INTL_IDNA_VARIANT_UTS46, $info); + } + + /* + * The Idn class is marked as @internal. Verify that class and method exists. + */ + if (method_exists(Idn::class, 'idn_to_ascii')) { + return Idn::idn_to_ascii($domain, $options, Idn::INTL_IDNA_VARIANT_UTS46, $info); + } + + throw new \RuntimeException('ext-intl or symfony/polyfill-intl-idn not loaded or too old'); + } +} diff --git a/vendor/guzzlehttp/guzzle/src/functions.php b/vendor/guzzlehttp/guzzle/src/functions.php index c2afd8c..0f09e3a 100644 --- a/vendor/guzzlehttp/guzzle/src/functions.php +++ b/vendor/guzzlehttp/guzzle/src/functions.php @@ -1,334 +1,334 @@ -expand($template, $variables); -} - -/** - * Debug function used to describe the provided value type and class. - * - * @param mixed $input - * - * @return string Returns a string containing the type of the variable and - * if a class is provided, the class name. - */ -function describe_type($input) -{ - switch (gettype($input)) { - case 'object': - return 'object(' . get_class($input) . ')'; - case 'array': - return 'array(' . count($input) . ')'; - default: - ob_start(); - var_dump($input); - // normalize float vs double - return str_replace('double(', 'float(', rtrim(ob_get_clean())); - } -} - -/** - * Parses an array of header lines into an associative array of headers. - * - * @param iterable $lines Header lines array of strings in the following - * format: "Name: Value" - * @return array - */ -function headers_from_lines($lines) -{ - $headers = []; - - foreach ($lines as $line) { - $parts = explode(':', $line, 2); - $headers[trim($parts[0])][] = isset($parts[1]) - ? trim($parts[1]) - : null; - } - - return $headers; -} - -/** - * Returns a debug stream based on the provided variable. - * - * @param mixed $value Optional value - * - * @return resource - */ -function debug_resource($value = null) -{ - if (is_resource($value)) { - return $value; - } elseif (defined('STDOUT')) { - return STDOUT; - } - - return fopen('php://output', 'w'); -} - -/** - * Chooses and creates a default handler to use based on the environment. - * - * The returned handler is not wrapped by any default middlewares. - * - * @return callable Returns the best handler for the given system. - * @throws \RuntimeException if no viable Handler is available. - */ -function choose_handler() -{ - $handler = null; - if (function_exists('curl_multi_exec') && function_exists('curl_exec')) { - $handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler()); - } elseif (function_exists('curl_exec')) { - $handler = new CurlHandler(); - } elseif (function_exists('curl_multi_exec')) { - $handler = new CurlMultiHandler(); - } - - if (ini_get('allow_url_fopen')) { - $handler = $handler - ? Proxy::wrapStreaming($handler, new StreamHandler()) - : new StreamHandler(); - } elseif (!$handler) { - throw new \RuntimeException('GuzzleHttp requires cURL, the ' - . 'allow_url_fopen ini setting, or a custom HTTP handler.'); - } - - return $handler; -} - -/** - * Get the default User-Agent string to use with Guzzle - * - * @return string - */ -function default_user_agent() -{ - static $defaultAgent = ''; - - if (!$defaultAgent) { - $defaultAgent = 'GuzzleHttp/' . Client::VERSION; - if (extension_loaded('curl') && function_exists('curl_version')) { - $defaultAgent .= ' curl/' . \curl_version()['version']; - } - $defaultAgent .= ' PHP/' . PHP_VERSION; - } - - return $defaultAgent; -} - -/** - * Returns the default cacert bundle for the current system. - * - * First, the openssl.cafile and curl.cainfo php.ini settings are checked. - * If those settings are not configured, then the common locations for - * bundles found on Red Hat, CentOS, Fedora, Ubuntu, Debian, FreeBSD, OS X - * and Windows are checked. If any of these file locations are found on - * disk, they will be utilized. - * - * Note: the result of this function is cached for subsequent calls. - * - * @return string - * @throws \RuntimeException if no bundle can be found. - */ -function default_ca_bundle() -{ - static $cached = null; - static $cafiles = [ - // Red Hat, CentOS, Fedora (provided by the ca-certificates package) - '/etc/pki/tls/certs/ca-bundle.crt', - // Ubuntu, Debian (provided by the ca-certificates package) - '/etc/ssl/certs/ca-certificates.crt', - // FreeBSD (provided by the ca_root_nss package) - '/usr/local/share/certs/ca-root-nss.crt', - // SLES 12 (provided by the ca-certificates package) - '/var/lib/ca-certificates/ca-bundle.pem', - // OS X provided by homebrew (using the default path) - '/usr/local/etc/openssl/cert.pem', - // Google app engine - '/etc/ca-certificates.crt', - // Windows? - 'C:\\windows\\system32\\curl-ca-bundle.crt', - 'C:\\windows\\curl-ca-bundle.crt', - ]; - - if ($cached) { - return $cached; - } - - if ($ca = ini_get('openssl.cafile')) { - return $cached = $ca; - } - - if ($ca = ini_get('curl.cainfo')) { - return $cached = $ca; - } - - foreach ($cafiles as $filename) { - if (file_exists($filename)) { - return $cached = $filename; - } - } - - throw new \RuntimeException( - <<< EOT -No system CA bundle could be found in any of the the common system locations. -PHP versions earlier than 5.6 are not properly configured to use the system's -CA bundle by default. In order to verify peer certificates, you will need to -supply the path on disk to a certificate bundle to the 'verify' request -option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not -need a specific certificate bundle, then Mozilla provides a commonly used CA -bundle which can be downloaded here (provided by the maintainer of cURL): -https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt. Once -you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP -ini setting to point to the path to the file, allowing you to omit the 'verify' -request option. See http://curl.haxx.se/docs/sslcerts.html for more -information. -EOT - ); -} - -/** - * Creates an associative array of lowercase header names to the actual - * header casing. - * - * @param array $headers - * - * @return array - */ -function normalize_header_keys(array $headers) -{ - $result = []; - foreach (array_keys($headers) as $key) { - $result[strtolower($key)] = $key; - } - - return $result; -} - -/** - * Returns true if the provided host matches any of the no proxy areas. - * - * This method will strip a port from the host if it is present. Each pattern - * can be matched with an exact match (e.g., "foo.com" == "foo.com") or a - * partial match: (e.g., "foo.com" == "baz.foo.com" and ".foo.com" == - * "baz.foo.com", but ".foo.com" != "foo.com"). - * - * Areas are matched in the following cases: - * 1. "*" (without quotes) always matches any hosts. - * 2. An exact match. - * 3. The area starts with "." and the area is the last part of the host. e.g. - * '.mit.edu' will match any host that ends with '.mit.edu'. - * - * @param string $host Host to check against the patterns. - * @param array $noProxyArray An array of host patterns. - * - * @return bool - */ -function is_host_in_noproxy($host, array $noProxyArray) -{ - if (strlen($host) === 0) { - throw new \InvalidArgumentException('Empty host provided'); - } - - // Strip port if present. - if (strpos($host, ':')) { - $host = explode($host, ':', 2)[0]; - } - - foreach ($noProxyArray as $area) { - // Always match on wildcards. - if ($area === '*') { - return true; - } elseif (empty($area)) { - // Don't match on empty values. - continue; - } elseif ($area === $host) { - // Exact matches. - return true; - } else { - // Special match if the area when prefixed with ".". Remove any - // existing leading "." and add a new leading ".". - $area = '.' . ltrim($area, '.'); - if (substr($host, -(strlen($area))) === $area) { - return true; - } - } - } - - return false; -} - -/** - * Wrapper for json_decode that throws when an error occurs. - * - * @param string $json JSON data to parse - * @param bool $assoc When true, returned objects will be converted - * into associative arrays. - * @param int $depth User specified recursion depth. - * @param int $options Bitmask of JSON decode options. - * - * @return mixed - * @throws Exception\InvalidArgumentException if the JSON cannot be decoded. - * @link http://www.php.net/manual/en/function.json-decode.php - */ -function json_decode($json, $assoc = false, $depth = 512, $options = 0) -{ - $data = \json_decode($json, $assoc, $depth, $options); - if (JSON_ERROR_NONE !== json_last_error()) { - throw new Exception\InvalidArgumentException( - 'json_decode error: ' . json_last_error_msg() - ); - } - - return $data; -} - -/** - * Wrapper for JSON encoding that throws when an error occurs. - * - * @param mixed $value The value being encoded - * @param int $options JSON encode option bitmask - * @param int $depth Set the maximum depth. Must be greater than zero. - * - * @return string - * @throws Exception\InvalidArgumentException if the JSON cannot be encoded. - * @link http://www.php.net/manual/en/function.json-encode.php - */ -function json_encode($value, $options = 0, $depth = 512) -{ - $json = \json_encode($value, $options, $depth); - if (JSON_ERROR_NONE !== json_last_error()) { - throw new Exception\InvalidArgumentException( - 'json_encode error: ' . json_last_error_msg() - ); - } - - return $json; -} +expand($template, $variables); +} + +/** + * Debug function used to describe the provided value type and class. + * + * @param mixed $input + * + * @return string Returns a string containing the type of the variable and + * if a class is provided, the class name. + */ +function describe_type($input) +{ + switch (gettype($input)) { + case 'object': + return 'object(' . get_class($input) . ')'; + case 'array': + return 'array(' . count($input) . ')'; + default: + ob_start(); + var_dump($input); + // normalize float vs double + return str_replace('double(', 'float(', rtrim(ob_get_clean())); + } +} + +/** + * Parses an array of header lines into an associative array of headers. + * + * @param iterable $lines Header lines array of strings in the following + * format: "Name: Value" + * @return array + */ +function headers_from_lines($lines) +{ + $headers = []; + + foreach ($lines as $line) { + $parts = explode(':', $line, 2); + $headers[trim($parts[0])][] = isset($parts[1]) + ? trim($parts[1]) + : null; + } + + return $headers; +} + +/** + * Returns a debug stream based on the provided variable. + * + * @param mixed $value Optional value + * + * @return resource + */ +function debug_resource($value = null) +{ + if (is_resource($value)) { + return $value; + } elseif (defined('STDOUT')) { + return STDOUT; + } + + return fopen('php://output', 'w'); +} + +/** + * Chooses and creates a default handler to use based on the environment. + * + * The returned handler is not wrapped by any default middlewares. + * + * @return callable Returns the best handler for the given system. + * @throws \RuntimeException if no viable Handler is available. + */ +function choose_handler() +{ + $handler = null; + if (function_exists('curl_multi_exec') && function_exists('curl_exec')) { + $handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler()); + } elseif (function_exists('curl_exec')) { + $handler = new CurlHandler(); + } elseif (function_exists('curl_multi_exec')) { + $handler = new CurlMultiHandler(); + } + + if (ini_get('allow_url_fopen')) { + $handler = $handler + ? Proxy::wrapStreaming($handler, new StreamHandler()) + : new StreamHandler(); + } elseif (!$handler) { + throw new \RuntimeException('GuzzleHttp requires cURL, the ' + . 'allow_url_fopen ini setting, or a custom HTTP handler.'); + } + + return $handler; +} + +/** + * Get the default User-Agent string to use with Guzzle + * + * @return string + */ +function default_user_agent() +{ + static $defaultAgent = ''; + + if (!$defaultAgent) { + $defaultAgent = 'GuzzleHttp/' . Client::VERSION; + if (extension_loaded('curl') && function_exists('curl_version')) { + $defaultAgent .= ' curl/' . \curl_version()['version']; + } + $defaultAgent .= ' PHP/' . PHP_VERSION; + } + + return $defaultAgent; +} + +/** + * Returns the default cacert bundle for the current system. + * + * First, the openssl.cafile and curl.cainfo php.ini settings are checked. + * If those settings are not configured, then the common locations for + * bundles found on Red Hat, CentOS, Fedora, Ubuntu, Debian, FreeBSD, OS X + * and Windows are checked. If any of these file locations are found on + * disk, they will be utilized. + * + * Note: the result of this function is cached for subsequent calls. + * + * @return string + * @throws \RuntimeException if no bundle can be found. + */ +function default_ca_bundle() +{ + static $cached = null; + static $cafiles = [ + // Red Hat, CentOS, Fedora (provided by the ca-certificates package) + '/etc/pki/tls/certs/ca-bundle.crt', + // Ubuntu, Debian (provided by the ca-certificates package) + '/etc/ssl/certs/ca-certificates.crt', + // FreeBSD (provided by the ca_root_nss package) + '/usr/local/share/certs/ca-root-nss.crt', + // SLES 12 (provided by the ca-certificates package) + '/var/lib/ca-certificates/ca-bundle.pem', + // OS X provided by homebrew (using the default path) + '/usr/local/etc/openssl/cert.pem', + // Google app engine + '/etc/ca-certificates.crt', + // Windows? + 'C:\\windows\\system32\\curl-ca-bundle.crt', + 'C:\\windows\\curl-ca-bundle.crt', + ]; + + if ($cached) { + return $cached; + } + + if ($ca = ini_get('openssl.cafile')) { + return $cached = $ca; + } + + if ($ca = ini_get('curl.cainfo')) { + return $cached = $ca; + } + + foreach ($cafiles as $filename) { + if (file_exists($filename)) { + return $cached = $filename; + } + } + + throw new \RuntimeException( + <<< EOT +No system CA bundle could be found in any of the the common system locations. +PHP versions earlier than 5.6 are not properly configured to use the system's +CA bundle by default. In order to verify peer certificates, you will need to +supply the path on disk to a certificate bundle to the 'verify' request +option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not +need a specific certificate bundle, then Mozilla provides a commonly used CA +bundle which can be downloaded here (provided by the maintainer of cURL): +https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt. Once +you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP +ini setting to point to the path to the file, allowing you to omit the 'verify' +request option. See http://curl.haxx.se/docs/sslcerts.html for more +information. +EOT + ); +} + +/** + * Creates an associative array of lowercase header names to the actual + * header casing. + * + * @param array $headers + * + * @return array + */ +function normalize_header_keys(array $headers) +{ + $result = []; + foreach (array_keys($headers) as $key) { + $result[strtolower($key)] = $key; + } + + return $result; +} + +/** + * Returns true if the provided host matches any of the no proxy areas. + * + * This method will strip a port from the host if it is present. Each pattern + * can be matched with an exact match (e.g., "foo.com" == "foo.com") or a + * partial match: (e.g., "foo.com" == "baz.foo.com" and ".foo.com" == + * "baz.foo.com", but ".foo.com" != "foo.com"). + * + * Areas are matched in the following cases: + * 1. "*" (without quotes) always matches any hosts. + * 2. An exact match. + * 3. The area starts with "." and the area is the last part of the host. e.g. + * '.mit.edu' will match any host that ends with '.mit.edu'. + * + * @param string $host Host to check against the patterns. + * @param array $noProxyArray An array of host patterns. + * + * @return bool + */ +function is_host_in_noproxy($host, array $noProxyArray) +{ + if (strlen($host) === 0) { + throw new \InvalidArgumentException('Empty host provided'); + } + + // Strip port if present. + if (strpos($host, ':')) { + $host = explode($host, ':', 2)[0]; + } + + foreach ($noProxyArray as $area) { + // Always match on wildcards. + if ($area === '*') { + return true; + } elseif (empty($area)) { + // Don't match on empty values. + continue; + } elseif ($area === $host) { + // Exact matches. + return true; + } else { + // Special match if the area when prefixed with ".". Remove any + // existing leading "." and add a new leading ".". + $area = '.' . ltrim($area, '.'); + if (substr($host, -(strlen($area))) === $area) { + return true; + } + } + } + + return false; +} + +/** + * Wrapper for json_decode that throws when an error occurs. + * + * @param string $json JSON data to parse + * @param bool $assoc When true, returned objects will be converted + * into associative arrays. + * @param int $depth User specified recursion depth. + * @param int $options Bitmask of JSON decode options. + * + * @return mixed + * @throws Exception\InvalidArgumentException if the JSON cannot be decoded. + * @link http://www.php.net/manual/en/function.json-decode.php + */ +function json_decode($json, $assoc = false, $depth = 512, $options = 0) +{ + $data = \json_decode($json, $assoc, $depth, $options); + if (JSON_ERROR_NONE !== json_last_error()) { + throw new Exception\InvalidArgumentException( + 'json_decode error: ' . json_last_error_msg() + ); + } + + return $data; +} + +/** + * Wrapper for JSON encoding that throws when an error occurs. + * + * @param mixed $value The value being encoded + * @param int $options JSON encode option bitmask + * @param int $depth Set the maximum depth. Must be greater than zero. + * + * @return string + * @throws Exception\InvalidArgumentException if the JSON cannot be encoded. + * @link http://www.php.net/manual/en/function.json-encode.php + */ +function json_encode($value, $options = 0, $depth = 512) +{ + $json = \json_encode($value, $options, $depth); + if (JSON_ERROR_NONE !== json_last_error()) { + throw new Exception\InvalidArgumentException( + 'json_encode error: ' . json_last_error_msg() + ); + } + + return $json; +} diff --git a/vendor/guzzlehttp/guzzle/src/functions_include.php b/vendor/guzzlehttp/guzzle/src/functions_include.php index a93393a..fda82f1 100644 --- a/vendor/guzzlehttp/guzzle/src/functions_include.php +++ b/vendor/guzzlehttp/guzzle/src/functions_include.php @@ -1,6 +1,6 @@ -