annotate vendor/guzzlehttp/guzzle/src/functions.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 5fb285c0d0e3
children
rev   line source
Chris@0 1 <?php
Chris@0 2 namespace GuzzleHttp;
Chris@0 3
Chris@0 4 use GuzzleHttp\Handler\CurlHandler;
Chris@0 5 use GuzzleHttp\Handler\CurlMultiHandler;
Chris@0 6 use GuzzleHttp\Handler\Proxy;
Chris@0 7 use GuzzleHttp\Handler\StreamHandler;
Chris@0 8
Chris@0 9 /**
Chris@0 10 * Expands a URI template
Chris@0 11 *
Chris@0 12 * @param string $template URI template
Chris@0 13 * @param array $variables Template variables
Chris@0 14 *
Chris@0 15 * @return string
Chris@0 16 */
Chris@0 17 function uri_template($template, array $variables)
Chris@0 18 {
Chris@0 19 if (extension_loaded('uri_template')) {
Chris@0 20 // @codeCoverageIgnoreStart
Chris@0 21 return \uri_template($template, $variables);
Chris@0 22 // @codeCoverageIgnoreEnd
Chris@0 23 }
Chris@0 24
Chris@0 25 static $uriTemplate;
Chris@0 26 if (!$uriTemplate) {
Chris@0 27 $uriTemplate = new UriTemplate();
Chris@0 28 }
Chris@0 29
Chris@0 30 return $uriTemplate->expand($template, $variables);
Chris@0 31 }
Chris@0 32
Chris@0 33 /**
Chris@0 34 * Debug function used to describe the provided value type and class.
Chris@0 35 *
Chris@0 36 * @param mixed $input
Chris@0 37 *
Chris@0 38 * @return string Returns a string containing the type of the variable and
Chris@0 39 * if a class is provided, the class name.
Chris@0 40 */
Chris@0 41 function describe_type($input)
Chris@0 42 {
Chris@0 43 switch (gettype($input)) {
Chris@0 44 case 'object':
Chris@0 45 return 'object(' . get_class($input) . ')';
Chris@0 46 case 'array':
Chris@0 47 return 'array(' . count($input) . ')';
Chris@0 48 default:
Chris@0 49 ob_start();
Chris@0 50 var_dump($input);
Chris@0 51 // normalize float vs double
Chris@0 52 return str_replace('double(', 'float(', rtrim(ob_get_clean()));
Chris@0 53 }
Chris@0 54 }
Chris@0 55
Chris@0 56 /**
Chris@0 57 * Parses an array of header lines into an associative array of headers.
Chris@0 58 *
Chris@0 59 * @param array $lines Header lines array of strings in the following
Chris@0 60 * format: "Name: Value"
Chris@0 61 * @return array
Chris@0 62 */
Chris@0 63 function headers_from_lines($lines)
Chris@0 64 {
Chris@0 65 $headers = [];
Chris@0 66
Chris@0 67 foreach ($lines as $line) {
Chris@0 68 $parts = explode(':', $line, 2);
Chris@0 69 $headers[trim($parts[0])][] = isset($parts[1])
Chris@0 70 ? trim($parts[1])
Chris@0 71 : null;
Chris@0 72 }
Chris@0 73
Chris@0 74 return $headers;
Chris@0 75 }
Chris@0 76
Chris@0 77 /**
Chris@0 78 * Returns a debug stream based on the provided variable.
Chris@0 79 *
Chris@0 80 * @param mixed $value Optional value
Chris@0 81 *
Chris@0 82 * @return resource
Chris@0 83 */
Chris@0 84 function debug_resource($value = null)
Chris@0 85 {
Chris@0 86 if (is_resource($value)) {
Chris@0 87 return $value;
Chris@0 88 } elseif (defined('STDOUT')) {
Chris@0 89 return STDOUT;
Chris@0 90 }
Chris@0 91
Chris@0 92 return fopen('php://output', 'w');
Chris@0 93 }
Chris@0 94
Chris@0 95 /**
Chris@0 96 * Chooses and creates a default handler to use based on the environment.
Chris@0 97 *
Chris@0 98 * The returned handler is not wrapped by any default middlewares.
Chris@0 99 *
Chris@0 100 * @throws \RuntimeException if no viable Handler is available.
Chris@0 101 * @return callable Returns the best handler for the given system.
Chris@0 102 */
Chris@0 103 function choose_handler()
Chris@0 104 {
Chris@0 105 $handler = null;
Chris@0 106 if (function_exists('curl_multi_exec') && function_exists('curl_exec')) {
Chris@0 107 $handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler());
Chris@0 108 } elseif (function_exists('curl_exec')) {
Chris@0 109 $handler = new CurlHandler();
Chris@0 110 } elseif (function_exists('curl_multi_exec')) {
Chris@0 111 $handler = new CurlMultiHandler();
Chris@0 112 }
Chris@0 113
Chris@0 114 if (ini_get('allow_url_fopen')) {
Chris@0 115 $handler = $handler
Chris@0 116 ? Proxy::wrapStreaming($handler, new StreamHandler())
Chris@0 117 : new StreamHandler();
Chris@0 118 } elseif (!$handler) {
Chris@0 119 throw new \RuntimeException('GuzzleHttp requires cURL, the '
Chris@0 120 . 'allow_url_fopen ini setting, or a custom HTTP handler.');
Chris@0 121 }
Chris@0 122
Chris@0 123 return $handler;
Chris@0 124 }
Chris@0 125
Chris@0 126 /**
Chris@0 127 * Get the default User-Agent string to use with Guzzle
Chris@0 128 *
Chris@0 129 * @return string
Chris@0 130 */
Chris@0 131 function default_user_agent()
Chris@0 132 {
Chris@0 133 static $defaultAgent = '';
Chris@0 134
Chris@0 135 if (!$defaultAgent) {
Chris@0 136 $defaultAgent = 'GuzzleHttp/' . Client::VERSION;
Chris@0 137 if (extension_loaded('curl') && function_exists('curl_version')) {
Chris@0 138 $defaultAgent .= ' curl/' . \curl_version()['version'];
Chris@0 139 }
Chris@0 140 $defaultAgent .= ' PHP/' . PHP_VERSION;
Chris@0 141 }
Chris@0 142
Chris@0 143 return $defaultAgent;
Chris@0 144 }
Chris@0 145
Chris@0 146 /**
Chris@0 147 * Returns the default cacert bundle for the current system.
Chris@0 148 *
Chris@0 149 * First, the openssl.cafile and curl.cainfo php.ini settings are checked.
Chris@0 150 * If those settings are not configured, then the common locations for
Chris@0 151 * bundles found on Red Hat, CentOS, Fedora, Ubuntu, Debian, FreeBSD, OS X
Chris@0 152 * and Windows are checked. If any of these file locations are found on
Chris@0 153 * disk, they will be utilized.
Chris@0 154 *
Chris@0 155 * Note: the result of this function is cached for subsequent calls.
Chris@0 156 *
Chris@0 157 * @return string
Chris@0 158 * @throws \RuntimeException if no bundle can be found.
Chris@0 159 */
Chris@0 160 function default_ca_bundle()
Chris@0 161 {
Chris@0 162 static $cached = null;
Chris@0 163 static $cafiles = [
Chris@0 164 // Red Hat, CentOS, Fedora (provided by the ca-certificates package)
Chris@0 165 '/etc/pki/tls/certs/ca-bundle.crt',
Chris@0 166 // Ubuntu, Debian (provided by the ca-certificates package)
Chris@0 167 '/etc/ssl/certs/ca-certificates.crt',
Chris@0 168 // FreeBSD (provided by the ca_root_nss package)
Chris@0 169 '/usr/local/share/certs/ca-root-nss.crt',
Chris@0 170 // SLES 12 (provided by the ca-certificates package)
Chris@0 171 '/var/lib/ca-certificates/ca-bundle.pem',
Chris@0 172 // OS X provided by homebrew (using the default path)
Chris@0 173 '/usr/local/etc/openssl/cert.pem',
Chris@0 174 // Google app engine
Chris@0 175 '/etc/ca-certificates.crt',
Chris@0 176 // Windows?
Chris@0 177 'C:\\windows\\system32\\curl-ca-bundle.crt',
Chris@0 178 'C:\\windows\\curl-ca-bundle.crt',
Chris@0 179 ];
Chris@0 180
Chris@0 181 if ($cached) {
Chris@0 182 return $cached;
Chris@0 183 }
Chris@0 184
Chris@0 185 if ($ca = ini_get('openssl.cafile')) {
Chris@0 186 return $cached = $ca;
Chris@0 187 }
Chris@0 188
Chris@0 189 if ($ca = ini_get('curl.cainfo')) {
Chris@0 190 return $cached = $ca;
Chris@0 191 }
Chris@0 192
Chris@0 193 foreach ($cafiles as $filename) {
Chris@0 194 if (file_exists($filename)) {
Chris@0 195 return $cached = $filename;
Chris@0 196 }
Chris@0 197 }
Chris@0 198
Chris@0 199 throw new \RuntimeException(<<< EOT
Chris@0 200 No system CA bundle could be found in any of the the common system locations.
Chris@0 201 PHP versions earlier than 5.6 are not properly configured to use the system's
Chris@0 202 CA bundle by default. In order to verify peer certificates, you will need to
Chris@0 203 supply the path on disk to a certificate bundle to the 'verify' request
Chris@0 204 option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not
Chris@0 205 need a specific certificate bundle, then Mozilla provides a commonly used CA
Chris@0 206 bundle which can be downloaded here (provided by the maintainer of cURL):
Chris@0 207 https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt. Once
Chris@0 208 you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP
Chris@0 209 ini setting to point to the path to the file, allowing you to omit the 'verify'
Chris@0 210 request option. See http://curl.haxx.se/docs/sslcerts.html for more
Chris@0 211 information.
Chris@0 212 EOT
Chris@0 213 );
Chris@0 214 }
Chris@0 215
Chris@0 216 /**
Chris@0 217 * Creates an associative array of lowercase header names to the actual
Chris@0 218 * header casing.
Chris@0 219 *
Chris@0 220 * @param array $headers
Chris@0 221 *
Chris@0 222 * @return array
Chris@0 223 */
Chris@0 224 function normalize_header_keys(array $headers)
Chris@0 225 {
Chris@0 226 $result = [];
Chris@0 227 foreach (array_keys($headers) as $key) {
Chris@0 228 $result[strtolower($key)] = $key;
Chris@0 229 }
Chris@0 230
Chris@0 231 return $result;
Chris@0 232 }
Chris@0 233
Chris@0 234 /**
Chris@0 235 * Returns true if the provided host matches any of the no proxy areas.
Chris@0 236 *
Chris@0 237 * This method will strip a port from the host if it is present. Each pattern
Chris@0 238 * can be matched with an exact match (e.g., "foo.com" == "foo.com") or a
Chris@0 239 * partial match: (e.g., "foo.com" == "baz.foo.com" and ".foo.com" ==
Chris@0 240 * "baz.foo.com", but ".foo.com" != "foo.com").
Chris@0 241 *
Chris@0 242 * Areas are matched in the following cases:
Chris@0 243 * 1. "*" (without quotes) always matches any hosts.
Chris@0 244 * 2. An exact match.
Chris@0 245 * 3. The area starts with "." and the area is the last part of the host. e.g.
Chris@0 246 * '.mit.edu' will match any host that ends with '.mit.edu'.
Chris@0 247 *
Chris@0 248 * @param string $host Host to check against the patterns.
Chris@0 249 * @param array $noProxyArray An array of host patterns.
Chris@0 250 *
Chris@0 251 * @return bool
Chris@0 252 */
Chris@0 253 function is_host_in_noproxy($host, array $noProxyArray)
Chris@0 254 {
Chris@0 255 if (strlen($host) === 0) {
Chris@0 256 throw new \InvalidArgumentException('Empty host provided');
Chris@0 257 }
Chris@0 258
Chris@0 259 // Strip port if present.
Chris@0 260 if (strpos($host, ':')) {
Chris@0 261 $host = explode($host, ':', 2)[0];
Chris@0 262 }
Chris@0 263
Chris@0 264 foreach ($noProxyArray as $area) {
Chris@0 265 // Always match on wildcards.
Chris@0 266 if ($area === '*') {
Chris@0 267 return true;
Chris@0 268 } elseif (empty($area)) {
Chris@0 269 // Don't match on empty values.
Chris@0 270 continue;
Chris@0 271 } elseif ($area === $host) {
Chris@0 272 // Exact matches.
Chris@0 273 return true;
Chris@0 274 } else {
Chris@0 275 // Special match if the area when prefixed with ".". Remove any
Chris@0 276 // existing leading "." and add a new leading ".".
Chris@0 277 $area = '.' . ltrim($area, '.');
Chris@0 278 if (substr($host, -(strlen($area))) === $area) {
Chris@0 279 return true;
Chris@0 280 }
Chris@0 281 }
Chris@0 282 }
Chris@0 283
Chris@0 284 return false;
Chris@0 285 }
Chris@0 286
Chris@0 287 /**
Chris@0 288 * Wrapper for json_decode that throws when an error occurs.
Chris@0 289 *
Chris@0 290 * @param string $json JSON data to parse
Chris@0 291 * @param bool $assoc When true, returned objects will be converted
Chris@0 292 * into associative arrays.
Chris@0 293 * @param int $depth User specified recursion depth.
Chris@0 294 * @param int $options Bitmask of JSON decode options.
Chris@0 295 *
Chris@0 296 * @return mixed
Chris@0 297 * @throws \InvalidArgumentException if the JSON cannot be decoded.
Chris@0 298 * @link http://www.php.net/manual/en/function.json-decode.php
Chris@0 299 */
Chris@0 300 function json_decode($json, $assoc = false, $depth = 512, $options = 0)
Chris@0 301 {
Chris@0 302 $data = \json_decode($json, $assoc, $depth, $options);
Chris@0 303 if (JSON_ERROR_NONE !== json_last_error()) {
Chris@0 304 throw new \InvalidArgumentException(
Chris@13 305 'json_decode error: ' . json_last_error_msg()
Chris@13 306 );
Chris@0 307 }
Chris@0 308
Chris@0 309 return $data;
Chris@0 310 }
Chris@0 311
Chris@0 312 /**
Chris@0 313 * Wrapper for JSON encoding that throws when an error occurs.
Chris@0 314 *
Chris@0 315 * @param mixed $value The value being encoded
Chris@0 316 * @param int $options JSON encode option bitmask
Chris@0 317 * @param int $depth Set the maximum depth. Must be greater than zero.
Chris@0 318 *
Chris@0 319 * @return string
Chris@0 320 * @throws \InvalidArgumentException if the JSON cannot be encoded.
Chris@0 321 * @link http://www.php.net/manual/en/function.json-encode.php
Chris@0 322 */
Chris@0 323 function json_encode($value, $options = 0, $depth = 512)
Chris@0 324 {
Chris@0 325 $json = \json_encode($value, $options, $depth);
Chris@0 326 if (JSON_ERROR_NONE !== json_last_error()) {
Chris@0 327 throw new \InvalidArgumentException(
Chris@13 328 'json_encode error: ' . json_last_error_msg()
Chris@13 329 );
Chris@0 330 }
Chris@0 331
Chris@0 332 return $json;
Chris@0 333 }