External Libraries: Update the Requests library to version 1.8.0.

While some of the changes in the `1.8.0` release have already been copied to WordPress Core in earlier releases (see [38727], [46258], [47902] and [49382]), this release contains additional improvements, including:

- A significant performance fix when using cURL.
- Improved compliance with RFC2616.

The library has also been moved under the WordPress project’s GitHub organization and can now be found at https://github.com/WordPress/Requests.

Props jrf, dd32, rmccue, justinahinon, netweb, schlessera, TimothyBJacobs, soulseekah, ozh, skithund, carlalexander, travisnorthcutt, desrosj.
Fixes #53101.
Built from https://develop.svn.wordpress.org/trunk@50842


git-svn-id: http://core.svn.wordpress.org/trunk@50451 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
desrosj 2021-05-11 19:42:02 +00:00
parent 2e762721b1
commit f221b3eb54
56 changed files with 398 additions and 325 deletions

View File

@ -29,5 +29,5 @@ interface Requests_Auth {
* @see Requests_Hooks::register
* @param Requests_Hooks $hooks Hook system
*/
public function register(Requests_Hooks &$hooks);
}
public function register(Requests_Hooks $hooks);
}

View File

@ -53,9 +53,9 @@ class Requests_Auth_Basic implements Requests_Auth {
* @see fsockopen_header
* @param Requests_Hooks $hooks Hook system
*/
public function register(Requests_Hooks &$hooks) {
$hooks->register('curl.before_send', array(&$this, 'curl_before_send'));
$hooks->register('fsockopen.after_headers', array(&$this, 'fsockopen_header'));
public function register(Requests_Hooks $hooks) {
$hooks->register('curl.before_send', array($this, 'curl_before_send'));
$hooks->register('fsockopen.after_headers', array($this, 'fsockopen_header'));
}
/**
@ -85,4 +85,4 @@ class Requests_Auth_Basic implements Requests_Auth {
public function getAuthString() {
return $this->user . ':' . $this->pass;
}
}
}

View File

@ -65,16 +65,16 @@ class Requests_Cookie {
* @param array|Requests_Utility_CaseInsensitiveDictionary $attributes Associative array of attribute data
*/
public function __construct($name, $value, $attributes = array(), $flags = array(), $reference_time = null) {
$this->name = $name;
$this->value = $value;
$this->name = $name;
$this->value = $value;
$this->attributes = $attributes;
$default_flags = array(
'creation' => time(),
$default_flags = array(
'creation' => time(),
'last-access' => time(),
'persistent' => false,
'host-only' => true,
'persistent' => false,
'host-only' => true,
);
$this->flags = array_merge($default_flags, $flags);
$this->flags = array_merge($default_flags, $flags);
$this->reference_time = time();
if ($reference_time !== null) {
@ -228,7 +228,7 @@ class Requests_Cookie {
public function normalize() {
foreach ($this->attributes as $key => $value) {
$orig_value = $value;
$value = $this->normalize_attribute($key, $value);
$value = $this->normalize_attribute($key, $value);
if ($value === null) {
unset($this->attributes[$key]);
continue;
@ -385,7 +385,7 @@ class Requests_Cookie {
* @return Requests_Cookie Parsed cookie object
*/
public static function parse($string, $name = '', $reference_time = null) {
$parts = explode(';', $string);
$parts = explode(';', $string);
$kvparts = array_shift($parts);
if (!empty($name)) {
@ -397,13 +397,13 @@ class Requests_Cookie {
// (`=foo`)
//
// https://bugzilla.mozilla.org/show_bug.cgi?id=169091
$name = '';
$name = '';
$value = $kvparts;
}
else {
list($name, $value) = explode('=', $kvparts, 2);
}
$name = trim($name);
$name = trim($name);
$value = trim($value);
// Attribute key are handled case-insensitively
@ -412,15 +412,15 @@ class Requests_Cookie {
if (!empty($parts)) {
foreach ($parts as $part) {
if (strpos($part, '=') === false) {
$part_key = $part;
$part_key = $part;
$part_value = true;
}
else {
list($part_key, $part_value) = explode('=', $part, 2);
$part_value = trim($part_value);
$part_value = trim($part_value);
}
$part_key = trim($part_key);
$part_key = trim($part_key);
$attributes[$part_key] = $part_value;
}
}
@ -449,7 +449,7 @@ class Requests_Cookie {
// Default domain/path attributes
if (empty($parsed->attributes['domain']) && !empty($origin)) {
$parsed->attributes['domain'] = $origin->host;
$parsed->flags['host-only'] = true;
$parsed->flags['host-only'] = true;
}
else {
$parsed->flags['host-only'] = false;
@ -497,7 +497,7 @@ class Requests_Cookie {
*
* @codeCoverageIgnore
* @deprecated Use {@see Requests_Cookie::parse_from_headers}
* @return string
* @return array
*/
public static function parseFromHeaders(Requests_Response_Headers $headers) {
return self::parse_from_headers($headers);

View File

@ -68,7 +68,7 @@ class Requests_Cookie_Jar implements ArrayAccess, IteratorAggregate {
* Get the value for the item
*
* @param string $key Item key
* @return string Item value
* @return string|null Item value (null if offsetExists is false)
*/
public function offsetGet($key) {
if (!isset($this->cookies[$key])) {
@ -162,14 +162,14 @@ class Requests_Cookie_Jar implements ArrayAccess, IteratorAggregate {
*
* @var Requests_Response $response
*/
public function before_redirect_check(Requests_Response &$return) {
public function before_redirect_check(Requests_Response $return) {
$url = $return->url;
if (!$url instanceof Requests_IRI) {
$url = new Requests_IRI($url);
}
$cookies = Requests_Cookie::parse_from_headers($return->headers, $url);
$this->cookies = array_merge($this->cookies, $cookies);
$cookies = Requests_Cookie::parse_from_headers($return->headers, $url);
$this->cookies = array_merge($this->cookies, $cookies);
$return->cookies = $this;
}
}
}

View File

@ -59,4 +59,4 @@ class Requests_Exception extends Exception {
public function getData() {
return $this->data;
}
}
}

View File

@ -68,4 +68,4 @@ class Requests_Exception_HTTP extends Requests_Exception {
return 'Requests_Exception_HTTP_Unknown';
}
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_304 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Not Modified';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_400 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Bad Request';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_401 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Unauthorized';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_402 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Payment Required';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_403 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Forbidden';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_404 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Not Found';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_405 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Method Not Allowed';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_406 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Not Acceptable';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_407 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Proxy Authentication Required';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_408 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Request Timeout';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_409 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Conflict';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_410 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Gone';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_411 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Length Required';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_412 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Precondition Failed';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_413 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Request Entity Too Large';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_414 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Request-URI Too Large';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_415 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Unsupported Media Type';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_416 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Requested Range Not Satisfiable';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_417 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Expectation Failed';
}
}

View File

@ -26,4 +26,4 @@ class Requests_Exception_HTTP_418 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = "I'm A Teapot";
}
}

View File

@ -26,4 +26,4 @@ class Requests_Exception_HTTP_428 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Precondition Required';
}
}

View File

@ -26,4 +26,4 @@ class Requests_Exception_HTTP_429 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Too Many Requests';
}
}

View File

@ -26,4 +26,4 @@ class Requests_Exception_HTTP_431 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Request Header Fields Too Large';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_500 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Internal Server Error';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_501 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Not Implemented';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_502 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Bad Gateway';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_503 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Service Unavailable';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_504 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Gateway Timeout';
}
}

View File

@ -24,4 +24,4 @@ class Requests_Exception_HTTP_505 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'HTTP Version Not Supported';
}
}

View File

@ -26,4 +26,4 @@ class Requests_Exception_HTTP_511 extends Requests_Exception_HTTP {
* @var string
*/
protected $reason = 'Network Authentication Required';
}
}

View File

@ -41,4 +41,4 @@ class Requests_Exception_HTTP_Unknown extends Requests_Exception_HTTP {
parent::__construct($reason, $data);
}
}
}

View File

@ -2,7 +2,7 @@
class Requests_Exception_Transport_cURL extends Requests_Exception_Transport {
const EASY = 'cURLEasy';
const EASY = 'cURLEasy';
const MULTI = 'cURLMulti';
const SHARE = 'cURLShare';

View File

@ -30,4 +30,4 @@ interface Requests_Hooker {
* @return boolean Successfulness
*/
public function dispatch($hook, $parameters = array());
}
}

View File

@ -65,4 +65,4 @@ class Requests_Hooks implements Requests_Hooker {
return true;
}
}
}

View File

@ -141,31 +141,32 @@ class Requests_IDNAEncoder {
// Get number of bytes
$strlen = strlen($input);
// phpcs:ignore Generic.CodeAnalysis.JumbledIncrementer -- This is a deliberate choice.
for ($position = 0; $position < $strlen; $position++) {
$value = ord($input[$position]);
// One byte sequence:
if ((~$value & 0x80) === 0x80) {
$character = $value;
$length = 1;
$length = 1;
$remaining = 0;
}
// Two byte sequence:
elseif (($value & 0xE0) === 0xC0) {
$character = ($value & 0x1F) << 6;
$length = 2;
$length = 2;
$remaining = 1;
}
// Three byte sequence:
elseif (($value & 0xF0) === 0xE0) {
$character = ($value & 0x0F) << 12;
$length = 3;
$length = 3;
$remaining = 2;
}
// Four byte sequence:
elseif (($value & 0xF8) === 0xF0) {
$character = ($value & 0x07) << 18;
$length = 4;
$length = 4;
$remaining = 3;
}
// Invalid byte:
@ -185,14 +186,14 @@ class Requests_IDNAEncoder {
throw new Requests_Exception('Invalid Unicode codepoint', 'idna.invalidcodepoint', $character);
}
$character |= ($value & 0x3F) << (--$remaining * 6);
--$remaining;
$character |= ($value & 0x3F) << ($remaining * 6);
}
$position--;
}
if (
// Non-shortest form sequences are invalid
$length > 1 && $character <= 0x7F
if (// Non-shortest form sequences are invalid
$length > 1 && $character <= 0x7F
|| $length > 2 && $character <= 0x7FF
|| $length > 3 && $character <= 0xFFFF
// Outside of range of ucschar codepoints
@ -201,7 +202,7 @@ class Requests_IDNAEncoder {
|| $character >= 0xFDD0 && $character <= 0xFDEF
|| (
// Everything else not in ucschar
$character > 0xD7FF && $character < 0xF900
$character > 0xD7FF && $character < 0xF900
|| $character < 0x20
|| $character > 0x7E && $character < 0xA0
|| $character > 0xEFFFD
@ -227,17 +228,18 @@ class Requests_IDNAEncoder {
*/
public static function punycode_encode($input) {
$output = '';
# let n = initial_n
// let n = initial_n
$n = self::BOOTSTRAP_INITIAL_N;
# let delta = 0
// let delta = 0
$delta = 0;
# let bias = initial_bias
// let bias = initial_bias
$bias = self::BOOTSTRAP_INITIAL_BIAS;
# let h = b = the number of basic code points in the input
$h = $b = 0; // see loop
# copy them to the output in order
// let h = b = the number of basic code points in the input
$h = 0;
$b = 0; // see loop
// copy them to the output in order
$codepoints = self::utf8_to_codepoints($input);
$extended = array();
$extended = array();
foreach ($codepoints as $char) {
if ($char < 128) {
@ -260,35 +262,36 @@ class Requests_IDNAEncoder {
$extended = array_keys($extended);
sort($extended);
$b = $h;
# [copy them] followed by a delimiter if b > 0
// [copy them] followed by a delimiter if b > 0
if (strlen($output) > 0) {
$output .= '-';
}
# {if the input contains a non-basic code point < n then fail}
# while h < length(input) do begin
while ($h < count($codepoints)) {
# let m = the minimum code point >= n in the input
// {if the input contains a non-basic code point < n then fail}
// while h < length(input) do begin
$codepointcount = count($codepoints);
while ($h < $codepointcount) {
// let m = the minimum code point >= n in the input
$m = array_shift($extended);
//printf('next code point to insert is %s' . PHP_EOL, dechex($m));
# let delta = delta + (m - n) * (h + 1), fail on overflow
// let delta = delta + (m - n) * (h + 1), fail on overflow
$delta += ($m - $n) * ($h + 1);
# let n = m
// let n = m
$n = $m;
# for each code point c in the input (in order) do begin
for ($num = 0; $num < count($codepoints); $num++) {
// for each code point c in the input (in order) do begin
for ($num = 0; $num < $codepointcount; $num++) {
$c = $codepoints[$num];
# if c < n then increment delta, fail on overflow
// if c < n then increment delta, fail on overflow
if ($c < $n) {
$delta++;
}
# if c == n then begin
// if c == n then begin
elseif ($c === $n) {
# let q = delta
// let q = delta
$q = $delta;
# for k = base to infinity in steps of base do begin
// for k = base to infinity in steps of base do begin
for ($k = self::BOOTSTRAP_BASE; ; $k += self::BOOTSTRAP_BASE) {
# let t = tmin if k <= bias {+ tmin}, or
# tmax if k >= bias + tmax, or k - bias otherwise
// let t = tmin if k <= bias {+ tmin}, or
// tmax if k >= bias + tmax, or k - bias otherwise
if ($k <= ($bias + self::BOOTSTRAP_TMIN)) {
$t = self::BOOTSTRAP_TMIN;
}
@ -298,34 +301,30 @@ class Requests_IDNAEncoder {
else {
$t = $k - $bias;
}
# if q < t then break
// if q < t then break
if ($q < $t) {
break;
}
# output the code point for digit t + ((q - t) mod (base - t))
$digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t));
// output the code point for digit t + ((q - t) mod (base - t))
$digit = $t + (($q - $t) % (self::BOOTSTRAP_BASE - $t));
$output .= self::digit_to_char($digit);
# let q = (q - t) div (base - t)
// let q = (q - t) div (base - t)
$q = floor(($q - $t) / (self::BOOTSTRAP_BASE - $t));
# end
}
# output the code point for digit q
} // end
// output the code point for digit q
$output .= self::digit_to_char($q);
# let bias = adapt(delta, h + 1, test h equals b?)
// let bias = adapt(delta, h + 1, test h equals b?)
$bias = self::adapt($delta, $h + 1, $h === $b);
# let delta = 0
// let delta = 0
$delta = 0;
# increment h
// increment h
$h++;
# end
}
# end
}
# increment delta and n
} // end
} // end
// increment delta and n
$delta++;
$n++;
# end
}
} // end
return $output;
}
@ -358,31 +357,31 @@ class Requests_IDNAEncoder {
* @param int $numpoints
* @param bool $firsttime
* @return int New bias
*
* function adapt(delta,numpoints,firsttime):
*/
protected static function adapt($delta, $numpoints, $firsttime) {
# function adapt(delta,numpoints,firsttime):
# if firsttime then let delta = delta div damp
// if firsttime then let delta = delta div damp
if ($firsttime) {
$delta = floor($delta / self::BOOTSTRAP_DAMP);
}
# else let delta = delta div 2
// else let delta = delta div 2
else {
$delta = floor($delta / 2);
}
# let delta = delta + (delta div numpoints)
// let delta = delta + (delta div numpoints)
$delta += floor($delta / $numpoints);
# let k = 0
// let k = 0
$k = 0;
# while delta > ((base - tmin) * tmax) div 2 do begin
// while delta > ((base - tmin) * tmax) div 2 do begin
$max = floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN) * self::BOOTSTRAP_TMAX) / 2);
while ($delta > $max) {
# let delta = delta div (base - tmin)
// let delta = delta div (base - tmin)
$delta = floor($delta / (self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN));
# let k = k + base
// let k = k + base
$k += self::BOOTSTRAP_BASE;
# end
}
# return k + (((base - tmin + 1) * delta) div (delta + skew))
} // end
// return k + (((base - tmin + 1) * delta) div (delta + skew))
return $k + floor(((self::BOOTSTRAP_BASE - self::BOOTSTRAP_TMIN + 1) * $delta) / ($delta + self::BOOTSTRAP_SKEW));
}
}
}

View File

@ -40,8 +40,8 @@ class Requests_IPv6 {
}
list($ip1, $ip2) = explode('::', $ip);
$c1 = ($ip1 === '') ? -1 : substr_count($ip1, ':');
$c2 = ($ip2 === '') ? -1 : substr_count($ip2, ':');
$c1 = ($ip1 === '') ? -1 : substr_count($ip1, ':');
$c2 = ($ip2 === '') ? -1 : substr_count($ip2, ':');
if (strpos($ip2, '.') !== false) {
$c2++;
@ -51,19 +51,19 @@ class Requests_IPv6 {
$ip = '0:0:0:0:0:0:0:0';
}
// ::xxx
else if ($c1 === -1) {
elseif ($c1 === -1) {
$fill = str_repeat('0:', 7 - $c2);
$ip = str_replace('::', $fill, $ip);
$ip = str_replace('::', $fill, $ip);
}
// xxx::
else if ($c2 === -1) {
elseif ($c2 === -1) {
$fill = str_repeat(':0', 7 - $c1);
$ip = str_replace('::', $fill, $ip);
$ip = str_replace('::', $fill, $ip);
}
// xxx::xxx
else {
$fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
$ip = str_replace('::', $fill, $ip);
$ip = str_replace('::', $fill, $ip);
}
return $ip;
}
@ -84,7 +84,7 @@ class Requests_IPv6 {
*/
public static function compress($ip) {
// Prepare the IP to be compressed
$ip = self::uncompress($ip);
$ip = self::uncompress($ip);
$ip_parts = self::split_v6_v4($ip);
// Replace all leading zeros
@ -126,7 +126,7 @@ class Requests_IPv6 {
*/
protected static function split_v6_v4($ip) {
if (strpos($ip, '.') !== false) {
$pos = strrpos($ip, ':');
$pos = strrpos($ip, ':');
$ipv6_part = substr($ip, 0, $pos);
$ipv4_part = substr($ip, $pos + 1);
return array($ipv6_part, $ipv4_part);
@ -145,10 +145,10 @@ class Requests_IPv6 {
* @return bool true if $ip is a valid IPv6 address
*/
public static function check_ipv6($ip) {
$ip = self::uncompress($ip);
$ip = self::uncompress($ip);
list($ipv6, $ipv4) = self::split_v6_v4($ip);
$ipv6 = explode(':', $ipv6);
$ipv4 = explode('.', $ipv4);
$ipv6 = explode(':', $ipv6);
$ipv4 = explode('.', $ipv4);
if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) {
foreach ($ipv6 as $ipv6_part) {
// The section can't be empty

View File

@ -67,28 +67,28 @@ class Requests_IRI {
/**
* Scheme
*
* @var string
* @var string|null
*/
protected $scheme = null;
/**
* User Information
*
* @var string
* @var string|null
*/
protected $iuserinfo = null;
/**
* ihost
*
* @var string
* @var string|null
*/
protected $ihost = null;
/**
* Port
*
* @var string
* @var string|null
*/
protected $port = null;
@ -102,12 +102,12 @@ class Requests_IRI {
/**
* iquery
*
* @var string
* @var string|null
*/
protected $iquery = null;
/**
* ifragment
* ifragment|null
*
* @var string
*/
@ -118,6 +118,8 @@ class Requests_IRI {
*
* Each key is the scheme, each value is an array with each key as the IRI
* part and value as the default value for that part.
*
* @var array
*/
protected $normalization = array(
'acap' => array(
@ -249,9 +251,9 @@ class Requests_IRI {
*
* Returns false if $base is not absolute, otherwise an IRI.
*
* @param IRI|string $base (Absolute) Base IRI
* @param IRI|string $relative Relative IRI
* @return IRI|false
* @param Requests_IRI|string $base (Absolute) Base IRI
* @param Requests_IRI|string $relative Relative IRI
* @return Requests_IRI|false
*/
public static function absolutize($base, $relative) {
if (!($relative instanceof Requests_IRI)) {
@ -419,7 +421,7 @@ class Requests_IRI {
*/
protected function replace_invalid_with_pct_encoding($string, $extra_chars, $iprivate = false) {
// Normalize as many pct-encoded sections as possible
$string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array(&$this, 'remove_iunreserved_percent_encoded'), $string);
$string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array($this, 'remove_iunreserved_percent_encoded'), $string);
// Replace invalid percent characters
$string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
@ -1010,7 +1012,7 @@ class Requests_IRI {
/**
* Get the complete IRI
*
* @return string
* @return string|false
*/
protected function get_iri() {
if (!$this->is_valid()) {
@ -1047,7 +1049,7 @@ class Requests_IRI {
/**
* Get the complete iauthority
*
* @return string
* @return string|null
*/
protected function get_iauthority() {
if ($this->iuserinfo === null && $this->ihost === null && $this->port === null) {

View File

@ -31,5 +31,5 @@ interface Requests_Proxy {
* @see Requests_Hooks::register
* @param Requests_Hooks $hooks Hook system
*/
public function register(Requests_Hooks &$hooks);
}
public function register(Requests_Hooks $hooks);
}

View File

@ -59,12 +59,12 @@ class Requests_Proxy_HTTP implements Requests_Proxy {
$this->proxy = $args;
}
elseif (is_array($args)) {
if (count($args) == 1) {
if (count($args) === 1) {
list($this->proxy) = $args;
}
elseif (count($args) == 3) {
elseif (count($args) === 3) {
list($this->proxy, $this->user, $this->pass) = $args;
$this->use_authentication = true;
$this->use_authentication = true;
}
else {
throw new Requests_Exception('Invalid number of arguments', 'proxyhttpbadargs');
@ -82,13 +82,13 @@ class Requests_Proxy_HTTP implements Requests_Proxy {
* @see fsockopen_header
* @param Requests_Hooks $hooks Hook system
*/
public function register(Requests_Hooks &$hooks) {
$hooks->register('curl.before_send', array(&$this, 'curl_before_send'));
public function register(Requests_Hooks $hooks) {
$hooks->register('curl.before_send', array($this, 'curl_before_send'));
$hooks->register('fsockopen.remote_socket', array(&$this, 'fsockopen_remote_socket'));
$hooks->register('fsockopen.remote_host_path', array(&$this, 'fsockopen_remote_host_path'));
$hooks->register('fsockopen.remote_socket', array($this, 'fsockopen_remote_socket'));
$hooks->register('fsockopen.remote_host_path', array($this, 'fsockopen_remote_host_path'));
if ($this->use_authentication) {
$hooks->register('fsockopen.after_headers', array(&$this, 'fsockopen_header'));
$hooks->register('fsockopen.after_headers', array($this, 'fsockopen_header'));
}
}
@ -148,4 +148,4 @@ class Requests_Proxy_HTTP implements Requests_Proxy {
public function get_auth_string() {
return $this->user . ':' . $this->pass;
}
}
}

View File

@ -51,6 +51,7 @@ class Requests_Response {
/**
* Protocol version, false if non-blocking
*
* @var float|boolean
*/
public $protocol_version = false;
@ -97,7 +98,7 @@ class Requests_Response {
*/
public function is_redirect() {
$code = $this->status_code;
return in_array($code, array(300, 301, 302, 303, 307)) || $code > 307 && $code < 400;
return in_array($code, array(300, 301, 302, 303, 307), true) || $code > 307 && $code < 400;
}
/**

View File

@ -21,7 +21,7 @@ class Requests_Response_Headers extends Requests_Utility_CaseInsensitiveDictiona
* Set-Cookie headers.
*
* @param string $key
* @return string Header value
* @return string|null Header value
*/
public function offsetGet($key) {
$key = strtolower($key);
@ -58,7 +58,7 @@ class Requests_Response_Headers extends Requests_Utility_CaseInsensitiveDictiona
* Get all values for a given header
*
* @param string $key
* @return array Header values
* @return array|null Header values
*/
public function getValues($key) {
$key = strtolower($key);

View File

@ -20,7 +20,6 @@ class Requests_SSL {
*
* Unfortunately, PHP doesn't check the certificate against the alternative
* names, leading things like 'https://www.github.com/' to be invalid.
* Instead
*
* @see https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
*
@ -30,13 +29,6 @@ class Requests_SSL {
* @return bool
*/
public static function verify_certificate($host, $cert) {
// Calculate the valid wildcard match if the host is not an IP address
$parts = explode('.', $host);
if (ip2long($host) === false) {
$parts[0] = '*';
}
$wildcard = implode('.', $parts);
$has_dns_alt = false;
// Check the subjectAltName
@ -139,7 +131,7 @@ class Requests_SSL {
// Also validates that the host has 3 parts or more, as per Firefox's
// ruleset.
if (ip2long($host) === false) {
$parts = explode('.', $host);
$parts = explode('.', $host);
$parts[0] = '*';
$wildcard = implode('.', $parts);
if ($wildcard === $reference) {

View File

@ -22,12 +22,14 @@ class Requests_Session {
* Base URL for requests
*
* URLs will be made absolute using this as the base
*
* @var string|null
*/
public $url = null;
/**
* Base headers for requests
*
* @var array
*/
public $headers = array();
@ -64,9 +66,9 @@ class Requests_Session {
* @param array $options Default options for requests
*/
public function __construct($url = null, $headers = array(), $data = array(), $options = array()) {
$this->url = $url;
$this->url = $url;
$this->headers = $headers;
$this->data = $data;
$this->data = $data;
$this->options = $options;
if (empty($this->options['cookies'])) {

View File

@ -38,4 +38,4 @@ interface Requests_Transport {
* @return bool
*/
public static function test();
}
}

View File

@ -38,9 +38,9 @@ class Requests_Transport_cURL implements Requests_Transport {
public $info;
/**
* Version string
* cURL version number
*
* @var long
* @var int
*/
public $version;
@ -90,9 +90,9 @@ class Requests_Transport_cURL implements Requests_Transport {
* Constructor
*/
public function __construct() {
$curl = curl_version();
$curl = curl_version();
$this->version = $curl['version_number'];
$this->handle = curl_init();
$this->handle = curl_init();
curl_setopt($this->handle, CURLOPT_HEADER, false);
curl_setopt($this->handle, CURLOPT_RETURNTRANSFER, 1);
@ -100,9 +100,11 @@ class Requests_Transport_cURL implements Requests_Transport {
curl_setopt($this->handle, CURLOPT_ENCODING, '');
}
if (defined('CURLOPT_PROTOCOLS')) {
// phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_protocolsFound
curl_setopt($this->handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
}
if (defined('CURLOPT_REDIR_PROTOCOLS')) {
// phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_redir_protocolsFound
curl_setopt($this->handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
}
}
@ -138,8 +140,8 @@ class Requests_Transport_cURL implements Requests_Transport {
$this->stream_handle = fopen($options['filename'], 'wb');
}
$this->response_data = '';
$this->response_bytes = 0;
$this->response_data = '';
$this->response_bytes = 0;
$this->response_byte_limit = false;
if ($options['max_bytes'] !== false) {
$this->response_byte_limit = $options['max_bytes'];
@ -168,7 +170,7 @@ class Requests_Transport_cURL implements Requests_Transport {
// Reset encoding and try again
curl_setopt($this->handle, CURLOPT_ENCODING, 'none');
$this->response_data = '';
$this->response_data = '';
$this->response_bytes = 0;
curl_exec($this->handle);
$response = $this->response_data;
@ -199,23 +201,24 @@ class Requests_Transport_cURL implements Requests_Transport {
$multihandle = curl_multi_init();
$subrequests = array();
$subhandles = array();
$subhandles = array();
$class = get_class($this);
foreach ($requests as $id => $request) {
$subrequests[$id] = new $class();
$subhandles[$id] = $subrequests[$id]->get_subrequest_handle($request['url'], $request['headers'], $request['data'], $request['options']);
$subhandles[$id] = $subrequests[$id]->get_subrequest_handle($request['url'], $request['headers'], $request['data'], $request['options']);
$request['options']['hooks']->dispatch('curl.before_multi_add', array(&$subhandles[$id]));
curl_multi_add_handle($multihandle, $subhandles[$id]);
}
$completed = 0;
$responses = array();
$completed = 0;
$responses = array();
$subrequestcount = count($subrequests);
$request['options']['hooks']->dispatch('curl.before_multi_exec', array(&$multihandle));
do {
$active = false;
$active = 0;
do {
$status = curl_multi_exec($multihandle, $active);
@ -235,15 +238,15 @@ class Requests_Transport_cURL implements Requests_Transport {
// Parse the finished requests before we start getting the new ones
foreach ($to_process as $key => $done) {
$options = $requests[$key]['options'];
if (CURLE_OK !== $done['result']) {
if ($done['result'] !== CURLE_OK) {
//get error string for handle.
$reason = curl_error($done['handle']);
$exception = new Requests_Exception_Transport_cURL(
$reason,
Requests_Exception_Transport_cURL::EASY,
$done['handle'],
$done['result']
);
$reason = curl_error($done['handle']);
$exception = new Requests_Exception_Transport_cURL(
$reason,
Requests_Exception_Transport_cURL::EASY,
$done['handle'],
$done['result']
);
$responses[$key] = $exception;
$options['hooks']->dispatch('transport.internal.parse_error', array(&$responses[$key], $requests[$key]));
}
@ -262,7 +265,7 @@ class Requests_Transport_cURL implements Requests_Transport {
$completed++;
}
}
while ($active || $completed < count($subrequests));
while ($active || $completed < $subrequestcount);
$request['options']['hooks']->dispatch('curl.after_multi_exec', array(&$multihandle));
@ -287,8 +290,8 @@ class Requests_Transport_cURL implements Requests_Transport {
$this->stream_handle = fopen($options['filename'], 'wb');
}
$this->response_data = '';
$this->response_bytes = 0;
$this->response_data = '';
$this->response_bytes = 0;
$this->response_byte_limit = false;
if ($options['max_bytes'] !== false) {
$this->response_byte_limit = $options['max_bytes'];
@ -310,17 +313,32 @@ class Requests_Transport_cURL implements Requests_Transport {
$options['hooks']->dispatch('curl.before_request', array(&$this->handle));
// Force closing the connection for old versions of cURL (<7.22).
if ( ! isset( $headers['Connection'] ) ) {
if (!isset($headers['Connection'])) {
$headers['Connection'] = 'close';
}
/**
* Add "Expect" header.
*
* By default, cURL adds a "Expect: 100-Continue" to most requests. This header can
* add as much as a second to the time it takes for cURL to perform a request. To
* prevent this, we need to set an empty "Expect" header. To match the behaviour of
* Guzzle, we'll add the empty header to requests that are smaller than 1 MB and use
* HTTP/1.1.
*
* https://curl.se/mail/lib-2017-07/0013.html
*/
if (!isset($headers['Expect']) && $options['protocol_version'] === 1.1) {
$headers['Expect'] = $this->get_expect_header($data);
}
$headers = Requests::flatten($headers);
if (!empty($data)) {
$data_format = $options['data_format'];
if ($data_format === 'query') {
$url = self::format_get($url, $data);
$url = self::format_get($url, $data);
$data = '';
}
elseif (!is_string($data)) {
@ -363,6 +381,7 @@ class Requests_Transport_cURL implements Requests_Transport {
curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($timeout));
}
else {
// phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_timeout_msFound
curl_setopt($this->handle, CURLOPT_TIMEOUT_MS, round($timeout * 1000));
}
@ -370,6 +389,7 @@ class Requests_Transport_cURL implements Requests_Transport {
curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT, ceil($options['connect_timeout']));
}
else {
// phpcs:ignore PHPCompatibility.Constants.NewConstants.curlopt_connecttimeout_msFound
curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT_MS, round($options['connect_timeout'] * 1000));
}
curl_setopt($this->handle, CURLOPT_URL, $url);
@ -385,9 +405,9 @@ class Requests_Transport_cURL implements Requests_Transport {
curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
}
if (true === $options['blocking']) {
curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, array(&$this, 'stream_headers'));
curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, array(&$this, 'stream_body'));
if ($options['blocking'] === true) {
curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, array($this, 'stream_headers'));
curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, array($this, 'stream_body'));
curl_setopt($this->handle, CURLOPT_BUFFERSIZE, Requests::BUFFER_SIZE);
}
}
@ -397,7 +417,8 @@ class Requests_Transport_cURL implements Requests_Transport {
*
* @param string $response Response data from the body
* @param array $options Request options
* @return string HTTP response data including headers
* @return string|false HTTP response data including headers. False if non-blocking.
* @throws Requests_Exception
*/
public function process_response($response, $options) {
if ($options['blocking'] === false) {
@ -405,7 +426,7 @@ class Requests_Transport_cURL implements Requests_Transport {
$options['hooks']->dispatch('curl.after_request', array(&$fake_headers));
return false;
}
if ($options['filename'] !== false) {
if ($options['filename'] !== false && $this->stream_handle) {
fclose($this->stream_handle);
$this->headers = trim($this->headers);
}
@ -439,7 +460,7 @@ class Requests_Transport_cURL implements Requests_Transport {
// interim responses, such as a 100 Continue. We don't need that.
// (We may want to keep this somewhere just in case)
if ($this->done_headers) {
$this->headers = '';
$this->headers = '';
$this->done_headers = false;
}
$this->headers .= $headers;
@ -473,7 +494,7 @@ class Requests_Transport_cURL implements Requests_Transport {
if (($this->response_bytes + $data_length) > $this->response_byte_limit) {
// Limit the length
$limited_length = ($this->response_byte_limit - $this->response_bytes);
$data = substr($data, 0, $limited_length);
$data = substr($data, 0, $limited_length);
}
}
@ -497,16 +518,17 @@ class Requests_Transport_cURL implements Requests_Transport {
*/
protected static function format_get($url, $data) {
if (!empty($data)) {
$query = '';
$url_parts = parse_url($url);
if (empty($url_parts['query'])) {
$query = $url_parts['query'] = '';
$url_parts['query'] = '';
}
else {
$query = $url_parts['query'];
}
$query .= '&' . http_build_query($data, null, '&');
$query = trim($query, '&');
$query = trim($query, '&');
if (empty($url_parts['query'])) {
$url .= '?' . $query;
@ -539,4 +561,29 @@ class Requests_Transport_cURL implements Requests_Transport {
return true;
}
/**
* Get the correct "Expect" header for the given request data.
*
* @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD.
* @return string The "Expect" header.
*/
protected function get_expect_header($data) {
if (!is_array($data)) {
return strlen((string) $data) >= 1048576 ? '100-Continue' : '';
}
$bytesize = 0;
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($data));
foreach ($iterator as $datum) {
$bytesize += strlen((string) $datum);
if ($bytesize >= 1048576) {
return '100-Continue';
}
}
return '';
}
}

View File

@ -62,9 +62,9 @@ class Requests_Transport_fsockopen implements Requests_Transport {
if (empty($url_parts)) {
throw new Requests_Exception('Invalid URL.', 'invalidurl', $url);
}
$host = $url_parts['host'];
$context = stream_context_create();
$verifyname = false;
$host = $url_parts['host'];
$context = stream_context_create();
$verifyname = false;
$case_insensitive_headers = new Requests_Utility_CaseInsensitiveDictionary($headers);
// HTTPS support
@ -75,13 +75,13 @@ class Requests_Transport_fsockopen implements Requests_Transport {
}
$context_options = array(
'verify_peer' => true,
// 'CN_match' => $host,
'capture_peer_cert' => true
'verify_peer' => true,
'capture_peer_cert' => true,
);
$verifyname = true;
$verifyname = true;
// SNI, if enabled (OpenSSL >=0.9.8j)
// phpcs:ignore PHPCompatibility.Constants.NewConstants.openssl_tlsext_server_nameFound
if (defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME) {
$context_options['SNI_enabled'] = true;
if (isset($options['verifyname']) && $options['verifyname'] === false) {
@ -91,7 +91,9 @@ class Requests_Transport_fsockopen implements Requests_Transport {
if (isset($options['verify'])) {
if ($options['verify'] === false) {
$context_options['verify_peer'] = false;
$context_options['verify_peer'] = false;
$context_options['verify_peer_name'] = false;
$verifyname = false;
}
elseif (is_string($options['verify'])) {
$context_options['cafile'] = $options['verify'];
@ -100,7 +102,7 @@ class Requests_Transport_fsockopen implements Requests_Transport {
if (isset($options['verifyname']) && $options['verifyname'] === false) {
$context_options['verify_peer_name'] = false;
$verifyname = false;
$verifyname = false;
}
stream_context_set_option($context, array('ssl' => $context_options));
@ -116,6 +118,7 @@ class Requests_Transport_fsockopen implements Requests_Transport {
}
$remote_socket .= ':' . $url_parts['port'];
// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler
set_error_handler(array($this, 'connect_error_handler'), E_WARNING | E_NOTICE);
$options['hooks']->dispatch('fsockopen.remote_socket', array(&$remote_socket));
@ -150,17 +153,19 @@ class Requests_Transport_fsockopen implements Requests_Transport {
$options['hooks']->dispatch('fsockopen.remote_host_path', array(&$path, $url));
$request_body = '';
$out = sprintf("%s %s HTTP/%.1F\r\n", $options['type'], $path, $options['protocol_version']);
$out = sprintf("%s %s HTTP/%.1F\r\n", $options['type'], $path, $options['protocol_version']);
if ($options['type'] !== Requests::TRACE) {
if (is_array($data)) {
$request_body = http_build_query($data, null, '&');
$request_body = http_build_query($data, '', '&');
}
else {
$request_body = $data;
}
if (!empty($data)) {
// Always include Content-length on POST requests to prevent
// 411 errors from some servers when the body is empty.
if (!empty($data) || $options['type'] === Requests::POST) {
if (!isset($case_insensitive_headers['Content-Length'])) {
$headers['Content-Length'] = strlen($request_body);
}
@ -174,7 +179,7 @@ class Requests_Transport_fsockopen implements Requests_Transport {
if (!isset($case_insensitive_headers['Host'])) {
$out .= sprintf('Host: %s', $url_parts['host']);
if (( 'http' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 80 ) || ( 'https' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 443 )) {
if ((strtolower($url_parts['scheme']) === 'http' && $url_parts['port'] !== 80) || (strtolower($url_parts['scheme']) === 'https' && $url_parts['port'] !== 443)) {
$out .= ':' . $url_parts['port'];
}
$out .= "\r\n";
@ -220,7 +225,7 @@ class Requests_Transport_fsockopen implements Requests_Transport {
}
$timeout_sec = (int) floor($options['timeout']);
if ($timeout_sec == $options['timeout']) {
if ($timeout_sec === $options['timeout']) {
$timeout_msec = 0;
}
else {
@ -228,11 +233,13 @@ class Requests_Transport_fsockopen implements Requests_Transport {
}
stream_set_timeout($socket, $timeout_sec, $timeout_msec);
$response = $body = $headers = '';
$response = '';
$body = '';
$headers = '';
$this->info = stream_get_meta_data($socket);
$size = 0;
$doingbody = false;
$download = false;
$size = 0;
$doingbody = false;
$download = false;
if ($options['filename']) {
$download = fopen($options['filename'], 'wb');
}
@ -248,7 +255,7 @@ class Requests_Transport_fsockopen implements Requests_Transport {
$response .= $block;
if (strpos($response, "\r\n\r\n")) {
list($headers, $block) = explode("\r\n\r\n", $response, 2);
$doingbody = true;
$doingbody = true;
}
}
@ -264,7 +271,7 @@ class Requests_Transport_fsockopen implements Requests_Transport {
if (($size + $data_length) > $this->max_bytes) {
// Limit the length
$limited_length = ($this->max_bytes - $size);
$block = substr($block, 0, $limited_length);
$block = substr($block, 0, $limited_length);
}
}
@ -300,10 +307,10 @@ class Requests_Transport_fsockopen implements Requests_Transport {
*/
public function request_multiple($requests, $options) {
$responses = array();
$class = get_class($this);
$class = get_class($this);
foreach ($requests as $id => $request) {
try {
$handler = new $class();
$handler = new $class();
$responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
$request['options']['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$id], $request));
@ -353,8 +360,8 @@ class Requests_Transport_fsockopen implements Requests_Transport {
$url_parts['query'] = '';
}
$url_parts['query'] .= '&' . http_build_query($data, null, '&');
$url_parts['query'] = trim($url_parts['query'], '&');
$url_parts['query'] .= '&' . http_build_query($data, '', '&');
$url_parts['query'] = trim($url_parts['query'], '&');
}
if (isset($url_parts['path'])) {
if (isset($url_parts['query'])) {

View File

@ -46,7 +46,7 @@ class Requests_Utility_CaseInsensitiveDictionary implements ArrayAccess, Iterato
* Get the value for the item
*
* @param string $key Item key
* @return string Item value
* @return string|null Item value (null if offsetExists is false)
*/
public function offsetGet($key) {
$key = strtolower($key);
@ -70,7 +70,7 @@ class Requests_Utility_CaseInsensitiveDictionary implements ArrayAccess, Iterato
throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
}
$key = strtolower($key);
$key = strtolower($key);
$this->data[$key] = $value;
}

View File

@ -39,23 +39,27 @@ class Requests_Utility_FilteredIterator extends ArrayIterator {
*/
public function current() {
$value = parent::current();
$value = call_user_func($this->callback, $value);
if (is_callable($this->callback)) {
$value = call_user_func($this->callback, $value);
}
return $value;
}
/**
* @inheritdoc
*/
public function unserialize( $serialized ) {
}
public function unserialize($serialized) {}
/**
* @inheritdoc
*
* @phpcs:disable PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.MethodDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound
*/
public function __unserialize( $serialized ) { // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.MethodDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound
}
public function __unserialize($serialized) {}
public function __wakeup() { // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.ReservedFunctionNames.MethodDoubleUnderscore,PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__wakeupFound
unset( $this->callback );
public function __wakeup() {
unset($this->callback);
}
}

View File

@ -88,7 +88,7 @@ class Requests {
*
* @var string
*/
const VERSION = '1.7-3470169';
const VERSION = '1.7';
/**
* Registered transport classes
@ -143,7 +143,7 @@ class Requests {
$file = str_replace('_', '/', $class);
if (file_exists(dirname(__FILE__) . '/' . $file . '.php')) {
require_once(dirname(__FILE__) . '/' . $file . '.php');
require_once dirname(__FILE__) . '/' . $file . '.php';
}
}
@ -342,7 +342,7 @@ class Requests {
* across transports.)
* (string|boolean, default: library/Requests/Transport/cacert.pem)
* - `verifyname`: Should we verify the common name in the SSL certificate?
* (boolean: default, true)
* (boolean, default: true)
* - `data_format`: How should we send the `$data` parameter?
* (string, one of 'query' or 'body', default: 'query' for
* HEAD/GET/DELETE, 'body' for POST/PUT/OPTIONS/PATCH)
@ -374,9 +374,9 @@ class Requests {
}
}
else {
$need_ssl = (0 === stripos($url, 'https://'));
$need_ssl = (stripos($url, 'https://') === 0);
$capabilities = array('ssl' => $need_ssl);
$transport = self::get_transport($capabilities);
$transport = self::get_transport($capabilities);
}
$response = $transport->request($url, $headers, $data, $options);
@ -447,7 +447,7 @@ class Requests {
$request['type'] = self::GET;
}
if (!isset($request['options'])) {
$request['options'] = $options;
$request['options'] = $options;
$request['options']['type'] = $request['type'];
}
else {
@ -503,25 +503,25 @@ class Requests {
*/
protected static function get_default_options($multirequest = false) {
$defaults = array(
'timeout' => 10,
'connect_timeout' => 10,
'useragent' => 'php-requests/' . self::VERSION,
'timeout' => 10,
'connect_timeout' => 10,
'useragent' => 'php-requests/' . self::VERSION,
'protocol_version' => 1.1,
'redirected' => 0,
'redirects' => 10,
'redirected' => 0,
'redirects' => 10,
'follow_redirects' => true,
'blocking' => true,
'type' => self::GET,
'filename' => false,
'auth' => false,
'proxy' => false,
'cookies' => false,
'max_bytes' => false,
'idn' => true,
'hooks' => null,
'transport' => null,
'verify' => Requests::get_certificate_path(),
'verifyname' => true,
'blocking' => true,
'type' => self::GET,
'filename' => false,
'auth' => false,
'proxy' => false,
'cookies' => false,
'max_bytes' => false,
'idn' => true,
'hooks' => null,
'transport' => null,
'verify' => self::get_certificate_path(),
'verifyname' => true,
);
if ($multirequest !== false) {
$defaults['complete'] = null;
@ -535,8 +535,8 @@ class Requests {
* @return string Default certificate path.
*/
public static function get_certificate_path() {
if ( ! empty( Requests::$certificate_path ) ) {
return Requests::$certificate_path;
if (!empty(self::$certificate_path)) {
return self::$certificate_path;
}
return dirname(__FILE__) . '/Requests/Transport/cacert.pem';
@ -547,8 +547,8 @@ class Requests {
*
* @param string $path Certificate path, pointing to a PEM file.
*/
public static function set_certificate_path( $path ) {
Requests::$certificate_path = $path;
public static function set_certificate_path($path) {
self::$certificate_path = $path;
}
/**
@ -595,16 +595,16 @@ class Requests {
}
if ($options['idn'] !== false) {
$iri = new Requests_IRI($url);
$iri = new Requests_IRI($url);
$iri->host = Requests_IDNAEncoder::encode($iri->ihost);
$url = $iri->uri;
$url = $iri->uri;
}
// Massage the type to ensure we support it.
$type = strtoupper($type);
if (!isset($options['data_format'])) {
if (in_array($type, array(self::HEAD, self::GET, self::DELETE))) {
if (in_array($type, array(self::HEAD, self::GET, self::DELETE), true)) {
$options['data_format'] = 'query';
}
else {
@ -633,20 +633,23 @@ class Requests {
return $return;
}
$return->raw = $headers;
$return->url = $url;
$return->raw = $headers;
$return->url = (string) $url;
$return->body = '';
if (!$options['filename']) {
if (($pos = strpos($headers, "\r\n\r\n")) === false) {
$pos = strpos($headers, "\r\n\r\n");
if ($pos === false) {
// Crap!
throw new Requests_Exception('Missing header/body separator', 'requests.no_crlf_separator');
}
$headers = substr($return->raw, 0, $pos);
$return->body = substr($return->raw, $pos + strlen("\n\r\n\r"));
}
else {
$return->body = '';
// Headers will always be separated from the body by two new lines - `\n\r\n\r`.
$body = substr($return->raw, $pos + 4);
if (!empty($body)) {
$return->body = $body;
}
}
// Pretend CRLF = LF for compatibility (RFC 2616, section 19.3)
$headers = str_replace("\r\n", "\n", $headers);
@ -658,14 +661,14 @@ class Requests {
throw new Requests_Exception('Response could not be parsed', 'noversion', $headers);
}
$return->protocol_version = (float) $matches[1];
$return->status_code = (int) $matches[2];
$return->status_code = (int) $matches[2];
if ($return->status_code >= 200 && $return->status_code < 300) {
$return->success = true;
}
foreach ($headers as $header) {
list($key, $value) = explode(':', $header, 2);
$value = trim($value);
$value = trim($value);
preg_replace('#(\s+)#i', ' ', $value);
$return->headers[$key] = $value;
}
@ -702,10 +705,10 @@ class Requests {
&$req_headers,
&$req_data,
&$options,
$return
$return,
);
$options['hooks']->dispatch('requests.before_redirect', $hook_args);
$redirected = self::request($location, $req_headers, $req_data, $options['type'], $options);
$redirected = self::request($location, $req_headers, $req_data, $options['type'], $options);
$redirected->history[] = $return;
return $redirected;
}
@ -732,10 +735,10 @@ class Requests {
*/
public static function parse_multiple(&$response, $request) {
try {
$url = $request['url'];
$headers = $request['headers'];
$data = $request['data'];
$options = $request['options'];
$url = $request['url'];
$headers = $request['headers'];
$data = $request['data'];
$options = $request['options'];
$response = self::parse_response($response, $url, $headers, $data, $options);
}
catch (Requests_Exception $e) {
@ -755,8 +758,6 @@ class Requests {
return $data;
}
$decoded = '';
$encoded = $data;
@ -774,8 +775,8 @@ class Requests {
}
$chunk_length = strlen($matches[0]);
$decoded .= substr($encoded, $chunk_length, $length);
$encoded = substr($encoded, $chunk_length + $length + 2);
$decoded .= substr($encoded, $chunk_length, $length);
$encoded = substr($encoded, $chunk_length + $length + 2);
if (trim($encoded) === '0' || empty($encoded)) {
return $decoded;
@ -791,7 +792,7 @@ class Requests {
* Convert a key => value array to a 'key: value' array for headers
*
* @param array $array Dictionary of header values
* @return string[] List of headers
* @return array List of headers
*/
public static function flatten($array) {
$return = array();
@ -807,7 +808,7 @@ class Requests {
* @codeCoverageIgnore
* @deprecated Misspelling of {@see Requests::flatten}
* @param array $array Dictionary of header values
* @return string[] List of headers
* @return array List of headers
*/
public static function flattern($array) {
return self::flatten($array);
@ -828,17 +829,31 @@ class Requests {
return $data;
}
if (function_exists('gzdecode') && ($decoded = @gzdecode($data)) !== false) {
if (function_exists('gzdecode')) {
// phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.gzdecodeFound -- Wrapped in function_exists() for PHP 5.2.
$decoded = @gzdecode($data);
if ($decoded !== false) {
return $decoded;
}
}
if (function_exists('gzinflate')) {
$decoded = @gzinflate($data);
if ($decoded !== false) {
return $decoded;
}
}
$decoded = self::compatible_gzinflate($data);
if ($decoded !== false) {
return $decoded;
}
elseif (function_exists('gzinflate') && ($decoded = @gzinflate($data)) !== false) {
return $decoded;
}
elseif (($decoded = self::compatible_gzinflate($data)) !== false) {
return $decoded;
}
elseif (function_exists('gzuncompress') && ($decoded = @gzuncompress($data)) !== false) {
return $decoded;
if (function_exists('gzuncompress')) {
$decoded = @gzuncompress($data);
if ($decoded !== false) {
return $decoded;
}
}
return $data;
@ -861,32 +876,32 @@ class Requests {
* @link https://secure.php.net/manual/en/function.gzinflate.php#70875
* @link https://secure.php.net/manual/en/function.gzinflate.php#77336
*
* @param string $gzData String to decompress.
* @param string $gz_data String to decompress.
* @return string|bool False on failure.
*/
public static function compatible_gzinflate($gzData) {
public static function compatible_gzinflate($gz_data) {
// Compressed data might contain a full zlib header, if so strip it for
// gzinflate()
if (substr($gzData, 0, 3) == "\x1f\x8b\x08") {
$i = 10;
$flg = ord(substr($gzData, 3, 1));
if (substr($gz_data, 0, 3) === "\x1f\x8b\x08") {
$i = 10;
$flg = ord(substr($gz_data, 3, 1));
if ($flg > 0) {
if ($flg & 4) {
list($xlen) = unpack('v', substr($gzData, $i, 2));
$i = $i + 2 + $xlen;
list($xlen) = unpack('v', substr($gz_data, $i, 2));
$i += 2 + $xlen;
}
if ($flg & 8) {
$i = strpos($gzData, "\0", $i) + 1;
$i = strpos($gz_data, "\0", $i) + 1;
}
if ($flg & 16) {
$i = strpos($gzData, "\0", $i) + 1;
$i = strpos($gz_data, "\0", $i) + 1;
}
if ($flg & 2) {
$i = $i + 2;
$i += 2;
}
}
$decompressed = self::compatible_gzinflate(substr($gzData, $i));
if (false !== $decompressed) {
$decompressed = self::compatible_gzinflate(substr($gz_data, $i));
if ($decompressed !== false) {
return $decompressed;
}
}
@ -902,57 +917,61 @@ class Requests {
$huffman_encoded = false;
// low nibble of first byte should be 0x08
list(, $first_nibble) = unpack('h', $gzData);
list(, $first_nibble) = unpack('h', $gz_data);
// First 2 bytes should be divisible by 0x1F
list(, $first_two_bytes) = unpack('n', $gzData);
list(, $first_two_bytes) = unpack('n', $gz_data);
if (0x08 == $first_nibble && 0 == ($first_two_bytes % 0x1F)) {
if ($first_nibble === 0x08 && ($first_two_bytes % 0x1F) === 0) {
$huffman_encoded = true;
}
if ($huffman_encoded) {
if (false !== ($decompressed = @gzinflate(substr($gzData, 2)))) {
$decompressed = @gzinflate(substr($gz_data, 2));
if ($decompressed !== false) {
return $decompressed;
}
}
if ("\x50\x4b\x03\x04" == substr($gzData, 0, 4)) {
if (substr($gz_data, 0, 4) === "\x50\x4b\x03\x04") {
// ZIP file format header
// Offset 6: 2 bytes, General-purpose field
// Offset 26: 2 bytes, filename length
// Offset 28: 2 bytes, optional field length
// Offset 30: Filename field, followed by optional field, followed
// immediately by data
list(, $general_purpose_flag) = unpack('v', substr($gzData, 6, 2));
list(, $general_purpose_flag) = unpack('v', substr($gz_data, 6, 2));
// If the file has been compressed on the fly, 0x08 bit is set of
// the general purpose field. We can use this to differentiate
// between a compressed document, and a ZIP file
$zip_compressed_on_the_fly = (0x08 == (0x08 & $general_purpose_flag));
$zip_compressed_on_the_fly = ((0x08 & $general_purpose_flag) === 0x08);
if (!$zip_compressed_on_the_fly) {
// Don't attempt to decode a compressed zip file
return $gzData;
return $gz_data;
}
// Determine the first byte of data, based on the above ZIP header
// offsets:
$first_file_start = array_sum(unpack('v2', substr($gzData, 26, 4)));
if (false !== ($decompressed = @gzinflate(substr($gzData, 30 + $first_file_start)))) {
$first_file_start = array_sum(unpack('v2', substr($gz_data, 26, 4)));
$decompressed = @gzinflate(substr($gz_data, 30 + $first_file_start));
if ($decompressed !== false) {
return $decompressed;
}
return false;
}
// Finally fall back to straight gzinflate
if (false !== ($decompressed = @gzinflate($gzData))) {
$decompressed = @gzinflate($gz_data);
if ($decompressed !== false) {
return $decompressed;
}
// Fallback for all above failing, not expected, but included for
// debugging and preventing regressions and to track stats
if (false !== ($decompressed = @gzinflate(substr($gzData, 2)))) {
$decompressed = @gzinflate(substr($gz_data, 2));
if ($decompressed !== false) {
return $decompressed;
}

View File

@ -13,7 +13,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.8-alpha-50841';
$wp_version = '5.8-alpha-50842';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.