2015-08-27 12:03:05 -07:00
< ? php
namespace GuzzleHttp ;
use GuzzleHttp\Handler\CurlHandler ;
use GuzzleHttp\Handler\CurlMultiHandler ;
use GuzzleHttp\Handler\Proxy ;
use GuzzleHttp\Handler\StreamHandler ;
/**
* Expands a URI template
*
* @ param string $template URI template
* @ param array $variables Template variables
*
* @ return string
*/
function uri_template ( $template , array $variables )
{
if ( extension_loaded ( 'uri_template' )) {
// @codeCoverageIgnoreStart
return \uri_template ( $template , $variables );
// @codeCoverageIgnoreEnd
}
static $uriTemplate ;
if ( ! $uriTemplate ) {
$uriTemplate = new UriTemplate ();
}
return $uriTemplate -> 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 array $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 .
*
* @ throws \RuntimeException if no viable Handler is available .
* @ return callable Returns the best handler for the given system .
*/
function choose_handler ()
{
$handler = null ;
2016-07-18 09:07:48 -07:00
if ( function_exists ( 'curl_multi_exec' ) && function_exists ( 'curl_exec' )) {
2015-08-27 12:03:05 -07:00
$handler = Proxy :: wrapSync ( new CurlMultiHandler (), new CurlHandler ());
2016-07-18 09:07:48 -07:00
} elseif ( function_exists ( 'curl_exec' )) {
$handler = new CurlHandler ();
} elseif ( function_exists ( 'curl_multi_exec' )) {
$handler = new CurlMultiHandler ();
2015-08-27 12:03:05 -07:00
}
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 ;
2015-10-08 11:40:12 -07:00
if ( extension_loaded ( 'curl' ) && function_exists ( 'curl_version' )) {
2015-08-27 12:03:05 -07:00
$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' ,
// OS X provided by homebrew (using the default path)
'/usr/local/etc/openssl/cert.pem' ,
2015-10-08 11:40:12 -07:00
// Google app engine
'/etc/ca-certificates.crt' ,
2015-08-27 12:03:05 -07:00
// 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 ;
}
2015-10-08 11:40:12 -07:00
/**
* 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 ;
}
2016-07-18 09:07:48 -07:00
/**
* 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 \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 \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 \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 \InvalidArgumentException (
'json_encode error: ' . json_last_error_msg ());
}
return $json ;
}