Changeset 52244 for trunk/src/wp-includes/Requests/Requests.php
- Timestamp:
- 11/25/2021 01:10:30 AM (5 years ago)
- File:
-
- 1 copied
-
trunk/src/wp-includes/Requests/Requests.php (copied) (copied from trunk/src/wp-includes/class-requests.php ) (48 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/Requests/Requests.php
r52243 r52244 10 10 */ 11 11 12 namespace WpOrg\Requests; 13 14 use WpOrg\Requests\Auth\Basic; 15 use WpOrg\Requests\Capability; 16 use WpOrg\Requests\Cookie\Jar; 17 use WpOrg\Requests\Exception; 18 use WpOrg\Requests\Exception\InvalidArgument; 19 use WpOrg\Requests\Hooks; 20 use WpOrg\Requests\IdnaEncoder; 21 use WpOrg\Requests\Iri; 22 use WpOrg\Requests\Proxy\Http; 23 use WpOrg\Requests\Response; 24 use WpOrg\Requests\Transport\Curl; 25 use WpOrg\Requests\Transport\Fsockopen; 26 use WpOrg\Requests\Utility\InputValidator; 27 12 28 /** 13 29 * Requests for PHP … … 85 101 86 102 /** 103 * Option defaults. 104 * 105 * @see \WpOrg\Requests\Requests::get_default_options() 106 * @see \WpOrg\Requests\Requests::request() for values returned by this method 107 * 108 * @since 2.0.0 109 * 110 * @var array 111 */ 112 const OPTION_DEFAULTS = [ 113 'timeout' => 10, 114 'connect_timeout' => 10, 115 'useragent' => 'php-requests/' . self::VERSION, 116 'protocol_version' => 1.1, 117 'redirected' => 0, 118 'redirects' => 10, 119 'follow_redirects' => true, 120 'blocking' => true, 121 'type' => self::GET, 122 'filename' => false, 123 'auth' => false, 124 'proxy' => false, 125 'cookies' => false, 126 'max_bytes' => false, 127 'idn' => true, 128 'hooks' => null, 129 'transport' => null, 130 'verify' => null, 131 'verifyname' => true, 132 ]; 133 134 /** 135 * Default supported Transport classes. 136 * 137 * @since 2.0.0 138 * 139 * @var array 140 */ 141 const DEFAULT_TRANSPORTS = [ 142 Curl::class => Curl::class, 143 Fsockopen::class => Fsockopen::class, 144 ]; 145 146 /** 87 147 * Current version of Requests 88 148 * 89 149 * @var string 90 150 */ 91 const VERSION = '1.8.1'; 151 const VERSION = '2.0.0'; 152 153 /** 154 * Selected transport name 155 * 156 * Use {@see \WpOrg\Requests\Requests::get_transport()} instead 157 * 158 * @var array 159 */ 160 public static $transport = []; 92 161 93 162 /** … … 96 165 * @var array 97 166 */ 98 protected static $transports = array(); 99 100 /** 101 * Selected transport name 102 * 103 * Use {@see get_transport()} instead 167 protected static $transports = []; 168 169 /** 170 * Default certificate path. 171 * 172 * @see \WpOrg\Requests\Requests::get_certificate_path() 173 * @see \WpOrg\Requests\Requests::set_certificate_path() 174 * 175 * @var string 176 */ 177 protected static $certificate_path = __DIR__ . '/../certificates/cacert.pem'; 178 179 /** 180 * All (known) valid deflate, gzip header magic markers. 181 * 182 * These markers relate to different compression levels. 183 * 184 * @link https://stackoverflow.com/a/43170354/482864 Marker source. 185 * 186 * @since 2.0.0 104 187 * 105 188 * @var array 106 189 */ 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; 190 private static $magic_compression_headers = [ 191 "\x1f\x8b" => true, // Gzip marker. 192 "\x78\x01" => true, // Zlib marker - level 1. 193 "\x78\x5e" => true, // Zlib marker - level 2 to 5. 194 "\x78\x9c" => true, // Zlib marker - level 6. 195 "\x78\xda" => true, // Zlib marker - level 7 to 9. 196 ]; 118 197 119 198 /** … … 125 204 126 205 /** 127 * Autoloader for Requests128 *129 * Register this with {@see register_autoloader()} if you'd like to avoid130 * having to create your own.131 *132 * (You can also use `spl_autoload_register` directly if you'd prefer.)133 *134 * @codeCoverageIgnore135 *136 * @param string $class Class name to load137 */138 public static function autoloader($class) {139 // Check that the class starts with "Requests"140 if (strpos($class, 'Requests') !== 0) {141 return;142 }143 144 $file = str_replace('_', '/', $class);145 if (file_exists(dirname(__FILE__) . '/' . $file . '.php')) {146 require_once dirname(__FILE__) . '/' . $file . '.php';147 }148 }149 150 /**151 * Register the built-in autoloader152 *153 * @codeCoverageIgnore154 */155 public static function register_autoloader() {156 spl_autoload_register(array('Requests', 'autoloader'));157 }158 159 /**160 206 * Register a transport 161 207 * 162 * @param string $transport Transport class to add, must support the Requests_Transport interface208 * @param string $transport Transport class to add, must support the \WpOrg\Requests\Transport interface 163 209 */ 164 210 public static function add_transport($transport) { 165 211 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 212 self::$transports = self::DEFAULT_TRANSPORTS; 213 } 214 215 self::$transports[$transport] = $transport; 216 } 217 218 /** 219 * Get the fully qualified class name (FQCN) for a working transport. 220 * 221 * @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`. 222 * @return string FQCN of the transport to use, or an empty string if no transport was 223 * found which provided the requested capabilities. 224 */ 225 protected static function get_transport_class(array $capabilities = []) { 226 // Caching code, don't bother testing coverage. 183 227 // @codeCoverageIgnoreStart 184 // array of capabilities as a string to be used as an array key228 // Array of capabilities as a string to be used as an array key. 185 229 ksort($capabilities); 186 230 $cap_string = serialize($capabilities); 187 231 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 } 232 // Don't search for a transport if it's already been done for these $capabilities. 233 if (isset(self::$transport[$cap_string])) { 234 return self::$transport[$cap_string]; 235 } 236 237 // Ensure we will not run this same check again later on. 238 self::$transport[$cap_string] = ''; 193 239 // @codeCoverageIgnoreEnd 194 240 195 241 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 242 self::$transports = self::DEFAULT_TRANSPORTS; 243 } 244 245 // Find us a working transport. 203 246 foreach (self::$transports as $class) { 204 247 if (!class_exists($class)) { … … 206 249 } 207 250 208 $result = call_user_func(array($class, 'test'),$capabilities);209 if ($result ) {251 $result = $class::test($capabilities); 252 if ($result === true) { 210 253 self::$transport[$cap_string] = $class; 211 254 break; 212 255 } 213 256 } 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]; 257 258 return self::$transport[$cap_string]; 259 } 260 261 /** 262 * Get a working transport. 263 * 264 * @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`. 265 * @return \WpOrg\Requests\Transport 266 * @throws \WpOrg\Requests\Exception If no valid transport is found (`notransport`). 267 */ 268 protected static function get_transport(array $capabilities = []) { 269 $class = self::get_transport_class($capabilities); 270 271 if ($class === '') { 272 throw new Exception('No working transports found', 'notransport', self::$transports); 273 } 274 219 275 return new $class(); 220 276 } 221 277 278 /** 279 * Checks to see if we have a transport for the capabilities requested. 280 * 281 * Supported capabilities can be found in the {@see \WpOrg\Requests\Capability} 282 * interface as constants. 283 * 284 * Example usage: 285 * `Requests::has_capabilities([Capability::SSL => true])`. 286 * 287 * @param array<string, bool> $capabilities Optional. Associative array of capabilities to test against, i.e. `['<capability>' => true]`. 288 * @return bool Whether the transport has the requested capabilities. 289 */ 290 public static function has_capabilities(array $capabilities = []) { 291 return self::get_transport_class($capabilities) !== ''; 292 } 293 222 294 /**#@+ 223 * @see request()295 * @see \WpOrg\Requests\Requests::request() 224 296 * @param string $url 225 297 * @param array $headers 226 298 * @param array $options 227 * @return Requests_Response299 * @return \WpOrg\Requests\Response 228 300 */ 229 301 /** 230 302 * Send a GET request 231 303 */ 232 public static function get($url, $headers = array(), $options = array()) {304 public static function get($url, $headers = [], $options = []) { 233 305 return self::request($url, $headers, null, self::GET, $options); 234 306 } … … 237 309 * Send a HEAD request 238 310 */ 239 public static function head($url, $headers = array(), $options = array()) {311 public static function head($url, $headers = [], $options = []) { 240 312 return self::request($url, $headers, null, self::HEAD, $options); 241 313 } … … 244 316 * Send a DELETE request 245 317 */ 246 public static function delete($url, $headers = array(), $options = array()) {318 public static function delete($url, $headers = [], $options = []) { 247 319 return self::request($url, $headers, null, self::DELETE, $options); 248 320 } … … 251 323 * Send a TRACE request 252 324 */ 253 public static function trace($url, $headers = array(), $options = array()) {325 public static function trace($url, $headers = [], $options = []) { 254 326 return self::request($url, $headers, null, self::TRACE, $options); 255 327 } … … 257 329 258 330 /**#@+ 259 * @see request()331 * @see \WpOrg\Requests\Requests::request() 260 332 * @param string $url 261 333 * @param array $headers 262 334 * @param array $data 263 335 * @param array $options 264 * @return Requests_Response336 * @return \WpOrg\Requests\Response 265 337 */ 266 338 /** 267 339 * Send a POST request 268 340 */ 269 public static function post($url, $headers = array(), $data = array(), $options = array()) {341 public static function post($url, $headers = [], $data = [], $options = []) { 270 342 return self::request($url, $headers, $data, self::POST, $options); 271 343 } … … 273 345 * Send a PUT request 274 346 */ 275 public static function put($url, $headers = array(), $data = array(), $options = array()) {347 public static function put($url, $headers = [], $data = [], $options = []) { 276 348 return self::request($url, $headers, $data, self::PUT, $options); 277 349 } … … 280 352 * Send an OPTIONS request 281 353 */ 282 public static function options($url, $headers = array(), $data = array(), $options = array()) {354 public static function options($url, $headers = [], $data = [], $options = []) { 283 355 return self::request($url, $headers, $data, self::OPTIONS, $options); 284 356 } … … 287 359 * Send a PATCH request 288 360 * 289 * Note: Unlike {@see post} and {@see put}, `$headers` is required, as the290 * specification recommends that should send an ETag361 * Note: Unlike {@see \WpOrg\Requests\Requests::post()} and {@see \WpOrg\Requests\Requests::put()}, 362 * `$headers` is required, as the specification recommends that should send an ETag 291 363 * 292 364 * @link https://tools.ietf.org/html/rfc5789 293 365 */ 294 public static function patch($url, $headers, $data = array(), $options = array()) {366 public static function patch($url, $headers, $data = [], $options = []) { 295 367 return self::request($url, $headers, $data, self::PATCH, $options); 296 368 } … … 324 396 * - `auth`: Authentication handler or array of user/password details to use 325 397 * for Basic authentication 326 * ( Requests_Auth|array|boolean, default: false)398 * (\WpOrg\Requests\Auth|array|boolean, default: false) 327 399 * - `proxy`: Proxy details to use for proxy by-passing and authentication 328 * ( Requests_Proxy|array|string|boolean, default: false)400 * (\WpOrg\Requests\Proxy|array|string|boolean, default: false) 329 401 * - `max_bytes`: Limit for the response body size. 330 402 * (integer|boolean, default: false) … … 333 405 * - `transport`: Custom transport. Either a class name, or a 334 406 * transport object. Defaults to the first working transport from 335 * {@see getTransport()}336 * (string| Requests_Transport, default: {@seegetTransport()})407 * {@see \WpOrg\Requests\Requests::getTransport()} 408 * (string|\WpOrg\Requests\Transport, default: {@see \WpOrg\Requests\Requests::getTransport()}) 337 409 * - `hooks`: Hooks handler. 338 * ( Requests_Hooker, default: new Requests_Hooks())410 * (\WpOrg\Requests\HookManager, default: new WpOrg\Requests\Hooks()) 339 411 * - `verify`: Should we verify SSL certificates? Allows passing in a custom 340 412 * certificate file as a string. (Using true uses the system-wide root 341 413 * certificate store instead, but this may have different behaviour 342 414 * across transports.) 343 * (string|boolean, default: library/Requests/Transport/cacert.pem)415 * (string|boolean, default: certificates/cacert.pem) 344 416 * - `verifyname`: Should we verify the common name in the SSL certificate? 345 417 * (boolean, default: true) … … 348 420 * HEAD/GET/DELETE, 'body' for POST/PUT/OPTIONS/PATCH) 349 421 * 350 * @throws Requests_Exception On invalid URLs (`nonhttp`) 351 * 352 * @param string $url URL to request 422 * @param string|Stringable $url URL to request 353 423 * @param array $headers Extra headers to send with the request 354 424 * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests 355 425 * @param string $type HTTP request type (use Requests constants) 356 426 * @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()) { 427 * @return \WpOrg\Requests\Response 428 * 429 * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $url argument is not a string or Stringable. 430 * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $type argument is not a string. 431 * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array. 432 * @throws \WpOrg\Requests\Exception On invalid URLs (`nonhttp`) 433 */ 434 public static function request($url, $headers = [], $data = [], $type = self::GET, $options = []) { 435 if (InputValidator::is_string_or_stringable($url) === false) { 436 throw InvalidArgument::create(1, '$url', 'string|Stringable', gettype($url)); 437 } 438 439 if (is_string($type) === false) { 440 throw InvalidArgument::create(4, '$type', 'string', gettype($type)); 441 } 442 443 if (is_array($options) === false) { 444 throw InvalidArgument::create(5, '$options', 'array', gettype($options)); 445 } 446 360 447 if (empty($options['type'])) { 361 448 $options['type'] = $type; … … 365 452 self::set_defaults($url, $headers, $data, $type, $options); 366 453 367 $options['hooks']->dispatch('requests.before_request', array(&$url, &$headers, &$data, &$type, &$options));454 $options['hooks']->dispatch('requests.before_request', [&$url, &$headers, &$data, &$type, &$options]); 368 455 369 456 if (!empty($options['transport'])) { … … 376 463 else { 377 464 $need_ssl = (stripos($url, 'https://') === 0); 378 $capabilities = array('ssl' => $need_ssl);465 $capabilities = [Capability::SSL => $need_ssl]; 379 466 $transport = self::get_transport($capabilities); 380 467 } 381 468 $response = $transport->request($url, $headers, $data, $options); 382 469 383 $options['hooks']->dispatch('requests.before_parse', array(&$response, $url, $headers, $data, $type, $options));470 $options['hooks']->dispatch('requests.before_parse', [&$response, $url, $headers, $data, $type, $options]); 384 471 385 472 return self::parse_response($response, $url, $headers, $data, $options); … … 397 484 * 398 485 * - `url`: Request URL Same as the `$url` parameter to 399 * {@see Requests::request}486 * {@see \WpOrg\Requests\Requests::request()} 400 487 * (string, required) 401 488 * - `headers`: Associative array of header fields. Same as the `$headers` 402 * parameter to {@see Requests::request}489 * parameter to {@see \WpOrg\Requests\Requests::request()} 403 490 * (array, default: `array()`) 404 491 * - `data`: Associative array of data fields or a string. Same as the 405 * `$data` parameter to {@see Requests::request}492 * `$data` parameter to {@see \WpOrg\Requests\Requests::request()} 406 493 * (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`)494 * - `type`: HTTP request type (use \WpOrg\Requests\Requests constants). Same as the `$type` 495 * parameter to {@see \WpOrg\Requests\Requests::request()} 496 * (string, default: `\WpOrg\Requests\Requests::GET`) 410 497 * - `cookies`: Associative array of cookie name to value, or cookie jar. 411 * (array| Requests_Cookie_Jar)498 * (array|\WpOrg\Requests\Cookie\Jar) 412 499 * 413 500 * If the `$options` parameter is specified, individual requests will 414 501 * 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.502 * or set all the types to `\WpOrg\Requests\Requests::POST`, for example. 416 503 * 417 504 * In addition, the `$options` parameter takes the following global options: 418 505 * 419 506 * - `complete`: A callback for when a request is complete. Takes two 420 * parameters, a Requests_Response/Requests_Exception reference, and the507 * parameters, a \WpOrg\Requests\Response/\WpOrg\Requests\Exception reference, and the 421 508 * ID from the request array (Note: this can also be overridden on a 422 509 * per-request basis, although that's a little silly) … … 424 511 * 425 512 * @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()) { 513 * @param array $options Global and default options (see {@see \WpOrg\Requests\Requests::request()}) 514 * @return array Responses (either \WpOrg\Requests\Response or a \WpOrg\Requests\Exception object) 515 * 516 * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $requests argument is not an array or iterable object with array access. 517 * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $options argument is not an array. 518 */ 519 public static function request_multiple($requests, $options = []) { 520 if (InputValidator::has_array_access($requests) === false || InputValidator::is_iterable($requests) === false) { 521 throw InvalidArgument::create(1, '$requests', 'array|ArrayAccess&Traversable', gettype($requests)); 522 } 523 524 if (is_array($options) === false) { 525 throw InvalidArgument::create(2, '$options', 'array', gettype($options)); 526 } 527 430 528 $options = array_merge(self::get_default_options(true), $options); 431 529 432 530 if (!empty($options['hooks'])) { 433 $options['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple'));531 $options['hooks']->register('transport.internal.parse_response', [static::class, 'parse_multiple']); 434 532 if (!empty($options['complete'])) { 435 533 $options['hooks']->register('multiple.request.complete', $options['complete']); … … 439 537 foreach ($requests as $id => &$request) { 440 538 if (!isset($request['headers'])) { 441 $request['headers'] = array();539 $request['headers'] = []; 442 540 } 443 541 if (!isset($request['data'])) { 444 $request['data'] = array();542 $request['data'] = []; 445 543 } 446 544 if (!isset($request['type'])) { … … 462 560 // Ensure we only hook in once 463 561 if ($request['options']['hooks'] !== $options['hooks']) { 464 $request['options']['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple'));562 $request['options']['hooks']->register('transport.internal.parse_response', [static::class, 'parse_multiple']); 465 563 if (!empty($request['options']['complete'])) { 466 564 $request['options']['hooks']->register('multiple.request.complete', $request['options']['complete']); … … 488 586 $request = $requests[$id]; 489 587 self::parse_multiple($response, $request); 490 $request['options']['hooks']->dispatch('multiple.request.complete', array(&$response, $id));588 $request['options']['hooks']->dispatch('multiple.request.complete', [&$response, $id]); 491 589 } 492 590 } … … 498 596 * Get the default options 499 597 * 500 * @see Requests::request() for values returned by this method598 * @see \WpOrg\Requests\Requests::request() for values returned by this method 501 599 * @param boolean $multirequest Is this a multirequest? 502 600 * @return array Default option values 503 601 */ 504 602 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 ); 603 $defaults = static::OPTION_DEFAULTS; 604 $defaults['verify'] = self::$certificate_path; 605 526 606 if ($multirequest !== false) { 527 607 $defaults['complete'] = null; … … 536 616 */ 537 617 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'; 618 return self::$certificate_path; 543 619 } 544 620 … … 546 622 * Set default certificate path. 547 623 * 548 * @param string $path Certificate path, pointing to a PEM file. 624 * @param string|Stringable|bool $path Certificate path, pointing to a PEM file. 625 * 626 * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed $url argument is not a string, Stringable or boolean. 549 627 */ 550 628 public static function set_certificate_path($path) { 629 if (InputValidator::is_string_or_stringable($path) === false && is_bool($path) === false) { 630 throw InvalidArgument::create(1, '$path', 'string|Stringable|bool', gettype($path)); 631 } 632 551 633 self::$certificate_path = $path; 552 634 } … … 560 642 * @param string $type HTTP request type 561 643 * @param array $options Options for the request 562 * @return array $options 644 * @return void $options is updated with the results 645 * 646 * @throws \WpOrg\Requests\Exception When the $url is not an http(s) URL. 563 647 */ 564 648 protected static function set_defaults(&$url, &$headers, &$data, &$type, &$options) { 565 649 if (!preg_match('/^http(s)?:\/\//i', $url, $matches)) { 566 throw new Requests_Exception('Only HTTP(S) requests are handled.', 'nonhttp', $url);650 throw new Exception('Only HTTP(S) requests are handled.', 'nonhttp', $url); 567 651 } 568 652 569 653 if (empty($options['hooks'])) { 570 $options['hooks'] = new Requests_Hooks();654 $options['hooks'] = new Hooks(); 571 655 } 572 656 573 657 if (is_array($options['auth'])) { 574 $options['auth'] = new Requests_Auth_Basic($options['auth']);658 $options['auth'] = new Basic($options['auth']); 575 659 } 576 660 if ($options['auth'] !== false) { … … 579 663 580 664 if (is_string($options['proxy']) || is_array($options['proxy'])) { 581 $options['proxy'] = new Requests_Proxy_HTTP($options['proxy']);665 $options['proxy'] = new Http($options['proxy']); 582 666 } 583 667 if ($options['proxy'] !== false) { … … 586 670 587 671 if (is_array($options['cookies'])) { 588 $options['cookies'] = new Requests_Cookie_Jar($options['cookies']);672 $options['cookies'] = new Jar($options['cookies']); 589 673 } 590 674 elseif (empty($options['cookies'])) { 591 $options['cookies'] = new Requests_Cookie_Jar();675 $options['cookies'] = new Jar(); 592 676 } 593 677 if ($options['cookies'] !== false) { … … 596 680 597 681 if ($options['idn'] !== false) { 598 $iri = new Requests_IRI($url);599 $iri->host = Requests_IDNAEncoder::encode($iri->ihost);682 $iri = new Iri($url); 683 $iri->host = IdnaEncoder::encode($iri->ihost); 600 684 $url = $iri->uri; 601 685 } … … 605 689 606 690 if (!isset($options['data_format'])) { 607 if (in_array($type, array(self::HEAD, self::GET, self::DELETE), true)) {691 if (in_array($type, [self::HEAD, self::GET, self::DELETE], true)) { 608 692 $options['data_format'] = 'query'; 609 693 } … … 616 700 /** 617 701 * 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 702 * 623 703 * @param string $headers Full response text including headers and body … … 626 706 * @param array $req_data Original $data array passed to {@link request()}, in case we need to follow redirects 627 707 * @param array $options Original $options array passed to {@link request()}, in case we need to follow redirects 628 * @return Requests_Response 708 * @return \WpOrg\Requests\Response 709 * 710 * @throws \WpOrg\Requests\Exception On missing head/body separator (`requests.no_crlf_separator`) 711 * @throws \WpOrg\Requests\Exception On missing head/body separator (`noversion`) 712 * @throws \WpOrg\Requests\Exception On missing head/body separator (`toomanyredirects`) 629 713 */ 630 714 protected static function parse_response($headers, $url, $req_headers, $req_data, $options) { 631 $return = new Re quests_Response();715 $return = new Response(); 632 716 if (!$options['blocking']) { 633 717 return $return; … … 642 726 if ($pos === false) { 643 727 // Crap! 644 throw new Requests_Exception('Missing header/body separator', 'requests.no_crlf_separator');728 throw new Exception('Missing header/body separator', 'requests.no_crlf_separator'); 645 729 } 646 730 … … 659 743 preg_match('#^HTTP/(1\.\d)[ \t]+(\d+)#i', array_shift($headers), $matches); 660 744 if (empty($matches)) { 661 throw new Requests_Exception('Response could not be parsed', 'noversion', $headers);745 throw new Exception('Response could not be parsed', 'noversion', $headers); 662 746 } 663 747 $return->protocol_version = (float) $matches[1]; … … 686 770 } 687 771 688 $options['hooks']->dispatch('requests.before_redirect_check', array(&$return, $req_headers, $req_data, $options));772 $options['hooks']->dispatch('requests.before_redirect_check', [&$return, $req_headers, $req_data, $options]); 689 773 690 774 if ($return->is_redirect() && $options['follow_redirects'] === true) { … … 697 781 if (strpos($location, 'http://') !== 0 && strpos($location, 'https://') !== 0) { 698 782 // relative redirect, for compatibility make it absolute 699 $location = Requests_IRI::absolutize($url, $location);783 $location = Iri::absolutize($url, $location); 700 784 $location = $location->uri; 701 785 } 702 786 703 $hook_args = array(787 $hook_args = [ 704 788 &$location, 705 789 &$req_headers, … … 707 791 &$options, 708 792 $return, 709 );793 ]; 710 794 $options['hooks']->dispatch('requests.before_redirect', $hook_args); 711 795 $redirected = self::request($location, $req_headers, $req_data, $options['type'], $options); … … 714 798 } 715 799 elseif ($options['redirected'] >= $options['redirects']) { 716 throw new Requests_Exception('Too many redirects', 'toomanyredirects', $return);800 throw new Exception('Too many redirects', 'toomanyredirects', $return); 717 801 } 718 802 } … … 720 804 $return->redirects = $options['redirected']; 721 805 722 $options['hooks']->dispatch('requests.after_request', array(&$return, $req_headers, $req_data, $options));806 $options['hooks']->dispatch('requests.after_request', [&$return, $req_headers, $req_data, $options]); 723 807 return $return; 724 808 } … … 727 811 * Callback for `transport.internal.parse_response` 728 812 * 729 * Internal use only. Converts a raw HTTP response to a Requests_Response813 * Internal use only. Converts a raw HTTP response to a \WpOrg\Requests\Response 730 814 * while still executing a multiple request. 731 815 * 732 816 * @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 object817 * @param array $request Request data as passed into {@see \WpOrg\Requests\Requests::request_multiple()} 818 * @return void `$response` is either set to a \WpOrg\Requests\Response instance, or a \WpOrg\Requests\Exception object 735 819 */ 736 820 public static function parse_multiple(&$response, $request) { … … 742 826 $response = self::parse_response($response, $url, $headers, $data, $options); 743 827 } 744 catch ( Requests_Exception $e) {828 catch (Exception $e) { 745 829 $response = $e; 746 830 } … … 750 834 * Decoded a chunked body as per RFC 2616 751 835 * 752 * @ seehttps://tools.ietf.org/html/rfc2616#section-3.6.1836 * @link https://tools.ietf.org/html/rfc2616#section-3.6.1 753 837 * @param string $data Chunked body 754 838 * @return string Decoded body … … 792 876 * Convert a key => value array to a 'key: value' array for headers 793 877 * 794 * @param array $array Dictionary of header values878 * @param iterable $dictionary Dictionary of header values 795 879 * @return array List of headers 796 */ 797 public static function flatten($array) { 798 $return = array(); 799 foreach ($array as $key => $value) { 880 * 881 * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not iterable. 882 */ 883 public static function flatten($dictionary) { 884 if (InputValidator::is_iterable($dictionary) === false) { 885 throw InvalidArgument::create(1, '$dictionary', 'iterable', gettype($dictionary)); 886 } 887 888 $return = []; 889 foreach ($dictionary as $key => $value) { 800 890 $return[] = sprintf('%s: %s', $key, $value); 801 891 } 802 892 return $return; 803 }804 805 /**806 * Convert a key => value array to a 'key: value' array for headers807 *808 * @codeCoverageIgnore809 * @deprecated Misspelling of {@see Requests::flatten}810 * @param array $array Dictionary of header values811 * @return array List of headers812 */813 public static function flattern($array) {814 return self::flatten($array);815 893 } 816 894 … … 823 901 * @param string $data Compressed data in one of the above formats 824 902 * @return string Decompressed string 903 * 904 * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string. 825 905 */ 826 906 public static function decompress($data) { 827 if (substr($data, 0, 2) !== "\x1f\x8b" && substr($data, 0, 2) !== "\x78\x9c") { 907 if (is_string($data) === false) { 908 throw InvalidArgument::create(1, '$data', 'string', gettype($data)); 909 } 910 911 if (trim($data) === '') { 912 // Empty body does not need further processing. 913 return $data; 914 } 915 916 $marker = substr($data, 0, 2); 917 if (!isset(self::$magic_compression_headers[$marker])) { 828 918 // Not actually compressed. Probably cURL ruining this for us. 829 919 return $data; … … 831 921 832 922 if (function_exists('gzdecode')) { 833 // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.gzdecodeFound -- Wrapped in function_exists() for PHP 5.2.834 923 $decoded = @gzdecode($data); 835 924 if ($decoded !== false) { … … 872 961 * https://core.trac.wordpress.org/ticket/18273 873 962 * 874 * @since 2.8.1963 * @since 1.6.0 875 964 * @link https://core.trac.wordpress.org/ticket/18273 876 * @link https:// secure.php.net/manual/en/function.gzinflate.php#70875877 * @link https:// secure.php.net/manual/en/function.gzinflate.php#77336965 * @link https://www.php.net/gzinflate#70875 966 * @link https://www.php.net/gzinflate#77336 878 967 * 879 968 * @param string $gz_data String to decompress. 880 969 * @return string|bool False on failure. 970 * 971 * @throws \WpOrg\Requests\Exception\InvalidArgument When the passed argument is not a string. 881 972 */ 882 973 public static function compatible_gzinflate($gz_data) { 974 if (is_string($gz_data) === false) { 975 throw InvalidArgument::create(1, '$gz_data', 'string', gettype($gz_data)); 976 } 977 978 if (trim($gz_data) === '') { 979 return false; 980 } 981 883 982 // Compressed data might contain a full zlib header, if so strip it for 884 983 // gzinflate() … … 910 1009 // byte Huffman marker for gzinflate() 911 1010 // The response is Huffman coded by many compressors such as 912 // java.util.zip.Deflater, Ruby ’s Zlib::Deflate, and .NET's1011 // java.util.zip.Deflater, Ruby's Zlib::Deflate, and .NET's 913 1012 // System.IO.Compression.DeflateStream. 914 1013 // … … 978 1077 return false; 979 1078 } 980 981 public static function match_domain($host, $reference) {982 // Check for a direct match983 if ($host === $reference) {984 return true;985 }986 987 // Calculate the valid wildcard match if the host is not an IP address988 // Also validates that the host has 3 parts or more, as per Firefox's989 // 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;1000 }1001 1079 }
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)