Make WordPress Core

Changeset 54997


Ignore:
Timestamp:
12/15/2022 09:30:26 PM (19 months ago)
Author:
hellofromTonya
Message:

External Libraries: Update Requests library to version 2.0.0.

This is a major release and contains breaking changes.

Most important changes to be aware of for this release:

  • All code is now namespaced. Though there is a full backward compatibility layer available and the old class names are still supported, using them will generate a deprecation notice (which can be silenced by plugins if they'd need to support multiple WP versions). See the upgrade guide for more details.
  • A lot of classes have been marked final. This should generally not affect userland code as care has been taken to not apply the final keyword to classes which are known to be extended in userland code.
  • Extensive input validation has been added to Requests. When Requests is used as documented though, this will be unnoticable.
  • A new WpOrg\Requests\Requests::has_capabilities() method has been introduced which can be used to address #37708.
  • A new WpOrg\Requests\Response::decode_body() method has been introduced which may be usable to simplify some of the WP native wrapper code.
  • Remaining PHP 8.0 compatibility fixed (support for named parameters).
  • PHP 8.1 compatibility.

Release notes: https://github.com/WordPress/Requests/releases/tag/v2.0.0

For a full list of changes in this update, see the Requests GitHub:
https://github.com/WordPress/Requests/compare/v1.8.1...v2.0.0

This commit also resolves 2 blocking issues which previously caused the revert of [52244]:

  • New Requests files are loaded into wp-includes/Requests/src/, matching the location of the library. In doing so, filesystems that are case-insensitive are not impacted (see #54582).
  • Preload: During a Core update, the old Requests files are preloaded into memory before the update deletes the files. Preloading avoids fatal errors noted in #54562.

Follow-up to [50842], [51078], [52244], [52315], [52327], [52328].

Props jrf, schlessera, datagutten, wojsmol, dustinrue, soulseekah, szepeviktor. costdev, sergeybiryukov, peterwilsoncc, ironprogrammer, antonvlasenko, hellofromTonya, swissspidy, dd32, azaozz, TobiasBg, audrasjb.
Fixes #54504.
See #54582, #54562.

Location:
trunk
Files:
74 added
20 deleted
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/update-core.php

    r54891 r54997  
    867867
    868868/**
     869 * Stores Requests files to be preloaded and deleted.
     870 *
     871 * For classes/interfaces, use the class/interface name
     872 * as the array key.
     873 *
     874 * All other files/directories should not have a key.
     875 *
     876 * @since 6.2.0
     877 *
     878 * @global array $_old_requests_files
     879 * @var array
     880 * @name $_old_requests_files
     881 */
     882global $_old_requests_files;
     883
     884$_old_requests_files = array(
     885    // Interfaces.
     886    'Requests_Auth'                              => 'wp-includes/Requests/Auth.php',
     887    'Requests_Hooker'                            => 'wp-includes/Requests/Hooker.php',
     888    'Requests_Proxy'                             => 'wp-includes/Requests/Proxy.php',
     889    'Requests_Transport'                         => 'wp-includes/Requests/Transport.php',
     890
     891    // Classes.
     892    'Requests_Auth_Basic'                        => 'wp-includes/Requests/Auth/Basic.php',
     893    'Requests_Cookie_Jar'                        => 'wp-includes/Requests/Cookie/Jar.php',
     894    'Requests_Exception_HTTP'                    => 'wp-includes/Requests/Exception/HTTP.php',
     895    'Requests_Exception_Transport'               => 'wp-includes/Requests/Exception/Transport.php',
     896    'Requests_Exception_HTTP_304'                => 'wp-includes/Requests/Exception/HTTP/304.php',
     897    'Requests_Exception_HTTP_305'                => 'wp-includes/Requests/Exception/HTTP/305.php',
     898    'Requests_Exception_HTTP_306'                => 'wp-includes/Requests/Exception/HTTP/306.php',
     899    'Requests_Exception_HTTP_400'                => 'wp-includes/Requests/Exception/HTTP/400.php',
     900    'Requests_Exception_HTTP_401'                => 'wp-includes/Requests/Exception/HTTP/401.php',
     901    'Requests_Exception_HTTP_402'                => 'wp-includes/Requests/Exception/HTTP/402.php',
     902    'Requests_Exception_HTTP_403'                => 'wp-includes/Requests/Exception/HTTP/403.php',
     903    'Requests_Exception_HTTP_404'                => 'wp-includes/Requests/Exception/HTTP/404.php',
     904    'Requests_Exception_HTTP_405'                => 'wp-includes/Requests/Exception/HTTP/405.php',
     905    'Requests_Exception_HTTP_406'                => 'wp-includes/Requests/Exception/HTTP/406.php',
     906    'Requests_Exception_HTTP_407'                => 'wp-includes/Requests/Exception/HTTP/407.php',
     907    'Requests_Exception_HTTP_408'                => 'wp-includes/Requests/Exception/HTTP/408.php',
     908    'Requests_Exception_HTTP_409'                => 'wp-includes/Requests/Exception/HTTP/409.php',
     909    'Requests_Exception_HTTP_410'                => 'wp-includes/Requests/Exception/HTTP/410.php',
     910    'Requests_Exception_HTTP_411'                => 'wp-includes/Requests/Exception/HTTP/411.php',
     911    'Requests_Exception_HTTP_412'                => 'wp-includes/Requests/Exception/HTTP/412.php',
     912    'Requests_Exception_HTTP_413'                => 'wp-includes/Requests/Exception/HTTP/413.php',
     913    'Requests_Exception_HTTP_414'                => 'wp-includes/Requests/Exception/HTTP/414.php',
     914    'Requests_Exception_HTTP_415'                => 'wp-includes/Requests/Exception/HTTP/415.php',
     915    'Requests_Exception_HTTP_416'                => 'wp-includes/Requests/Exception/HTTP/416.php',
     916    'Requests_Exception_HTTP_417'                => 'wp-includes/Requests/Exception/HTTP/417.php',
     917    'Requests_Exception_HTTP_418'                => 'wp-includes/Requests/Exception/HTTP/418.php',
     918    'Requests_Exception_HTTP_428'                => 'wp-includes/Requests/Exception/HTTP/428.php',
     919    'Requests_Exception_HTTP_429'                => 'wp-includes/Requests/Exception/HTTP/429.php',
     920    'Requests_Exception_HTTP_431'                => 'wp-includes/Requests/Exception/HTTP/431.php',
     921    'Requests_Exception_HTTP_500'                => 'wp-includes/Requests/Exception/HTTP/500.php',
     922    'Requests_Exception_HTTP_501'                => 'wp-includes/Requests/Exception/HTTP/501.php',
     923    'Requests_Exception_HTTP_502'                => 'wp-includes/Requests/Exception/HTTP/502.php',
     924    'Requests_Exception_HTTP_503'                => 'wp-includes/Requests/Exception/HTTP/503.php',
     925    'Requests_Exception_HTTP_504'                => 'wp-includes/Requests/Exception/HTTP/504.php',
     926    'Requests_Exception_HTTP_505'                => 'wp-includes/Requests/Exception/HTTP/505.php',
     927    'Requests_Exception_HTTP_511'                => 'wp-includes/Requests/Exception/HTTP/511.php',
     928    'Requests_Exception_HTTP_Unknown'            => 'wp-includes/Requests/Exception/HTTP/Unknown.php',
     929    'Requests_Exception_Transport_cURL'          => 'wp-includes/Requests/Exception/Transport/cURL.php',
     930    'Requests_Proxy_HTTP'                        => 'wp-includes/Requests/Proxy/HTTP.php',
     931    'Requests_Response_Headers'                  => 'wp-includes/Requests/Response/Headers.php',
     932    'Requests_Transport_cURL'                    => 'wp-includes/Requests/Transport/cURL.php',
     933    'Requests_Transport_fsockopen'               => 'wp-includes/Requests/Transport/fsockopen.php',
     934    'Requests_Utility_CaseInsensitiveDictionary' => 'wp-includes/Requests/Utility/CaseInsensitiveDictionary.php',
     935    'Requests_Utility_FilteredIterator'          => 'wp-includes/Requests/Utility/FilteredIterator.php',
     936    'Requests_Cookie'                            => 'wp-includes/Requests/Cookie.php',
     937    'Requests_Exception'                         => 'wp-includes/Requests/Exception.php',
     938    'Requests_Hooks'                             => 'wp-includes/Requests/Hooks.php',
     939    'Requests_IDNAEncoder'                       => 'wp-includes/Requests/IDNAEncoder.php',
     940    'Requests_IPv6'                              => 'wp-includes/Requests/IPv6.php',
     941    'Requests_IRI'                               => 'wp-includes/Requests/IRI.php',
     942    'Requests_Response'                          => 'wp-includes/Requests/Response.php',
     943    'Requests_SSL'                               => 'wp-includes/Requests/SSL.php',
     944    'Requests_Session'                           => 'wp-includes/Requests/Session.php',
     945
     946    // Directories.
     947    'wp-includes/Requests/Auth/',
     948    'wp-includes/Requests/Cookie/',
     949    'wp-includes/Requests/Exception/HTTP/',
     950    'wp-includes/Requests/Exception/Transport/',
     951    'wp-includes/Requests/Exception/',
     952    'wp-includes/Requests/Proxy/',
     953    'wp-includes/Requests/Response/',
     954    'wp-includes/Requests/Transport/',
     955    'wp-includes/Requests/Utility/',
     956);
     957
     958/**
    869959 * Stores new files in wp-content to copy
    870960 *
     
    9501040 * @global WP_Filesystem_Base $wp_filesystem          WordPress filesystem subclass.
    9511041 * @global array              $_old_files
     1042 * @global array              $_old_requests_files
    9521043 * @global array              $_new_bundled_files
    9531044 * @global wpdb               $wpdb                   WordPress database abstraction object.
     
    9611052 */
    9621053function update_core( $from, $to ) {
    963     global $wp_filesystem, $_old_files, $_new_bundled_files, $wpdb;
     1054    global $wp_filesystem, $_old_files, $_old_requests_files, $_new_bundled_files, $wpdb;
    9641055
    9651056    set_time_limit( 300 );
     1057
     1058    /*
     1059     * Merge the old Requests files and directories into the `$_old_files`.
     1060     * Then preload these Requests files first, before the files are deleted
     1061     * and replaced to ensure the code is in memory if needed.
     1062     */
     1063    $_old_files = array_merge( $_old_files, array_values( $_old_requests_files ) );
     1064    _preload_old_requests_classes_and_interfaces( $to );
    9661065
    9671066    /**
     
    14801579
    14811580/**
     1581 * Preloads old Requests classes and interfaces.
     1582 *
     1583 * This function preloads the old Requests code into memory before the
     1584 * upgrade process deletes the files. Why? Requests code is loaded into
     1585 * memory via an autoloader, meaning when a class or interface is needed
     1586 * If a request is in process, Requests could attempt to access code. If
     1587 * the file is not there, a fatal error could occur. If the file was
     1588 * replaced, the new code is not compatible with the old, resulting in
     1589 * a fatal error. Preloading ensures the code is in memory before the
     1590 * code is updated.
     1591 *
     1592 * @since 6.2.0
     1593 *
     1594 * @global array              $_old_requests_files Requests files to be preloaded.
     1595 * @global WP_Filesystem_Base $wp_filesystem       WordPress filesystem subclass.
     1596 *
     1597 * @param string $to Path to old WordPress installation.
     1598 */
     1599function _preload_old_requests_classes_and_interfaces( $to ) {
     1600    global $_old_requests_files, $wp_filesystem;
     1601
     1602    foreach ( $_old_requests_files as $name => $file ) {
     1603        // Skip files that aren't interfaces or classes.
     1604        if ( is_int( $name ) ) {
     1605            continue;
     1606        }
     1607
     1608        // Skip if it's already loaded.
     1609        if ( class_exists( $name ) || interface_exists( $name ) ) {
     1610            continue;
     1611        }
     1612
     1613        // Skip if the file is missing.
     1614        if ( ! $wp_filesystem->is_file( $to . $file ) ) {
     1615            continue;
     1616        }
     1617
     1618        require_once $to . $file;
     1619    }
     1620}
     1621
     1622/**
    14821623 * Redirect to the About WordPress page after a successful upgrade.
    14831624 *
  • trunk/src/wp-includes/class-requests.php

    r52328 r54997  
    88 *
    99 * @package Requests
     10 *
     11 * @deprecated 6.2.0
    1012 */
     13
     14/*
     15 * Integrators who cannot yet upgrade to the PSR-4 class names can silence deprecations
     16 * by defining a `REQUESTS_SILENCE_PSR0_DEPRECATIONS` constant and setting it to `true`.
     17 * The constant needs to be defined before this class is required.
     18 */
     19if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS') || REQUESTS_SILENCE_PSR0_DEPRECATIONS !== true) {
     20    // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_trigger_error
     21    trigger_error(
     22        'The PSR-0 `Requests_...` class names in the Request library are deprecated.'
     23        . ' Switch to the PSR-4 `WpOrg\Requests\...` class names at your earliest convenience.',
     24        E_USER_DEPRECATED
     25    );
     26
     27    // Prevent the deprecation notice from being thrown twice.
     28    if (!defined('REQUESTS_SILENCE_PSR0_DEPRECATIONS')) {
     29        define('REQUESTS_SILENCE_PSR0_DEPRECATIONS', true);
     30    }
     31}
     32
     33require_once __DIR__ . '/Requests/src/Requests.php';
    1134
    1235/**
     
    1841 *
    1942 * @package Requests
     43 *
     44 * @deprecated 6.2.0 Use `WpOrg\Requests\Requests` instead for the actual functionality and
     45 *                   use `WpOrg\Requests\Autoload` for the autoloading.
    2046 */
    21 class Requests {
    22     /**
    23      * POST method
    24      *
    25      * @var string
    26      */
    27     const POST = 'POST';
     47class Requests extends WpOrg\Requests\Requests {
    2848
    2949    /**
    30      * PUT method
     50     * Deprecated autoloader for Requests.
    3151     *
    32      * @var string
    33      */
    34     const PUT = 'PUT';
    35 
    36     /**
    37      * GET method
    38      *
    39      * @var string
    40      */
    41     const GET = 'GET';
    42 
    43     /**
    44      * HEAD method
    45      *
    46      * @var string
    47      */
    48     const HEAD = 'HEAD';
    49 
    50     /**
    51      * DELETE method
    52      *
    53      * @var string
    54      */
    55     const DELETE = 'DELETE';
    56 
    57     /**
    58      * OPTIONS method
    59      *
    60      * @var string
    61      */
    62     const OPTIONS = 'OPTIONS';
    63 
    64     /**
    65      * TRACE method
    66      *
    67      * @var string
    68      */
    69     const TRACE = 'TRACE';
    70 
    71     /**
    72      * PATCH method
    73      *
    74      * @link https://tools.ietf.org/html/rfc5789
    75      * @var string
    76      */
    77     const PATCH = 'PATCH';
    78 
    79     /**
    80      * Default size of buffer size to read streams
    81      *
    82      * @var integer
    83      */
    84     const BUFFER_SIZE = 1160;
    85 
    86     /**
    87      * Current version of Requests
    88      *
    89      * @var string
    90      */
    91     const VERSION = '1.8.1';
    92 
    93     /**
    94      * Registered transport classes
    95      *
    96      * @var array
    97      */
    98     protected static $transports = array();
    99 
    100     /**
    101      * Selected transport name
    102      *
    103      * Use {@see get_transport()} instead
    104      *
    105      * @var array
    106      */
    107     public static $transport = array();
    108 
    109     /**
    110      * Default certificate path.
    111      *
    112      * @see Requests::get_certificate_path()
    113      * @see Requests::set_certificate_path()
    114      *
    115      * @var string
    116      */
    117     protected static $certificate_path;
    118 
    119     /**
    120      * This is a static class, do not instantiate it
    121      *
    122      * @codeCoverageIgnore
    123      */
    124     private function __construct() {}
    125 
    126     /**
    127      * Autoloader for Requests
    128      *
    129      * Register this with {@see register_autoloader()} if you'd like to avoid
    130      * having to create your own.
    131      *
    132      * (You can also use `spl_autoload_register` directly if you'd prefer.)
     52     * @deprecated 6.2.0 Use the `WpOrg\Requests\Autoload::load()` method instead.
    13353     *
    13454     * @codeCoverageIgnore
     
    13757     */
    13858    public static function autoloader($class) {
    139         // Check that the class starts with "Requests"
    140         if (strpos($class, 'Requests') !== 0) {
    141             return;
     59        if (class_exists('WpOrg\Requests\Autoload') === false) {
     60            require_once __DIR__ . '/Requests/src/Autoload.php';
    14261        }
    14362
    144         $file = str_replace('_', '/', $class);
    145         if (file_exists(dirname(__FILE__) . '/' . $file . '.php')) {
    146             require_once dirname(__FILE__) . '/' . $file . '.php';
    147         }
     63        return WpOrg\Requests\Autoload::load($class);
    14864    }
    14965
     
    15167     * Register the built-in autoloader
    15268     *
     69     * @deprecated 6.2.0 Include the `WpOrg\Requests\Autoload` class and
     70     *                   call `WpOrg\Requests\Autoload::register()` instead.
     71     *
    15372     * @codeCoverageIgnore
    15473     */
    15574    public static function register_autoloader() {
    156         spl_autoload_register(array('Requests', 'autoloader'));
    157     }
    158 
    159     /**
    160      * Register a transport
    161      *
    162      * @param string $transport Transport class to add, must support the Requests_Transport interface
    163      */
    164     public static function add_transport($transport) {
    165         if (empty(self::$transports)) {
    166             self::$transports = array(
    167                 'Requests_Transport_cURL',
    168                 'Requests_Transport_fsockopen',
    169             );
    170         }
    171 
    172         self::$transports = array_merge(self::$transports, array($transport));
    173     }
    174 
    175     /**
    176      * Get a working transport
    177      *
    178      * @throws Requests_Exception If no valid transport is found (`notransport`)
    179      * @return Requests_Transport
    180      */
    181     protected static function get_transport($capabilities = array()) {
    182         // Caching code, don't bother testing coverage
    183         // @codeCoverageIgnoreStart
    184         // array of capabilities as a string to be used as an array key
    185         ksort($capabilities);
    186         $cap_string = serialize($capabilities);
    187 
    188         // Don't search for a transport if it's already been done for these $capabilities
    189         if (isset(self::$transport[$cap_string]) && self::$transport[$cap_string] !== null) {
    190             $class = self::$transport[$cap_string];
    191             return new $class();
    192         }
    193         // @codeCoverageIgnoreEnd
    194 
    195         if (empty(self::$transports)) {
    196             self::$transports = array(
    197                 'Requests_Transport_cURL',
    198                 'Requests_Transport_fsockopen',
    199             );
    200         }
    201 
    202         // Find us a working transport
    203         foreach (self::$transports as $class) {
    204             if (!class_exists($class)) {
    205                 continue;
    206             }
    207 
    208             $result = call_user_func(array($class, 'test'), $capabilities);
    209             if ($result) {
    210                 self::$transport[$cap_string] = $class;
    211                 break;
    212             }
    213         }
    214         if (self::$transport[$cap_string] === null) {
    215             throw new Requests_Exception('No working transports found', 'notransport', self::$transports);
    216         }
    217 
    218         $class = self::$transport[$cap_string];
    219         return new $class();
    220     }
    221 
    222     /**#@+
    223      * @see request()
    224      * @param string $url
    225      * @param array $headers
    226      * @param array $options
    227      * @return Requests_Response
    228      */
    229     /**
    230      * Send a GET request
    231      */
    232     public static function get($url, $headers = array(), $options = array()) {
    233         return self::request($url, $headers, null, self::GET, $options);
    234     }
    235 
    236     /**
    237      * Send a HEAD request
    238      */
    239     public static function head($url, $headers = array(), $options = array()) {
    240         return self::request($url, $headers, null, self::HEAD, $options);
    241     }
    242 
    243     /**
    244      * Send a DELETE request
    245      */
    246     public static function delete($url, $headers = array(), $options = array()) {
    247         return self::request($url, $headers, null, self::DELETE, $options);
    248     }
    249 
    250     /**
    251      * Send a TRACE request
    252      */
    253     public static function trace($url, $headers = array(), $options = array()) {
    254         return self::request($url, $headers, null, self::TRACE, $options);
    255     }
    256     /**#@-*/
    257 
    258     /**#@+
    259      * @see request()
    260      * @param string $url
    261      * @param array $headers
    262      * @param array $data
    263      * @param array $options
    264      * @return Requests_Response
    265      */
    266     /**
    267      * Send a POST request
    268      */
    269     public static function post($url, $headers = array(), $data = array(), $options = array()) {
    270         return self::request($url, $headers, $data, self::POST, $options);
    271     }
    272     /**
    273      * Send a PUT request
    274      */
    275     public static function put($url, $headers = array(), $data = array(), $options = array()) {
    276         return self::request($url, $headers, $data, self::PUT, $options);
    277     }
    278 
    279     /**
    280      * Send an OPTIONS request
    281      */
    282     public static function options($url, $headers = array(), $data = array(), $options = array()) {
    283         return self::request($url, $headers, $data, self::OPTIONS, $options);
    284     }
    285 
    286     /**
    287      * Send a PATCH request
    288      *
    289      * Note: Unlike {@see post} and {@see put}, `$headers` is required, as the
    290      * specification recommends that should send an ETag
    291      *
    292      * @link https://tools.ietf.org/html/rfc5789
    293      */
    294     public static function patch($url, $headers, $data = array(), $options = array()) {
    295         return self::request($url, $headers, $data, self::PATCH, $options);
    296     }
    297     /**#@-*/
    298 
    299     /**
    300      * Main interface for HTTP requests
    301      *
    302      * This method initiates a request and sends it via a transport before
    303      * parsing.
    304      *
    305      * The `$options` parameter takes an associative array with the following
    306      * options:
    307      *
    308      * - `timeout`: How long should we wait for a response?
    309      *    Note: for cURL, a minimum of 1 second applies, as DNS resolution
    310      *    operates at second-resolution only.
    311      *    (float, seconds with a millisecond precision, default: 10, example: 0.01)
    312      * - `connect_timeout`: How long should we wait while trying to connect?
    313      *    (float, seconds with a millisecond precision, default: 10, example: 0.01)
    314      * - `useragent`: Useragent to send to the server
    315      *    (string, default: php-requests/$version)
    316      * - `follow_redirects`: Should we follow 3xx redirects?
    317      *    (boolean, default: true)
    318      * - `redirects`: How many times should we redirect before erroring?
    319      *    (integer, default: 10)
    320      * - `blocking`: Should we block processing on this request?
    321      *    (boolean, default: true)
    322      * - `filename`: File to stream the body to instead.
    323      *    (string|boolean, default: false)
    324      * - `auth`: Authentication handler or array of user/password details to use
    325      *    for Basic authentication
    326      *    (Requests_Auth|array|boolean, default: false)
    327      * - `proxy`: Proxy details to use for proxy by-passing and authentication
    328      *    (Requests_Proxy|array|string|boolean, default: false)
    329      * - `max_bytes`: Limit for the response body size.
    330      *    (integer|boolean, default: false)
    331      * - `idn`: Enable IDN parsing
    332      *    (boolean, default: true)
    333      * - `transport`: Custom transport. Either a class name, or a
    334      *    transport object. Defaults to the first working transport from
    335      *    {@see getTransport()}
    336      *    (string|Requests_Transport, default: {@see getTransport()})
    337      * - `hooks`: Hooks handler.
    338      *    (Requests_Hooker, default: new Requests_Hooks())
    339      * - `verify`: Should we verify SSL certificates? Allows passing in a custom
    340      *    certificate file as a string. (Using true uses the system-wide root
    341      *    certificate store instead, but this may have different behaviour
    342      *    across transports.)
    343      *    (string|boolean, default: library/Requests/Transport/cacert.pem)
    344      * - `verifyname`: Should we verify the common name in the SSL certificate?
    345      *    (boolean, default: true)
    346      * - `data_format`: How should we send the `$data` parameter?
    347      *    (string, one of 'query' or 'body', default: 'query' for
    348      *    HEAD/GET/DELETE, 'body' for POST/PUT/OPTIONS/PATCH)
    349      *
    350      * @throws Requests_Exception On invalid URLs (`nonhttp`)
    351      *
    352      * @param string $url URL to request
    353      * @param array $headers Extra headers to send with the request
    354      * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
    355      * @param string $type HTTP request type (use Requests constants)
    356      * @param array $options Options for the request (see description for more information)
    357      * @return Requests_Response
    358      */
    359     public static function request($url, $headers = array(), $data = array(), $type = self::GET, $options = array()) {
    360         if (empty($options['type'])) {
    361             $options['type'] = $type;
    362         }
    363         $options = array_merge(self::get_default_options(), $options);
    364 
    365         self::set_defaults($url, $headers, $data, $type, $options);
    366 
    367         $options['hooks']->dispatch('requests.before_request', array(&$url, &$headers, &$data, &$type, &$options));
    368 
    369         if (!empty($options['transport'])) {
    370             $transport = $options['transport'];
    371 
    372             if (is_string($options['transport'])) {
    373                 $transport = new $transport();
    374             }
    375         }
    376         else {
    377             $need_ssl     = (stripos($url, 'https://') === 0);
    378             $capabilities = array('ssl' => $need_ssl);
    379             $transport    = self::get_transport($capabilities);
    380         }
    381         $response = $transport->request($url, $headers, $data, $options);
    382 
    383         $options['hooks']->dispatch('requests.before_parse', array(&$response, $url, $headers, $data, $type, $options));
    384 
    385         return self::parse_response($response, $url, $headers, $data, $options);
    386     }
    387 
    388     /**
    389      * Send multiple HTTP requests simultaneously
    390      *
    391      * The `$requests` parameter takes an associative or indexed array of
    392      * request fields. The key of each request can be used to match up the
    393      * request with the returned data, or with the request passed into your
    394      * `multiple.request.complete` callback.
    395      *
    396      * The request fields value is an associative array with the following keys:
    397      *
    398      * - `url`: Request URL Same as the `$url` parameter to
    399      *    {@see Requests::request}
    400      *    (string, required)
    401      * - `headers`: Associative array of header fields. Same as the `$headers`
    402      *    parameter to {@see Requests::request}
    403      *    (array, default: `array()`)
    404      * - `data`: Associative array of data fields or a string. Same as the
    405      *    `$data` parameter to {@see Requests::request}
    406      *    (array|string, default: `array()`)
    407      * - `type`: HTTP request type (use Requests constants). Same as the `$type`
    408      *    parameter to {@see Requests::request}
    409      *    (string, default: `Requests::GET`)
    410      * - `cookies`: Associative array of cookie name to value, or cookie jar.
    411      *    (array|Requests_Cookie_Jar)
    412      *
    413      * If the `$options` parameter is specified, individual requests will
    414      * inherit options from it. This can be used to use a single hooking system,
    415      * or set all the types to `Requests::POST`, for example.
    416      *
    417      * In addition, the `$options` parameter takes the following global options:
    418      *
    419      * - `complete`: A callback for when a request is complete. Takes two
    420      *    parameters, a Requests_Response/Requests_Exception reference, and the
    421      *    ID from the request array (Note: this can also be overridden on a
    422      *    per-request basis, although that's a little silly)
    423      *    (callback)
    424      *
    425      * @param array $requests Requests data (see description for more information)
    426      * @param array $options Global and default options (see {@see Requests::request})
    427      * @return array Responses (either Requests_Response or a Requests_Exception object)
    428      */
    429     public static function request_multiple($requests, $options = array()) {
    430         $options = array_merge(self::get_default_options(true), $options);
    431 
    432         if (!empty($options['hooks'])) {
    433             $options['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple'));
    434             if (!empty($options['complete'])) {
    435                 $options['hooks']->register('multiple.request.complete', $options['complete']);
    436             }
    437         }
    438 
    439         foreach ($requests as $id => &$request) {
    440             if (!isset($request['headers'])) {
    441                 $request['headers'] = array();
    442             }
    443             if (!isset($request['data'])) {
    444                 $request['data'] = array();
    445             }
    446             if (!isset($request['type'])) {
    447                 $request['type'] = self::GET;
    448             }
    449             if (!isset($request['options'])) {
    450                 $request['options']         = $options;
    451                 $request['options']['type'] = $request['type'];
    452             }
    453             else {
    454                 if (empty($request['options']['type'])) {
    455                     $request['options']['type'] = $request['type'];
    456                 }
    457                 $request['options'] = array_merge($options, $request['options']);
    458             }
    459 
    460             self::set_defaults($request['url'], $request['headers'], $request['data'], $request['type'], $request['options']);
    461 
    462             // Ensure we only hook in once
    463             if ($request['options']['hooks'] !== $options['hooks']) {
    464                 $request['options']['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple'));
    465                 if (!empty($request['options']['complete'])) {
    466                     $request['options']['hooks']->register('multiple.request.complete', $request['options']['complete']);
    467                 }
    468             }
    469         }
    470         unset($request);
    471 
    472         if (!empty($options['transport'])) {
    473             $transport = $options['transport'];
    474 
    475             if (is_string($options['transport'])) {
    476                 $transport = new $transport();
    477             }
    478         }
    479         else {
    480             $transport = self::get_transport();
    481         }
    482         $responses = $transport->request_multiple($requests, $options);
    483 
    484         foreach ($responses as $id => &$response) {
    485             // If our hook got messed with somehow, ensure we end up with the
    486             // correct response
    487             if (is_string($response)) {
    488                 $request = $requests[$id];
    489                 self::parse_multiple($response, $request);
    490                 $request['options']['hooks']->dispatch('multiple.request.complete', array(&$response, $id));
    491             }
    492         }
    493 
    494         return $responses;
    495     }
    496 
    497     /**
    498      * Get the default options
    499      *
    500      * @see Requests::request() for values returned by this method
    501      * @param boolean $multirequest Is this a multirequest?
    502      * @return array Default option values
    503      */
    504     protected static function get_default_options($multirequest = false) {
    505         $defaults = array(
    506             'timeout'          => 10,
    507             'connect_timeout'  => 10,
    508             'useragent'        => 'php-requests/' . self::VERSION,
    509             'protocol_version' => 1.1,
    510             'redirected'       => 0,
    511             'redirects'        => 10,
    512             'follow_redirects' => true,
    513             'blocking'         => true,
    514             'type'             => self::GET,
    515             'filename'         => false,
    516             'auth'             => false,
    517             'proxy'            => false,
    518             'cookies'          => false,
    519             'max_bytes'        => false,
    520             'idn'              => true,
    521             'hooks'            => null,
    522             'transport'        => null,
    523             'verify'           => self::get_certificate_path(),
    524             'verifyname'       => true,
    525         );
    526         if ($multirequest !== false) {
    527             $defaults['complete'] = null;
    528         }
    529         return $defaults;
    530     }
    531 
    532     /**
    533      * Get default certificate path.
    534      *
    535      * @return string Default certificate path.
    536      */
    537     public static function get_certificate_path() {
    538         if (!empty(self::$certificate_path)) {
    539             return self::$certificate_path;
    540         }
    541 
    542         return dirname(__FILE__) . '/Requests/Transport/cacert.pem';
    543     }
    544 
    545     /**
    546      * Set default certificate path.
    547      *
    548      * @param string $path Certificate path, pointing to a PEM file.
    549      */
    550     public static function set_certificate_path($path) {
    551         self::$certificate_path = $path;
    552     }
    553 
    554     /**
    555      * Set the default values
    556      *
    557      * @param string $url URL to request
    558      * @param array $headers Extra headers to send with the request
    559      * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
    560      * @param string $type HTTP request type
    561      * @param array $options Options for the request
    562      * @return array $options
    563      */
    564     protected static function set_defaults(&$url, &$headers, &$data, &$type, &$options) {
    565         if (!preg_match('/^http(s)?:\/\//i', $url, $matches)) {
    566             throw new Requests_Exception('Only HTTP(S) requests are handled.', 'nonhttp', $url);
    567         }
    568 
    569         if (empty($options['hooks'])) {
    570             $options['hooks'] = new Requests_Hooks();
    571         }
    572 
    573         if (is_array($options['auth'])) {
    574             $options['auth'] = new Requests_Auth_Basic($options['auth']);
    575         }
    576         if ($options['auth'] !== false) {
    577             $options['auth']->register($options['hooks']);
    578         }
    579 
    580         if (is_string($options['proxy']) || is_array($options['proxy'])) {
    581             $options['proxy'] = new Requests_Proxy_HTTP($options['proxy']);
    582         }
    583         if ($options['proxy'] !== false) {
    584             $options['proxy']->register($options['hooks']);
    585         }
    586 
    587         if (is_array($options['cookies'])) {
    588             $options['cookies'] = new Requests_Cookie_Jar($options['cookies']);
    589         }
    590         elseif (empty($options['cookies'])) {
    591             $options['cookies'] = new Requests_Cookie_Jar();
    592         }
    593         if ($options['cookies'] !== false) {
    594             $options['cookies']->register($options['hooks']);
    595         }
    596 
    597         if ($options['idn'] !== false) {
    598             $iri       = new Requests_IRI($url);
    599             $iri->host = Requests_IDNAEncoder::encode($iri->ihost);
    600             $url       = $iri->uri;
    601         }
    602 
    603         // Massage the type to ensure we support it.
    604         $type = strtoupper($type);
    605 
    606         if (!isset($options['data_format'])) {
    607             if (in_array($type, array(self::HEAD, self::GET, self::DELETE), true)) {
    608                 $options['data_format'] = 'query';
    609             }
    610             else {
    611                 $options['data_format'] = 'body';
    612             }
    613         }
    614     }
    615 
    616     /**
    617      * HTTP response parser
    618      *
    619      * @throws Requests_Exception On missing head/body separator (`requests.no_crlf_separator`)
    620      * @throws Requests_Exception On missing head/body separator (`noversion`)
    621      * @throws Requests_Exception On missing head/body separator (`toomanyredirects`)
    622      *
    623      * @param string $headers Full response text including headers and body
    624      * @param string $url Original request URL
    625      * @param array $req_headers Original $headers array passed to {@link request()}, in case we need to follow redirects
    626      * @param array $req_data Original $data array passed to {@link request()}, in case we need to follow redirects
    627      * @param array $options Original $options array passed to {@link request()}, in case we need to follow redirects
    628      * @return Requests_Response
    629      */
    630     protected static function parse_response($headers, $url, $req_headers, $req_data, $options) {
    631         $return = new Requests_Response();
    632         if (!$options['blocking']) {
    633             return $return;
    634         }
    635 
    636         $return->raw  = $headers;
    637         $return->url  = (string) $url;
    638         $return->body = '';
    639 
    640         if (!$options['filename']) {
    641             $pos = strpos($headers, "\r\n\r\n");
    642             if ($pos === false) {
    643                 // Crap!
    644                 throw new Requests_Exception('Missing header/body separator', 'requests.no_crlf_separator');
    645             }
    646 
    647             $headers = substr($return->raw, 0, $pos);
    648             // Headers will always be separated from the body by two new lines - `\n\r\n\r`.
    649             $body = substr($return->raw, $pos + 4);
    650             if (!empty($body)) {
    651                 $return->body = $body;
    652             }
    653         }
    654         // Pretend CRLF = LF for compatibility (RFC 2616, section 19.3)
    655         $headers = str_replace("\r\n", "\n", $headers);
    656         // Unfold headers (replace [CRLF] 1*( SP | HT ) with SP) as per RFC 2616 (section 2.2)
    657         $headers = preg_replace('/\n[ \t]/', ' ', $headers);
    658         $headers = explode("\n", $headers);
    659         preg_match('#^HTTP/(1\.\d)[ \t]+(\d+)#i', array_shift($headers), $matches);
    660         if (empty($matches)) {
    661             throw new Requests_Exception('Response could not be parsed', 'noversion', $headers);
    662         }
    663         $return->protocol_version = (float) $matches[1];
    664         $return->status_code      = (int) $matches[2];
    665         if ($return->status_code >= 200 && $return->status_code < 300) {
    666             $return->success = true;
    667         }
    668 
    669         foreach ($headers as $header) {
    670             list($key, $value) = explode(':', $header, 2);
    671             $value             = trim($value);
    672             preg_replace('#(\s+)#i', ' ', $value);
    673             $return->headers[$key] = $value;
    674         }
    675         if (isset($return->headers['transfer-encoding'])) {
    676             $return->body = self::decode_chunked($return->body);
    677             unset($return->headers['transfer-encoding']);
    678         }
    679         if (isset($return->headers['content-encoding'])) {
    680             $return->body = self::decompress($return->body);
    681         }
    682 
    683         //fsockopen and cURL compatibility
    684         if (isset($return->headers['connection'])) {
    685             unset($return->headers['connection']);
    686         }
    687 
    688         $options['hooks']->dispatch('requests.before_redirect_check', array(&$return, $req_headers, $req_data, $options));
    689 
    690         if ($return->is_redirect() && $options['follow_redirects'] === true) {
    691             if (isset($return->headers['location']) && $options['redirected'] < $options['redirects']) {
    692                 if ($return->status_code === 303) {
    693                     $options['type'] = self::GET;
    694                 }
    695                 $options['redirected']++;
    696                 $location = $return->headers['location'];
    697                 if (strpos($location, 'http://') !== 0 && strpos($location, 'https://') !== 0) {
    698                     // relative redirect, for compatibility make it absolute
    699                     $location = Requests_IRI::absolutize($url, $location);
    700                     $location = $location->uri;
    701                 }
    702 
    703                 $hook_args = array(
    704                     &$location,
    705                     &$req_headers,
    706                     &$req_data,
    707                     &$options,
    708                     $return,
    709                 );
    710                 $options['hooks']->dispatch('requests.before_redirect', $hook_args);
    711                 $redirected            = self::request($location, $req_headers, $req_data, $options['type'], $options);
    712                 $redirected->history[] = $return;
    713                 return $redirected;
    714             }
    715             elseif ($options['redirected'] >= $options['redirects']) {
    716                 throw new Requests_Exception('Too many redirects', 'toomanyredirects', $return);
    717             }
    718         }
    719 
    720         $return->redirects = $options['redirected'];
    721 
    722         $options['hooks']->dispatch('requests.after_request', array(&$return, $req_headers, $req_data, $options));
    723         return $return;
    724     }
    725 
    726     /**
    727      * Callback for `transport.internal.parse_response`
    728      *
    729      * Internal use only. Converts a raw HTTP response to a Requests_Response
    730      * while still executing a multiple request.
    731      *
    732      * @param string $response Full response text including headers and body (will be overwritten with Response instance)
    733      * @param array $request Request data as passed into {@see Requests::request_multiple()}
    734      * @return null `$response` is either set to a Requests_Response instance, or a Requests_Exception object
    735      */
    736     public static function parse_multiple(&$response, $request) {
    737         try {
    738             $url      = $request['url'];
    739             $headers  = $request['headers'];
    740             $data     = $request['data'];
    741             $options  = $request['options'];
    742             $response = self::parse_response($response, $url, $headers, $data, $options);
    743         }
    744         catch (Requests_Exception $e) {
    745             $response = $e;
    746         }
    747     }
    748 
    749     /**
    750      * Decoded a chunked body as per RFC 2616
    751      *
    752      * @see https://tools.ietf.org/html/rfc2616#section-3.6.1
    753      * @param string $data Chunked body
    754      * @return string Decoded body
    755      */
    756     protected static function decode_chunked($data) {
    757         if (!preg_match('/^([0-9a-f]+)(?:;(?:[\w-]*)(?:=(?:(?:[\w-]*)*|"(?:[^\r\n])*"))?)*\r\n/i', trim($data))) {
    758             return $data;
    759         }
    760 
    761         $decoded = '';
    762         $encoded = $data;
    763 
    764         while (true) {
    765             $is_chunked = (bool) preg_match('/^([0-9a-f]+)(?:;(?:[\w-]*)(?:=(?:(?:[\w-]*)*|"(?:[^\r\n])*"))?)*\r\n/i', $encoded, $matches);
    766             if (!$is_chunked) {
    767                 // Looks like it's not chunked after all
    768                 return $data;
    769             }
    770 
    771             $length = hexdec(trim($matches[1]));
    772             if ($length === 0) {
    773                 // Ignore trailer headers
    774                 return $decoded;
    775             }
    776 
    777             $chunk_length = strlen($matches[0]);
    778             $decoded     .= substr($encoded, $chunk_length, $length);
    779             $encoded      = substr($encoded, $chunk_length + $length + 2);
    780 
    781             if (trim($encoded) === '0' || empty($encoded)) {
    782                 return $decoded;
    783             }
    784         }
    785 
    786         // We'll never actually get down here
    787         // @codeCoverageIgnoreStart
    788     }
    789     // @codeCoverageIgnoreEnd
    790 
    791     /**
    792      * Convert a key => value array to a 'key: value' array for headers
    793      *
    794      * @param array $array Dictionary of header values
    795      * @return array List of headers
    796      */
    797     public static function flatten($array) {
    798         $return = array();
    799         foreach ($array as $key => $value) {
    800             $return[] = sprintf('%s: %s', $key, $value);
    801         }
    802         return $return;
    803     }
    804 
    805     /**
    806      * Convert a key => value array to a 'key: value' array for headers
    807      *
    808      * @codeCoverageIgnore
    809      * @deprecated Misspelling of {@see Requests::flatten}
    810      * @param array $array Dictionary of header values
    811      * @return array List of headers
    812      */
    813     public static function flattern($array) {
    814         return self::flatten($array);
    815     }
    816 
    817     /**
    818      * Decompress an encoded body
    819      *
    820      * Implements gzip, compress and deflate. Guesses which it is by attempting
    821      * to decode.
    822      *
    823      * @param string $data Compressed data in one of the above formats
    824      * @return string Decompressed string
    825      */
    826     public static function decompress($data) {
    827         if (substr($data, 0, 2) !== "\x1f\x8b" && substr($data, 0, 2) !== "\x78\x9c") {
    828             // Not actually compressed. Probably cURL ruining this for us.
    829             return $data;
    830         }
    831 
    832         if (function_exists('gzdecode')) {
    833             // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.gzdecodeFound -- Wrapped in function_exists() for PHP 5.2.
    834             $decoded = @gzdecode($data);
    835             if ($decoded !== false) {
    836                 return $decoded;
    837             }
    838         }
    839 
    840         if (function_exists('gzinflate')) {
    841             $decoded = @gzinflate($data);
    842             if ($decoded !== false) {
    843                 return $decoded;
    844             }
    845         }
    846 
    847         $decoded = self::compatible_gzinflate($data);
    848         if ($decoded !== false) {
    849             return $decoded;
    850         }
    851 
    852         if (function_exists('gzuncompress')) {
    853             $decoded = @gzuncompress($data);
    854             if ($decoded !== false) {
    855                 return $decoded;
    856             }
    857         }
    858 
    859         return $data;
    860     }
    861 
    862     /**
    863      * Decompression of deflated string while staying compatible with the majority of servers.
    864      *
    865      * Certain Servers will return deflated data with headers which PHP's gzinflate()
    866      * function cannot handle out of the box. The following function has been created from
    867      * various snippets on the gzinflate() PHP documentation.
    868      *
    869      * Warning: Magic numbers within. Due to the potential different formats that the compressed
    870      * data may be returned in, some "magic offsets" are needed to ensure proper decompression
    871      * takes place. For a simple progmatic way to determine the magic offset in use, see:
    872      * https://core.trac.wordpress.org/ticket/18273
    873      *
    874      * @since 2.8.1
    875      * @link https://core.trac.wordpress.org/ticket/18273
    876      * @link https://secure.php.net/manual/en/function.gzinflate.php#70875
    877      * @link https://secure.php.net/manual/en/function.gzinflate.php#77336
    878      *
    879      * @param string $gz_data String to decompress.
    880      * @return string|bool False on failure.
    881      */
    882     public static function compatible_gzinflate($gz_data) {
    883         // Compressed data might contain a full zlib header, if so strip it for
    884         // gzinflate()
    885         if (substr($gz_data, 0, 3) === "\x1f\x8b\x08") {
    886             $i   = 10;
    887             $flg = ord(substr($gz_data, 3, 1));
    888             if ($flg > 0) {
    889                 if ($flg & 4) {
    890                     list($xlen) = unpack('v', substr($gz_data, $i, 2));
    891                     $i         += 2 + $xlen;
    892                 }
    893                 if ($flg & 8) {
    894                     $i = strpos($gz_data, "\0", $i) + 1;
    895                 }
    896                 if ($flg & 16) {
    897                     $i = strpos($gz_data, "\0", $i) + 1;
    898                 }
    899                 if ($flg & 2) {
    900                     $i += 2;
    901                 }
    902             }
    903             $decompressed = self::compatible_gzinflate(substr($gz_data, $i));
    904             if ($decompressed !== false) {
    905                 return $decompressed;
    906             }
    907         }
    908 
    909         // If the data is Huffman Encoded, we must first strip the leading 2
    910         // byte Huffman marker for gzinflate()
    911         // The response is Huffman coded by many compressors such as
    912         // java.util.zip.Deflater, Ruby’s Zlib::Deflate, and .NET's
    913         // System.IO.Compression.DeflateStream.
    914         //
    915         // See https://decompres.blogspot.com/ for a quick explanation of this
    916         // data type
    917         $huffman_encoded = false;
    918 
    919         // low nibble of first byte should be 0x08
    920         list(, $first_nibble) = unpack('h', $gz_data);
    921 
    922         // First 2 bytes should be divisible by 0x1F
    923         list(, $first_two_bytes) = unpack('n', $gz_data);
    924 
    925         if ($first_nibble === 0x08 && ($first_two_bytes % 0x1F) === 0) {
    926             $huffman_encoded = true;
    927         }
    928 
    929         if ($huffman_encoded) {
    930             $decompressed = @gzinflate(substr($gz_data, 2));
    931             if ($decompressed !== false) {
    932                 return $decompressed;
    933             }
    934         }
    935 
    936         if (substr($gz_data, 0, 4) === "\x50\x4b\x03\x04") {
    937             // ZIP file format header
    938             // Offset 6: 2 bytes, General-purpose field
    939             // Offset 26: 2 bytes, filename length
    940             // Offset 28: 2 bytes, optional field length
    941             // Offset 30: Filename field, followed by optional field, followed
    942             // immediately by data
    943             list(, $general_purpose_flag) = unpack('v', substr($gz_data, 6, 2));
    944 
    945             // If the file has been compressed on the fly, 0x08 bit is set of
    946             // the general purpose field. We can use this to differentiate
    947             // between a compressed document, and a ZIP file
    948             $zip_compressed_on_the_fly = ((0x08 & $general_purpose_flag) === 0x08);
    949 
    950             if (!$zip_compressed_on_the_fly) {
    951                 // Don't attempt to decode a compressed zip file
    952                 return $gz_data;
    953             }
    954 
    955             // Determine the first byte of data, based on the above ZIP header
    956             // offsets:
    957             $first_file_start = array_sum(unpack('v2', substr($gz_data, 26, 4)));
    958             $decompressed     = @gzinflate(substr($gz_data, 30 + $first_file_start));
    959             if ($decompressed !== false) {
    960                 return $decompressed;
    961             }
    962             return false;
    963         }
    964 
    965         // Finally fall back to straight gzinflate
    966         $decompressed = @gzinflate($gz_data);
    967         if ($decompressed !== false) {
    968             return $decompressed;
    969         }
    970 
    971         // Fallback for all above failing, not expected, but included for
    972         // debugging and preventing regressions and to track stats
    973         $decompressed = @gzinflate(substr($gz_data, 2));
    974         if ($decompressed !== false) {
    975             return $decompressed;
    976         }
    977 
    978         return false;
    979     }
    980 
    981     public static function match_domain($host, $reference) {
    982         // Check for a direct match
    983         if ($host === $reference) {
    984             return true;
    985         }
    986 
    987         // Calculate the valid wildcard match if the host is not an IP address
    988         // Also validates that the host has 3 parts or more, as per Firefox's
    989         // ruleset.
    990         $parts = explode('.', $host);
    991         if (ip2long($host) === false && count($parts) >= 3) {
    992             $parts[0] = '*';
    993             $wildcard = implode('.', $parts);
    994             if ($wildcard === $reference) {
    995                 return true;
    996             }
    997         }
    998 
    999         return false;
     75        require_once __DIR__ . '/Requests/src/Autoload.php';
     76        WpOrg\Requests\Autoload::register();
    100077    }
    100178}
  • trunk/src/wp-includes/class-wp-http-requests-hooks.php

    r54133 r54997  
    1313 * @since 4.7.0
    1414 *
    15  * @see Requests_Hooks
     15 * @see WpOrg\Requests\Hooks
    1616 */
    1717#[AllowDynamicProperties]
    18 class WP_HTTP_Requests_Hooks extends Requests_Hooks {
     18class WP_HTTP_Requests_Hooks extends WpOrg\Requests\Hooks {
    1919    /**
    2020     * Requested URL.
  • trunk/src/wp-includes/class-wp-http-requests-response.php

    r52328 r54997  
    99
    1010/**
    11  * Core wrapper object for a Requests_Response for standardisation.
     11 * Core wrapper object for a WpOrg\Requests\Response for standardisation.
    1212 *
    1313 * @since 4.6.0
     
    2020     *
    2121     * @since 4.6.0
    22      * @var Requests_Response
     22     * @var \WpOrg\Requests\Response
    2323     */
    2424    protected $response;
     
    3737     * @since 4.6.0
    3838     *
    39      * @param Requests_Response $response HTTP response.
    40      * @param string            $filename Optional. File name. Default empty.
     39     * @param \WpOrg\Requests\Response $response HTTP response.
     40     * @param string                   $filename Optional. File name. Default empty.
    4141     */
    42     public function __construct( Requests_Response $response, $filename = '' ) {
     42    public function __construct( WpOrg\Requests\Response $response, $filename = '' ) {
    4343        $this->response = $response;
    4444        $this->filename = $filename;
     
    5050     * @since 4.6.0
    5151     *
    52      * @return Requests_Response HTTP response.
     52     * @return WpOrg\Requests\Response HTTP response.
    5353     */
    5454    public function get_response_object() {
     
    6161     * @since 4.6.0
    6262     *
    63      * @return \Requests_Utility_CaseInsensitiveDictionary Map of header name to header value.
     63     * @return \WpOrg\Requests\Utility\CaseInsensitiveDictionary Map of header name to header value.
    6464     */
    6565    public function get_headers() {
    6666        // Ensure headers remain case-insensitive.
    67         $converted = new Requests_Utility_CaseInsensitiveDictionary();
     67        $converted = new WpOrg\Requests\Utility\CaseInsensitiveDictionary();
    6868
    6969        foreach ( $this->response->headers->getAll() as $key => $value ) {
     
    8686     */
    8787    public function set_headers( $headers ) {
    88         $this->response->headers = new Requests_Response_Headers( $headers );
     88        $this->response->headers = new WpOrg\Requests\Response\Headers( $headers );
    8989    }
    9090
  • trunk/src/wp-includes/class-wp-http.php

    r54891 r54997  
    88 */
    99
    10 if ( ! class_exists( 'Requests' ) ) {
    11     require ABSPATH . WPINC . '/class-requests.php';
    12 
    13     Requests::register_autoloader();
    14     Requests::set_certificate_path( ABSPATH . WPINC . '/certificates/ca-bundle.crt' );
     10if ( ! class_exists( 'WpOrg\Requests\Autoload' ) ) {
     11    require ABSPATH . WPINC . '/Requests/src/Autoload.php';
     12
     13    WpOrg\Requests\Autoload::register();
     14    WpOrg\Requests\Requests::set_certificate_path( ABSPATH . WPINC . '/certificates/ca-bundle.crt' );
    1515}
    1616
     
    276276            $response = new WP_Error( 'http_request_failed', __( 'A valid URL was not provided.' ) );
    277277            /** This action is documented in wp-includes/class-wp-http.php */
    278             do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url );
     278            do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url );
    279279            return $response;
    280280        }
     
    283283            $response = new WP_Error( 'http_request_not_executed', __( 'User has blocked requests through HTTP.' ) );
    284284            /** This action is documented in wp-includes/class-wp-http.php */
    285             do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url );
     285            do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url );
    286286            return $response;
    287287        }
     
    300300                $response = new WP_Error( 'http_request_failed', __( 'Destination directory for file streaming does not exist or is not writable.' ) );
    301301                /** This action is documented in wp-includes/class-wp-http.php */
    302                 do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url );
     302                do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url );
    303303                return $response;
    304304            }
     
    348348        }
    349349
    350         // If we've got cookies, use and convert them to Requests_Cookie.
     350        // If we've got cookies, use and convert them to WpOrg\Requests\Cookie.
    351351        if ( ! empty( $parsed_args['cookies'] ) ) {
    352352            $options['cookies'] = WP_Http::normalize_cookies( $parsed_args['cookies'] );
     
    380380        $proxy = new WP_HTTP_Proxy();
    381381        if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) {
    382             $options['proxy'] = new Requests_Proxy_HTTP( $proxy->host() . ':' . $proxy->port() );
     382            $options['proxy'] = new WpOrg\Requests\Proxy\HTTP( $proxy->host() . ':' . $proxy->port() );
    383383
    384384            if ( $proxy->use_authentication() ) {
     
    393393
    394394        try {
    395             $requests_response = Requests::request( $url, $headers, $data, $type, $options );
     395            $requests_response = WpOrg\Requests\Requests::request( $url, $headers, $data, $type, $options );
    396396
    397397            // Convert the response into an array.
     
    401401            // Add the original object to the array.
    402402            $response['http_response'] = $http_response;
    403         } catch ( Requests_Exception $e ) {
     403        } catch ( WpOrg\Requests\Exception $e ) {
    404404            $response = new WP_Error( 'http_request_failed', $e->getMessage() );
    405405        }
     
    418418         * @param string         $url         The request URL.
    419419         */
    420         do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url );
     420        do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url );
    421421        if ( is_wp_error( $response ) ) {
    422422            return $response;
     
    454454     *
    455455     * @param array $cookies Array of cookies to send with the request.
    456      * @return Requests_Cookie_Jar Cookie holder object.
     456     * @return WpOrg\Requests\Cookie\Jar Cookie holder object.
    457457     */
    458458    public static function normalize_cookies( $cookies ) {
    459         $cookie_jar = new Requests_Cookie_Jar();
     459        $cookie_jar = new WpOrg\Requests\Cookie\Jar();
    460460
    461461        foreach ( $cookies as $name => $value ) {
     
    467467                    }
    468468                );
    469                 $cookie_jar[ $value->name ] = new Requests_Cookie( $value->name, $value->value, $attributes, array( 'host-only' => $value->host_only ) );
     469                $cookie_jar[ $value->name ] = new WpOrg\Requests\Cookie( $value->name, $value->value, $attributes, array( 'host-only' => $value->host_only ) );
    470470            } elseif ( is_scalar( $value ) ) {
    471                 $cookie_jar[ $name ] = new Requests_Cookie( $name, $value );
     471                $cookie_jar[ $name ] = new WpOrg\Requests\Cookie( $name, (string) $value );
    472472            }
    473473        }
     
    485485     * @since 4.6.0
    486486     *
    487      * @param string            $location URL to redirect to.
    488      * @param array             $headers  Headers for the redirect.
    489      * @param string|array      $data     Body to send with the request.
    490      * @param array             $options  Redirect request options.
    491      * @param Requests_Response $original Response object.
     487     * @param string                  $location URL to redirect to.
     488     * @param array                   $headers  Headers for the redirect.
     489     * @param string|array            $data     Body to send with the request.
     490     * @param array                   $options  Redirect request options.
     491     * @param WpOrg\Requests\Response $original Response object.
    492492     */
    493493    public static function browser_redirect_compatibility( $location, $headers, $data, &$options, $original ) {
    494494        // Browser compatibility.
    495495        if ( 302 === $original->status_code ) {
    496             $options['type'] = Requests::GET;
     496            $options['type'] = WpOrg\Requests\Requests::GET;
    497497        }
    498498    }
     
    503503     * @since 4.7.5
    504504     *
    505      * @throws Requests_Exception On unsuccessful URL validation.
     505     * @throws WpOrg\Requests\Exception On unsuccessful URL validation.
    506506     * @param string $location URL to redirect to.
    507507     */
    508508    public static function validate_redirects( $location ) {
    509509        if ( ! wp_http_validate_url( $location ) ) {
    510             throw new Requests_Exception( __( 'A valid URL was not provided.' ), 'wp_http.redirect_failed_validation' );
     510            throw new WpOrg\Requests\Exception( __( 'A valid URL was not provided.' ), 'wp_http.redirect_failed_validation' );
    511511        }
    512512    }
  • trunk/src/wp-includes/deprecated.php

    r54878 r54997  
    36553655 * @param int         $red       Optional. The number of Redirects followed, Upon 5 being hit,
    36563656 *                               returns false. Default 1.
    3657  * @return \Requests_Utility_CaseInsensitiveDictionary|false Headers on success, false on failure.
     3657 * @return \WpOrg\Requests\Utility\CaseInsensitiveDictionary|false Headers on success, false on failure.
    36583658 */
    36593659function wp_get_http( $url, $file_path = false, $red = 1 ) {
  • trunk/src/wp-includes/functions.php

    r54929 r54997  
    977977 * @param string $url        URL to retrieve HTTP headers from.
    978978 * @param bool   $deprecated Not Used.
    979  * @return \Requests_Utility_CaseInsensitiveDictionary|false Headers on success, false on failure.
     979 * @return \WpOrg\Requests\Utility\CaseInsensitiveDictionary|false Headers on success, false on failure.
    980980 */
    981981function wp_get_http_headers( $url, $deprecated = false ) {
  • trunk/src/wp-includes/http.php

    r54157 r54997  
    201201 *
    202202 * @since 2.7.0
    203  * @since 4.6.0 Return value changed from an array to an Requests_Utility_CaseInsensitiveDictionary instance.
    204  *
    205  * @see \Requests_Utility_CaseInsensitiveDictionary
     203 * @since 4.6.0 Return value changed from an array to an WpOrg\Requests\Utility\CaseInsensitiveDictionary instance.
     204 *
     205 * @see \WpOrg\Requests\Utility\CaseInsensitiveDictionary
    206206 *
    207207 * @param array|WP_Error $response HTTP response.
    208  * @return \Requests_Utility_CaseInsensitiveDictionary|array The headers of the response, or empty array
    209  *                                                           if incorrect parameter given.
     208 * @return \WpOrg\Requests\Utility\CaseInsensitiveDictionary|array The headers of the response, or empty array
     209 *                                                                 if incorrect parameter given.
    210210 */
    211211function wp_remote_retrieve_headers( $response ) {
  • trunk/src/wp-includes/rest-api.php

    r54964 r54997  
    14151415    $ipv4_pattern = '/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/';
    14161416
    1417     if ( ! preg_match( $ipv4_pattern, $ip ) && ! Requests_IPv6::check_ipv6( $ip ) ) {
     1417    if ( ! preg_match( $ipv4_pattern, $ip ) && ! WpOrg\Requests\Ipv6::check_ipv6( $ip ) ) {
    14181418        return false;
    14191419    }
  • trunk/tests/phpunit/tests/feed/wpSimplePieFile.php

    r54872 r54997  
    8686
    8787        return array(
    88             'headers'  => new Requests_Utility_CaseInsensitiveDictionary( $single_value_headers ),
     88            'headers'  => new WpOrg\Requests\Utility\CaseInsensitiveDictionary( $single_value_headers ),
    8989            'body'     => file_get_contents( DIR_TESTDATA . '/feed/wordpress-org-news.xml' ),
    9090            'response' => array(
     
    115115        );
    116116
    117         $response['headers'] = new Requests_Utility_CaseInsensitiveDictionary( $multiple_value_headers );
     117        $response['headers'] = new WpOrg\Requests\Utility\CaseInsensitiveDictionary( $multiple_value_headers );
    118118
    119119        return $response;
  • trunk/tests/phpunit/tests/functions/maybeSerialize.php

    r53890 r54997  
    214214        $serialized = maybe_serialize( $value );
    215215
    216         if ( get_class( $value ) === 'Requests_Utility_FilteredIterator' ) {
     216        if ( get_class( $value ) === 'WpOrg\Requests\Utility\FilteredIterator' ) {
    217217            $new_value = unserialize( $serialized );
    218             $property  = ( new ReflectionClass( 'Requests_Utility_FilteredIterator' ) )->getProperty( 'callback' );
     218            $property  = ( new ReflectionClass( 'WpOrg\Requests\Utility\FilteredIterator' ) )->getProperty( 'callback' );
    219219            $property->setAccessible( true );
    220220            $callback_value = $property->getValue( $new_value );
     
    234234        return array(
    235235            'filtered iterator using md5'  => array(
    236                 new Requests_Utility_FilteredIterator( array( 1 ), 'md5' ),
     236                new WpOrg\Requests\Utility\FilteredIterator( array( 1 ), 'md5' ),
    237237            ),
    238238            'filtered iterator using sha1' => array(
    239                 new Requests_Utility_FilteredIterator( array( 1, 2 ), 'sha1' ),
     239                new WpOrg\Requests\Utility\FilteredIterator( array( 1, 2 ), 'sha1' ),
    240240            ),
    241241            'array iterator'               => array(
  • trunk/tests/phpunit/tests/http/functions.php

    r53491 r54997  
    217217    public function test_get_cookie_host_only() {
    218218        // Emulate WP_Http::request() internals.
    219         $requests_response = new Requests_Response();
    220 
    221         $requests_response->cookies['test'] = Requests_Cookie::parse( 'test=foo; domain=.wordpress.org' );
     219        $requests_response = new WpOrg\Requests\Response();
     220
     221        $requests_response->cookies['test'] = WpOrg\Requests\Cookie::parse( 'test=foo; domain=.wordpress.org' );
    222222
    223223        $requests_response->cookies['test']->flags['host-only'] = false; // https://github.com/WordPress/Requests/issues/306
     
    232232        $this->assertFalse( $cookie->host_only, 'host-only flag not set' );
    233233
    234         // Regurgitate (Requests_Cookie -> WP_Http_Cookie -> Requests_Cookie).
     234        // Regurgitate (WpOrg\Requests\Cookie -> WP_Http_Cookie -> WpOrg\Requests\Cookie).
    235235        $cookies = WP_Http::normalize_cookies( wp_remote_retrieve_cookies( $response ) );
    236236        $this->assertFalse( $cookies['test']->flags['host-only'], 'host-only flag data lost' );
  • trunk/tests/phpunit/tests/http/http.php

    r54968 r54997  
    310310        );
    311311
    312         $this->assertInstanceOf( 'Requests_Cookie_Jar', $cookie_jar );
     312        $this->assertInstanceOf( 'WpOrg\Requests\Cookie\Jar', $cookie_jar );
    313313
    314314        foreach ( array_keys( $cookies ) as $cookie ) {
     
    316316                $this->assertArrayNotHasKey( $cookie, $cookie_jar );
    317317            } else {
    318                 $this->assertInstanceOf( 'Requests_Cookie', $cookie_jar[ $cookie ] );
     318                $this->assertInstanceOf( 'WpOrg\Requests\Cookie', $cookie_jar[ $cookie ] );
    319319            }
    320320        }
  • trunk/tests/phpunit/tests/rest-api/rest-widgets-controller.php

    r54896 r54997  
    418418
    419419        return array(
    420             'headers'  => new Requests_Utility_CaseInsensitiveDictionary( $single_value_headers ),
     420            'headers'  => new WpOrg\Requests\Utility\CaseInsensitiveDictionary( $single_value_headers ),
    421421            'body'     => file_get_contents( DIR_TESTDATA . '/feed/wordpress-org-news.xml' ),
    422422            'response' => array(
  • trunk/tests/phpunit/tests/widgets/wpWidgetRss.php

    r52328 r54997  
    107107
    108108        return array(
    109             'headers'  => new Requests_Utility_CaseInsensitiveDictionary( $single_value_headers ),
     109            'headers'  => new WpOrg\Requests\Utility\CaseInsensitiveDictionary( $single_value_headers ),
    110110            'body'     => file_get_contents( DIR_TESTDATA . '/feed/wordpress-org-news.xml' ),
    111111            'response' => array(
Note: See TracChangeset for help on using the changeset viewer.