changeset 16 | a86126ab1dd4 |
parent 9 | 177826044cd9 |
child 18 | be944660c56a |
15:3d4e9c994f10 | 16:a86126ab1dd4 |
---|---|
6 * @subpackage HTTP |
6 * @subpackage HTTP |
7 * @since 2.7.0 |
7 * @since 2.7.0 |
8 */ |
8 */ |
9 |
9 |
10 if ( ! class_exists( 'Requests' ) ) { |
10 if ( ! class_exists( 'Requests' ) ) { |
11 require( ABSPATH . WPINC . '/class-requests.php' ); |
11 require ABSPATH . WPINC . '/class-requests.php'; |
12 |
12 |
13 Requests::register_autoloader(); |
13 Requests::register_autoloader(); |
14 Requests::set_certificate_path( ABSPATH . WPINC . '/certificates/ca-bundle.crt' ); |
14 Requests::set_certificate_path( ABSPATH . WPINC . '/certificates/ca-bundle.crt' ); |
15 } |
15 } |
16 |
16 |
107 * |
107 * |
108 * @type string $method Request method. Accepts 'GET', 'POST', 'HEAD', 'PUT', 'DELETE', |
108 * @type string $method Request method. Accepts 'GET', 'POST', 'HEAD', 'PUT', 'DELETE', |
109 * 'TRACE', 'OPTIONS', or 'PATCH'. |
109 * 'TRACE', 'OPTIONS', or 'PATCH'. |
110 * Some transports technically allow others, but should not be |
110 * Some transports technically allow others, but should not be |
111 * assumed. Default 'GET'. |
111 * assumed. Default 'GET'. |
112 * @type int $timeout How long the connection should stay open in seconds. Default 5. |
112 * @type float $timeout How long the connection should stay open in seconds. Default 5. |
113 * @type int $redirection Number of allowed redirects. Not supported by all transports |
113 * @type int $redirection Number of allowed redirects. Not supported by all transports |
114 * Default 5. |
114 * Default 5. |
115 * @type string $httpversion Version of the HTTP protocol to use. Accepts '1.0' and '1.1'. |
115 * @type string $httpversion Version of the HTTP protocol to use. Accepts '1.0' and '1.1'. |
116 * Default '1.0'. |
116 * Default '1.0'. |
117 * @type string $user-agent User-agent value sent. |
117 * @type string $user-agent User-agent value sent. |
131 * Default false. |
131 * Default false. |
132 * @type bool $decompress Whether to decompress a compressed response. If set to false and |
132 * @type bool $decompress Whether to decompress a compressed response. If set to false and |
133 * compressed content is returned in the response anyway, it will |
133 * compressed content is returned in the response anyway, it will |
134 * need to be separately decompressed. Default true. |
134 * need to be separately decompressed. Default true. |
135 * @type bool $sslverify Whether to verify SSL for the request. Default true. |
135 * @type bool $sslverify Whether to verify SSL for the request. Default true. |
136 * @type string sslcertificates Absolute path to an SSL certificate .crt file. |
136 * @type string $sslcertificates Absolute path to an SSL certificate .crt file. |
137 * Default ABSPATH . WPINC . '/certificates/ca-bundle.crt'. |
137 * Default ABSPATH . WPINC . '/certificates/ca-bundle.crt'. |
138 * @type bool $stream Whether to stream to a file. If set to true and no filename was |
138 * @type bool $stream Whether to stream to a file. If set to true and no filename was |
139 * given, it will be droped it in the WP temp dir and its name will |
139 * given, it will be droped it in the WP temp dir and its name will |
140 * be set using the basename of the URL. Default false. |
140 * be set using the basename of the URL. Default false. |
141 * @type string $filename Filename of the file to write to when streaming. $stream must be |
141 * @type string $filename Filename of the file to write to when streaming. $stream must be |
153 * Filters the timeout value for an HTTP request. |
153 * Filters the timeout value for an HTTP request. |
154 * |
154 * |
155 * @since 2.7.0 |
155 * @since 2.7.0 |
156 * @since 5.1.0 The `$url` parameter was added. |
156 * @since 5.1.0 The `$url` parameter was added. |
157 * |
157 * |
158 * @param int $timeout_value Time in seconds until a request times out. Default 5. |
158 * @param float $timeout_value Time in seconds until a request times out. Default 5. |
159 * @param string $url The request URL. |
159 * @param string $url The request URL. |
160 */ |
160 */ |
161 'timeout' => apply_filters( 'http_request_timeout', 5, $url ), |
161 'timeout' => apply_filters( 'http_request_timeout', 5, $url ), |
162 /** |
162 /** |
163 * Filters the number of redirects allowed during an HTTP request. |
163 * Filters the number of redirects allowed during an HTTP request. |
213 ); |
213 ); |
214 |
214 |
215 // Pre-parse for the HEAD checks. |
215 // Pre-parse for the HEAD checks. |
216 $args = wp_parse_args( $args ); |
216 $args = wp_parse_args( $args ); |
217 |
217 |
218 // By default, Head requests do not cause redirections. |
218 // By default, HEAD requests do not cause redirections. |
219 if ( isset( $args['method'] ) && 'HEAD' == $args['method'] ) { |
219 if ( isset( $args['method'] ) && 'HEAD' === $args['method'] ) { |
220 $defaults['redirection'] = 0; |
220 $defaults['redirection'] = 0; |
221 } |
221 } |
222 |
222 |
223 $r = wp_parse_args( $args, $defaults ); |
223 $parsed_args = wp_parse_args( $args, $defaults ); |
224 /** |
224 /** |
225 * Filters the arguments used in an HTTP request. |
225 * Filters the arguments used in an HTTP request. |
226 * |
226 * |
227 * @since 2.7.0 |
227 * @since 2.7.0 |
228 * |
228 * |
229 * @param array $r An array of HTTP request arguments. |
229 * @param array $parsed_args An array of HTTP request arguments. |
230 * @param string $url The request URL. |
230 * @param string $url The request URL. |
231 */ |
231 */ |
232 $r = apply_filters( 'http_request_args', $r, $url ); |
232 $parsed_args = apply_filters( 'http_request_args', $parsed_args, $url ); |
233 |
233 |
234 // The transports decrement this, store a copy of the original value for loop purposes. |
234 // The transports decrement this, store a copy of the original value for loop purposes. |
235 if ( ! isset( $r['_redirection'] ) ) { |
235 if ( ! isset( $parsed_args['_redirection'] ) ) { |
236 $r['_redirection'] = $r['redirection']; |
236 $parsed_args['_redirection'] = $parsed_args['redirection']; |
237 } |
237 } |
238 |
238 |
239 /** |
239 /** |
240 * Filters whether to preempt an HTTP request's return value. |
240 * Filters the preemptive return value of an HTTP request. |
241 * |
241 * |
242 * Returning a non-false value from the filter will short-circuit the HTTP request and return |
242 * Returning a non-false value from the filter will short-circuit the HTTP request and return |
243 * early with that value. A filter should return either: |
243 * early with that value. A filter should return one of: |
244 * |
244 * |
245 * - An array containing 'headers', 'body', 'response', 'cookies', and 'filename' elements |
245 * - An array containing 'headers', 'body', 'response', 'cookies', and 'filename' elements |
246 * - A WP_Error instance |
246 * - A WP_Error instance |
247 * - boolean false (to avoid short-circuiting the response) |
247 * - boolean false to avoid short-circuiting the response |
248 * |
248 * |
249 * Returning any other value may result in unexpected behaviour. |
249 * Returning any other value may result in unexpected behaviour. |
250 * |
250 * |
251 * @since 2.9.0 |
251 * @since 2.9.0 |
252 * |
252 * |
253 * @param false|array|WP_Error $preempt Whether to preempt an HTTP request's return value. Default false. |
253 * @param false|array|WP_Error $preempt A preemptive return value of an HTTP request. Default false. |
254 * @param array $r HTTP request arguments. |
254 * @param array $parsed_args HTTP request arguments. |
255 * @param string $url The request URL. |
255 * @param string $url The request URL. |
256 */ |
256 */ |
257 $pre = apply_filters( 'pre_http_request', false, $r, $url ); |
257 $pre = apply_filters( 'pre_http_request', false, $parsed_args, $url ); |
258 |
258 |
259 if ( false !== $pre ) { |
259 if ( false !== $pre ) { |
260 return $pre; |
260 return $pre; |
261 } |
261 } |
262 |
262 |
263 if ( function_exists( 'wp_kses_bad_protocol' ) ) { |
263 if ( function_exists( 'wp_kses_bad_protocol' ) ) { |
264 if ( $r['reject_unsafe_urls'] ) { |
264 if ( $parsed_args['reject_unsafe_urls'] ) { |
265 $url = wp_http_validate_url( $url ); |
265 $url = wp_http_validate_url( $url ); |
266 } |
266 } |
267 if ( $url ) { |
267 if ( $url ) { |
268 $url = wp_kses_bad_protocol( $url, array( 'http', 'https', 'ssl' ) ); |
268 $url = wp_kses_bad_protocol( $url, array( 'http', 'https', 'ssl' ) ); |
269 } |
269 } |
270 } |
270 } |
271 |
271 |
272 $arrURL = @parse_url( $url ); |
272 $arrURL = parse_url( $url ); |
273 |
273 |
274 if ( empty( $url ) || empty( $arrURL['scheme'] ) ) { |
274 if ( empty( $url ) || empty( $arrURL['scheme'] ) ) { |
275 return new WP_Error( 'http_request_failed', __( 'A valid URL was not provided.' ) ); |
275 $response = new WP_Error( 'http_request_failed', __( 'A valid URL was not provided.' ) ); |
276 /** This action is documented in wp-includes/class-http.php */ |
|
277 do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url ); |
|
278 return $response; |
|
276 } |
279 } |
277 |
280 |
278 if ( $this->block_request( $url ) ) { |
281 if ( $this->block_request( $url ) ) { |
279 return new WP_Error( 'http_request_failed', __( 'User has blocked requests through HTTP.' ) ); |
282 $response = new WP_Error( 'http_request_not_executed', __( 'User has blocked requests through HTTP.' ) ); |
283 /** This action is documented in wp-includes/class-http.php */ |
|
284 do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url ); |
|
285 return $response; |
|
280 } |
286 } |
281 |
287 |
282 // If we are streaming to a file but no filename was given drop it in the WP temp dir |
288 // If we are streaming to a file but no filename was given drop it in the WP temp dir |
283 // and pick its name using the basename of the $url |
289 // and pick its name using the basename of the $url. |
284 if ( $r['stream'] ) { |
290 if ( $parsed_args['stream'] ) { |
285 if ( empty( $r['filename'] ) ) { |
291 if ( empty( $parsed_args['filename'] ) ) { |
286 $r['filename'] = get_temp_dir() . basename( $url ); |
292 $parsed_args['filename'] = get_temp_dir() . basename( $url ); |
287 } |
293 } |
288 |
294 |
289 // Force some settings if we are streaming to a file and check for existence and perms of destination directory |
295 // Force some settings if we are streaming to a file and check for existence |
290 $r['blocking'] = true; |
296 // and perms of destination directory. |
291 if ( ! wp_is_writable( dirname( $r['filename'] ) ) ) { |
297 $parsed_args['blocking'] = true; |
292 return new WP_Error( 'http_request_failed', __( 'Destination directory for file streaming does not exist or is not writable.' ) ); |
298 if ( ! wp_is_writable( dirname( $parsed_args['filename'] ) ) ) { |
293 } |
299 $response = new WP_Error( 'http_request_failed', __( 'Destination directory for file streaming does not exist or is not writable.' ) ); |
294 } |
300 /** This action is documented in wp-includes/class-http.php */ |
295 |
301 do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url ); |
296 if ( is_null( $r['headers'] ) ) { |
302 return $response; |
297 $r['headers'] = array(); |
303 } |
304 } |
|
305 |
|
306 if ( is_null( $parsed_args['headers'] ) ) { |
|
307 $parsed_args['headers'] = array(); |
|
298 } |
308 } |
299 |
309 |
300 // WP allows passing in headers as a string, weirdly. |
310 // WP allows passing in headers as a string, weirdly. |
301 if ( ! is_array( $r['headers'] ) ) { |
311 if ( ! is_array( $parsed_args['headers'] ) ) { |
302 $processedHeaders = WP_Http::processHeaders( $r['headers'] ); |
312 $processedHeaders = WP_Http::processHeaders( $parsed_args['headers'] ); |
303 $r['headers'] = $processedHeaders['headers']; |
313 $parsed_args['headers'] = $processedHeaders['headers']; |
304 } |
314 } |
305 |
315 |
306 // Setup arguments |
316 // Setup arguments. |
307 $headers = $r['headers']; |
317 $headers = $parsed_args['headers']; |
308 $data = $r['body']; |
318 $data = $parsed_args['body']; |
309 $type = $r['method']; |
319 $type = $parsed_args['method']; |
310 $options = array( |
320 $options = array( |
311 'timeout' => $r['timeout'], |
321 'timeout' => $parsed_args['timeout'], |
312 'useragent' => $r['user-agent'], |
322 'useragent' => $parsed_args['user-agent'], |
313 'blocking' => $r['blocking'], |
323 'blocking' => $parsed_args['blocking'], |
314 'hooks' => new WP_HTTP_Requests_Hooks( $url, $r ), |
324 'hooks' => new WP_HTTP_Requests_Hooks( $url, $parsed_args ), |
315 ); |
325 ); |
316 |
326 |
317 // Ensure redirects follow browser behaviour. |
327 // Ensure redirects follow browser behaviour. |
318 $options['hooks']->register( 'requests.before_redirect', array( get_class(), 'browser_redirect_compatibility' ) ); |
328 $options['hooks']->register( 'requests.before_redirect', array( get_class(), 'browser_redirect_compatibility' ) ); |
319 |
329 |
320 // Validate redirected URLs. |
330 // Validate redirected URLs. |
321 if ( function_exists( 'wp_kses_bad_protocol' ) && $r['reject_unsafe_urls'] ) { |
331 if ( function_exists( 'wp_kses_bad_protocol' ) && $parsed_args['reject_unsafe_urls'] ) { |
322 $options['hooks']->register( 'requests.before_redirect', array( get_class(), 'validate_redirects' ) ); |
332 $options['hooks']->register( 'requests.before_redirect', array( get_class(), 'validate_redirects' ) ); |
323 } |
333 } |
324 |
334 |
325 if ( $r['stream'] ) { |
335 if ( $parsed_args['stream'] ) { |
326 $options['filename'] = $r['filename']; |
336 $options['filename'] = $parsed_args['filename']; |
327 } |
337 } |
328 if ( empty( $r['redirection'] ) ) { |
338 if ( empty( $parsed_args['redirection'] ) ) { |
329 $options['follow_redirects'] = false; |
339 $options['follow_redirects'] = false; |
330 } else { |
340 } else { |
331 $options['redirects'] = $r['redirection']; |
341 $options['redirects'] = $parsed_args['redirection']; |
332 } |
342 } |
333 |
343 |
334 // Use byte limit, if we can |
344 // Use byte limit, if we can. |
335 if ( isset( $r['limit_response_size'] ) ) { |
345 if ( isset( $parsed_args['limit_response_size'] ) ) { |
336 $options['max_bytes'] = $r['limit_response_size']; |
346 $options['max_bytes'] = $parsed_args['limit_response_size']; |
337 } |
347 } |
338 |
348 |
339 // If we've got cookies, use and convert them to Requests_Cookie. |
349 // If we've got cookies, use and convert them to Requests_Cookie. |
340 if ( ! empty( $r['cookies'] ) ) { |
350 if ( ! empty( $parsed_args['cookies'] ) ) { |
341 $options['cookies'] = WP_Http::normalize_cookies( $r['cookies'] ); |
351 $options['cookies'] = WP_Http::normalize_cookies( $parsed_args['cookies'] ); |
342 } |
352 } |
343 |
353 |
344 // SSL certificate handling |
354 // SSL certificate handling. |
345 if ( ! $r['sslverify'] ) { |
355 if ( ! $parsed_args['sslverify'] ) { |
346 $options['verify'] = false; |
356 $options['verify'] = false; |
347 $options['verifyname'] = false; |
357 $options['verifyname'] = false; |
348 } else { |
358 } else { |
349 $options['verify'] = $r['sslcertificates']; |
359 $options['verify'] = $parsed_args['sslcertificates']; |
350 } |
360 } |
351 |
361 |
352 // All non-GET/HEAD requests should put the arguments in the form body. |
362 // All non-GET/HEAD requests should put the arguments in the form body. |
353 if ( 'HEAD' !== $type && 'GET' !== $type ) { |
363 if ( 'HEAD' !== $type && 'GET' !== $type ) { |
354 $options['data_format'] = 'body'; |
364 $options['data_format'] = 'body'; |
375 $options['proxy']->user = $proxy->username(); |
385 $options['proxy']->user = $proxy->username(); |
376 $options['proxy']->pass = $proxy->password(); |
386 $options['proxy']->pass = $proxy->password(); |
377 } |
387 } |
378 } |
388 } |
379 |
389 |
380 // Avoid issues where mbstring.func_overload is enabled |
390 // Avoid issues where mbstring.func_overload is enabled. |
381 mbstring_binary_safe_encoding(); |
391 mbstring_binary_safe_encoding(); |
382 |
392 |
383 try { |
393 try { |
384 $requests_response = Requests::request( $url, $headers, $data, $type, $options ); |
394 $requests_response = Requests::request( $url, $headers, $data, $type, $options ); |
385 |
395 |
386 // Convert the response into an array |
396 // Convert the response into an array. |
387 $http_response = new WP_HTTP_Requests_Response( $requests_response, $r['filename'] ); |
397 $http_response = new WP_HTTP_Requests_Response( $requests_response, $parsed_args['filename'] ); |
388 $response = $http_response->to_array(); |
398 $response = $http_response->to_array(); |
389 |
399 |
390 // Add the original object to the array. |
400 // Add the original object to the array. |
391 $response['http_response'] = $http_response; |
401 $response['http_response'] = $http_response; |
392 } catch ( Requests_Exception $e ) { |
402 } catch ( Requests_Exception $e ) { |
398 /** |
408 /** |
399 * Fires after an HTTP API response is received and before the response is returned. |
409 * Fires after an HTTP API response is received and before the response is returned. |
400 * |
410 * |
401 * @since 2.8.0 |
411 * @since 2.8.0 |
402 * |
412 * |
403 * @param array|WP_Error $response HTTP response or WP_Error object. |
413 * @param array|WP_Error $response HTTP response or WP_Error object. |
404 * @param string $context Context under which the hook is fired. |
414 * @param string $context Context under which the hook is fired. |
405 * @param string $class HTTP transport used. |
415 * @param string $class HTTP transport used. |
406 * @param array $r HTTP request arguments. |
416 * @param array $parsed_args HTTP request arguments. |
407 * @param string $url The request URL. |
417 * @param string $url The request URL. |
408 */ |
418 */ |
409 do_action( 'http_api_debug', $response, 'response', 'Requests', $r, $url ); |
419 do_action( 'http_api_debug', $response, 'response', 'Requests', $parsed_args, $url ); |
410 if ( is_wp_error( $response ) ) { |
420 if ( is_wp_error( $response ) ) { |
411 return $response; |
421 return $response; |
412 } |
422 } |
413 |
423 |
414 if ( ! $r['blocking'] ) { |
424 if ( ! $parsed_args['blocking'] ) { |
415 return array( |
425 return array( |
416 'headers' => array(), |
426 'headers' => array(), |
417 'body' => '', |
427 'body' => '', |
418 'response' => array( |
428 'response' => array( |
419 'code' => false, |
429 'code' => false, |
427 /** |
437 /** |
428 * Filters the HTTP API response immediately before the response is returned. |
438 * Filters the HTTP API response immediately before the response is returned. |
429 * |
439 * |
430 * @since 2.9.0 |
440 * @since 2.9.0 |
431 * |
441 * |
432 * @param array $response HTTP response. |
442 * @param array $response HTTP response. |
433 * @param array $r HTTP request arguments. |
443 * @param array $parsed_args HTTP request arguments. |
434 * @param string $url The request URL. |
444 * @param string $url The request URL. |
435 */ |
445 */ |
436 return apply_filters( 'http_response', $response, $r, $url ); |
446 return apply_filters( 'http_response', $response, $parsed_args, $url ); |
437 } |
447 } |
438 |
448 |
439 /** |
449 /** |
440 * Normalizes cookies for using in Requests. |
450 * Normalizes cookies for using in Requests. |
441 * |
451 * |
472 * @param string|array $data Body to send with the request. |
482 * @param string|array $data Body to send with the request. |
473 * @param array $options Redirect request options. |
483 * @param array $options Redirect request options. |
474 * @param Requests_Response $original Response object. |
484 * @param Requests_Response $original Response object. |
475 */ |
485 */ |
476 public static function browser_redirect_compatibility( $location, $headers, $data, &$options, $original ) { |
486 public static function browser_redirect_compatibility( $location, $headers, $data, &$options, $original ) { |
477 // Browser compat |
487 // Browser compatibility. |
478 if ( $original->status_code === 302 ) { |
488 if ( 302 === $original->status_code ) { |
479 $options['type'] = Requests::GET; |
489 $options['type'] = Requests::GET; |
480 } |
490 } |
481 } |
491 } |
482 |
492 |
483 /** |
493 /** |
484 * Validate redirected URLs. |
494 * Validate redirected URLs. |
485 * |
495 * |
486 * @since 4.7.5 |
496 * @since 4.7.5 |
487 * |
497 * |
488 * @throws Requests_Exception On unsuccessful URL validation |
498 * @throws Requests_Exception On unsuccessful URL validation. |
489 * @param string $location URL to redirect to. |
499 * @param string $location URL to redirect to. |
490 */ |
500 */ |
491 public static function validate_redirects( $location ) { |
501 public static function validate_redirects( $location ) { |
492 if ( ! wp_http_validate_url( $location ) ) { |
502 if ( ! wp_http_validate_url( $location ) ) { |
493 throw new Requests_Exception( __( 'A valid URL was not provided.' ), 'wp_http.redirect_failed_validation' ); |
503 throw new Requests_Exception( __( 'A valid URL was not provided.' ), 'wp_http.redirect_failed_validation' ); |
497 /** |
507 /** |
498 * Tests which transports are capable of supporting the request. |
508 * Tests which transports are capable of supporting the request. |
499 * |
509 * |
500 * @since 3.2.0 |
510 * @since 3.2.0 |
501 * |
511 * |
502 * @param array $args Request arguments |
512 * @param array $args Request arguments. |
503 * @param string $url URL to Request |
513 * @param string $url URL to request. |
504 * |
514 * @return string|false Class name for the first transport that claims to support the request. |
505 * @return string|false Class name for the first transport that claims to support the request. False if no transport claims to support the request. |
515 * False if no transport claims to support the request. |
506 */ |
516 */ |
507 public function _get_first_available_transport( $args, $url = null ) { |
517 public function _get_first_available_transport( $args, $url = null ) { |
508 $transports = array( 'curl', 'streams' ); |
518 $transports = array( 'curl', 'streams' ); |
509 |
519 |
510 /** |
520 /** |
511 * Filters which HTTP transports are available and in what order. |
521 * Filters which HTTP transports are available and in what order. |
512 * |
522 * |
513 * @since 3.7.0 |
523 * @since 3.7.0 |
514 * |
524 * |
515 * @param array $transports Array of HTTP transports to check. Default array contains |
525 * @param string[] $transports Array of HTTP transports to check. Default array contains |
516 * 'curl', and 'streams', in that order. |
526 * 'curl' and 'streams', in that order. |
517 * @param array $args HTTP request arguments. |
527 * @param array $args HTTP request arguments. |
518 * @param string $url The URL to request. |
528 * @param string $url The URL to request. |
519 */ |
529 */ |
520 $request_order = apply_filters( 'http_api_transports', $transports, $args, $url ); |
530 $request_order = apply_filters( 'http_api_transports', $transports, $args, $url ); |
521 |
531 |
522 // Loop over each transport on each HTTP request looking for one which will serve this request's needs. |
532 // Loop over each transport on each HTTP request looking for one which will serve this request's needs. |
523 foreach ( $request_order as $transport ) { |
533 foreach ( $request_order as $transport ) { |
524 if ( in_array( $transport, $transports ) ) { |
534 if ( in_array( $transport, $transports, true ) ) { |
525 $transport = ucfirst( $transport ); |
535 $transport = ucfirst( $transport ); |
526 } |
536 } |
527 $class = 'WP_Http_' . $transport; |
537 $class = 'WP_Http_' . $transport; |
528 |
538 |
529 // Check to see if this transport is a possibility, calls the transport statically. |
539 // Check to see if this transport is a possibility, calls the transport statically. |
547 * |
557 * |
548 * @since 3.2.0 |
558 * @since 3.2.0 |
549 * @deprecated 5.1.0 Use WP_Http::request() |
559 * @deprecated 5.1.0 Use WP_Http::request() |
550 * @see WP_Http::request() |
560 * @see WP_Http::request() |
551 * |
561 * |
552 * @param string $url URL to Request |
562 * @param string $url URL to request. |
553 * @param array $args Request arguments |
563 * @param array $args Request arguments. |
554 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error |
564 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. |
565 * A WP_Error instance upon error. |
|
555 */ |
566 */ |
556 private function _dispatch_request( $url, $args ) { |
567 private function _dispatch_request( $url, $args ) { |
557 static $transports = array(); |
568 static $transports = array(); |
558 |
569 |
559 $class = $this->_get_first_available_transport( $args, $url ); |
570 $class = $this->_get_first_available_transport( $args, $url ); |
586 * |
597 * |
587 * @since 2.7.0 |
598 * @since 2.7.0 |
588 * |
599 * |
589 * @param string $url The request URL. |
600 * @param string $url The request URL. |
590 * @param string|array $args Optional. Override the defaults. |
601 * @param string|array $args Optional. Override the defaults. |
591 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error |
602 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. |
603 * A WP_Error instance upon error. |
|
592 */ |
604 */ |
593 public function post( $url, $args = array() ) { |
605 public function post( $url, $args = array() ) { |
594 $defaults = array( 'method' => 'POST' ); |
606 $defaults = array( 'method' => 'POST' ); |
595 $r = wp_parse_args( $args, $defaults ); |
607 $parsed_args = wp_parse_args( $args, $defaults ); |
596 return $this->request( $url, $r ); |
608 return $this->request( $url, $parsed_args ); |
597 } |
609 } |
598 |
610 |
599 /** |
611 /** |
600 * Uses the GET HTTP method. |
612 * Uses the GET HTTP method. |
601 * |
613 * |
602 * Used for sending data that is expected to be in the body. |
614 * Used for sending data that is expected to be in the body. |
603 * |
615 * |
604 * @since 2.7.0 |
616 * @since 2.7.0 |
605 * |
617 * |
606 * @param string $url The request URL. |
618 * @param string $url The request URL. |
607 * @param string|array $args Optional. Override the defaults. |
619 * @param string|array $args Optional. Override the defaults. |
608 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error |
620 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. |
621 * A WP_Error instance upon error. |
|
609 */ |
622 */ |
610 public function get( $url, $args = array() ) { |
623 public function get( $url, $args = array() ) { |
611 $defaults = array( 'method' => 'GET' ); |
624 $defaults = array( 'method' => 'GET' ); |
612 $r = wp_parse_args( $args, $defaults ); |
625 $parsed_args = wp_parse_args( $args, $defaults ); |
613 return $this->request( $url, $r ); |
626 return $this->request( $url, $parsed_args ); |
614 } |
627 } |
615 |
628 |
616 /** |
629 /** |
617 * Uses the HEAD HTTP method. |
630 * Uses the HEAD HTTP method. |
618 * |
631 * |
619 * Used for sending data that is expected to be in the body. |
632 * Used for sending data that is expected to be in the body. |
620 * |
633 * |
621 * @since 2.7.0 |
634 * @since 2.7.0 |
622 * |
635 * |
623 * @param string $url The request URL. |
636 * @param string $url The request URL. |
624 * @param string|array $args Optional. Override the defaults. |
637 * @param string|array $args Optional. Override the defaults. |
625 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. A WP_Error instance upon error |
638 * @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'. |
639 * A WP_Error instance upon error. |
|
626 */ |
640 */ |
627 public function head( $url, $args = array() ) { |
641 public function head( $url, $args = array() ) { |
628 $defaults = array( 'method' => 'HEAD' ); |
642 $defaults = array( 'method' => 'HEAD' ); |
629 $r = wp_parse_args( $args, $defaults ); |
643 $parsed_args = wp_parse_args( $args, $defaults ); |
630 return $this->request( $url, $r ); |
644 return $this->request( $url, $parsed_args ); |
631 } |
645 } |
632 |
646 |
633 /** |
647 /** |
634 * Parses the responses and splits the parts into headers and body. |
648 * Parses the responses and splits the parts into headers and body. |
635 * |
649 * |
636 * @since 2.7.0 |
650 * @since 2.7.0 |
637 * |
651 * |
638 * @param string $strResponse The full response string |
652 * @param string $strResponse The full response string. |
639 * @return array Array with 'headers' and 'body' keys. |
653 * @return array { |
640 */ |
654 * Array with response headers and body. |
641 public static function processResponse( $strResponse ) { |
655 * |
656 * @type string $headers HTTP response headers. |
|
657 * @type string $body HTTP response body. |
|
658 * } |
|
659 */ |
|
660 public static function processResponse( $strResponse ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid |
|
642 $res = explode( "\r\n\r\n", $strResponse, 2 ); |
661 $res = explode( "\r\n\r\n", $strResponse, 2 ); |
643 |
662 |
644 return array( |
663 return array( |
645 'headers' => $res[0], |
664 'headers' => $res[0], |
646 'body' => isset( $res[1] ) ? $res[1] : '', |
665 'body' => isset( $res[1] ) ? $res[1] : '', |
647 ); |
666 ); |
648 } |
667 } |
649 |
668 |
650 /** |
669 /** |
651 * Transform header string into an array. |
670 * Transforms header string into an array. |
652 * |
|
653 * If an array is given then it is assumed to be raw header data with numeric keys with the |
|
654 * headers as the values. No headers must be passed that were already processed. |
|
655 * |
671 * |
656 * @since 2.7.0 |
672 * @since 2.7.0 |
657 * |
673 * |
658 * @param string|array $headers |
674 * @param string|array $headers The original headers. If a string is passed, it will be converted |
659 * @param string $url The URL that was requested |
675 * to an array. If an array is passed, then it is assumed to be |
660 * @return array Processed string headers. If duplicate headers are encountered, |
676 * raw header data with numeric keys with the headers as the values. |
661 * Then a numbered array is returned as the value of that header-key. |
677 * No headers must be passed that were already processed. |
662 */ |
678 * @param string $url Optional. The URL that was requested. Default empty. |
663 public static function processHeaders( $headers, $url = '' ) { |
679 * @return array { |
680 * Processed string headers. If duplicate headers are encountered, |
|
681 * then a numbered array is returned as the value of that header-key. |
|
682 * |
|
683 * @type array $response { |
|
684 * @type int $code The response status code. Default 0. |
|
685 * @type string $message The response message. Default empty. |
|
686 * } |
|
687 * @type array $newheaders The processed header data as a multidimensional array. |
|
688 * @type WP_Http_Cookie[] $cookies If the original headers contain the 'Set-Cookie' key, |
|
689 * an array containing `WP_Http_Cookie` objects is returned. |
|
690 * } |
|
691 */ |
|
692 public static function processHeaders( $headers, $url = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid |
|
664 // Split headers, one per array element. |
693 // Split headers, one per array element. |
665 if ( is_string( $headers ) ) { |
694 if ( is_string( $headers ) ) { |
666 // Tolerate line terminator: CRLF = LF (RFC 2616 19.3). |
695 // Tolerate line terminator: CRLF = LF (RFC 2616 19.3). |
667 $headers = str_replace( "\r\n", "\n", $headers ); |
696 $headers = str_replace( "\r\n", "\n", $headers ); |
668 /* |
697 /* |
715 } |
744 } |
716 $newheaders[ $key ][] = $value; |
745 $newheaders[ $key ][] = $value; |
717 } else { |
746 } else { |
718 $newheaders[ $key ] = $value; |
747 $newheaders[ $key ] = $value; |
719 } |
748 } |
720 if ( 'set-cookie' == $key ) { |
749 if ( 'set-cookie' === $key ) { |
721 $cookies[] = new WP_Http_Cookie( $value, $url ); |
750 $cookies[] = new WP_Http_Cookie( $value, $url ); |
722 } |
751 } |
723 } |
752 } |
724 |
753 |
725 // Cast the Response Code to an int |
754 // Cast the Response Code to an int. |
726 $response['code'] = intval( $response['code'] ); |
755 $response['code'] = intval( $response['code'] ); |
727 |
756 |
728 return array( |
757 return array( |
729 'response' => $response, |
758 'response' => $response, |
730 'headers' => $newheaders, |
759 'headers' => $newheaders, |
741 * |
770 * |
742 * @since 2.8.0 |
771 * @since 2.8.0 |
743 * |
772 * |
744 * @param array $r Full array of args passed into ::request() |
773 * @param array $r Full array of args passed into ::request() |
745 */ |
774 */ |
746 public static function buildCookieHeader( &$r ) { |
775 public static function buildCookieHeader( &$r ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid |
747 if ( ! empty( $r['cookies'] ) ) { |
776 if ( ! empty( $r['cookies'] ) ) { |
748 // Upgrade any name => value cookie pairs to WP_HTTP_Cookie instances. |
777 // Upgrade any name => value cookie pairs to WP_HTTP_Cookie instances. |
749 foreach ( $r['cookies'] as $name => $value ) { |
778 foreach ( $r['cookies'] as $name => $value ) { |
750 if ( ! is_object( $value ) ) { |
779 if ( ! is_object( $value ) ) { |
751 $r['cookies'][ $name ] = new WP_Http_Cookie( |
780 $r['cookies'][ $name ] = new WP_Http_Cookie( |
774 * |
803 * |
775 * @link https://tools.ietf.org/html/rfc2616#section-19.4.6 Process for chunked decoding. |
804 * @link https://tools.ietf.org/html/rfc2616#section-19.4.6 Process for chunked decoding. |
776 * |
805 * |
777 * @since 2.7.0 |
806 * @since 2.7.0 |
778 * |
807 * |
779 * @param string $body Body content |
808 * @param string $body Body content. |
780 * @return string Chunked decoded body on success or raw body on failure. |
809 * @return string Chunked decoded body on success or raw body on failure. |
781 */ |
810 */ |
782 public static function chunkTransferDecode( $body ) { |
811 public static function chunkTransferDecode( $body ) { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.MethodNameInvalid |
783 // The body is not chunked encoded or is malformed. |
812 // The body is not chunked encoded or is malformed. |
784 if ( ! preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', trim( $body ) ) ) { |
813 if ( ! preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', trim( $body ) ) ) { |
785 return $body; |
814 return $body; |
786 } |
815 } |
787 |
816 |
811 } |
840 } |
812 } |
841 } |
813 } |
842 } |
814 |
843 |
815 /** |
844 /** |
816 * Block requests through the proxy. |
845 * Determines whether an HTTP API request to the given URL should be blocked. |
817 * |
846 * |
818 * Those who are behind a proxy and want to prevent access to certain hosts may do so. This will |
847 * Those who are behind a proxy and want to prevent access to certain hosts may do so. This will |
819 * prevent plugins from working and core functionality, if you don't include api.wordpress.org. |
848 * prevent plugins from working and core functionality, if you don't include `api.wordpress.org`. |
820 * |
849 * |
821 * You block external URL requests by defining WP_HTTP_BLOCK_EXTERNAL as true in your wp-config.php |
850 * You block external URL requests by defining `WP_HTTP_BLOCK_EXTERNAL` as true in your `wp-config.php` |
822 * file and this will only allow localhost and your site to make requests. The constant |
851 * file and this will only allow localhost and your site to make requests. The constant |
823 * WP_ACCESSIBLE_HOSTS will allow additional hosts to go through for requests. The format of the |
852 * `WP_ACCESSIBLE_HOSTS` will allow additional hosts to go through for requests. The format of the |
824 * WP_ACCESSIBLE_HOSTS constant is a comma separated list of hostnames to allow, wildcard domains |
853 * `WP_ACCESSIBLE_HOSTS` constant is a comma separated list of hostnames to allow, wildcard domains |
825 * are supported, eg *.wordpress.org will allow for all subdomains of wordpress.org to be contacted. |
854 * are supported, eg `*.wordpress.org` will allow for all subdomains of `wordpress.org` to be contacted. |
826 * |
855 * |
827 * @since 2.8.0 |
856 * @since 2.8.0 |
857 * |
|
828 * @link https://core.trac.wordpress.org/ticket/8927 Allow preventing external requests. |
858 * @link https://core.trac.wordpress.org/ticket/8927 Allow preventing external requests. |
829 * @link https://core.trac.wordpress.org/ticket/14636 Allow wildcard domains in WP_ACCESSIBLE_HOSTS |
859 * @link https://core.trac.wordpress.org/ticket/14636 Allow wildcard domains in WP_ACCESSIBLE_HOSTS |
830 * |
|
831 * @staticvar array|null $accessible_hosts |
|
832 * @staticvar array $wildcard_regex |
|
833 * |
860 * |
834 * @param string $uri URI of url. |
861 * @param string $uri URI of url. |
835 * @return bool True to block, false to allow. |
862 * @return bool True to block, false to allow. |
836 */ |
863 */ |
837 public function block_request( $uri ) { |
864 public function block_request( $uri ) { |
846 } |
873 } |
847 |
874 |
848 $home = parse_url( get_option( 'siteurl' ) ); |
875 $home = parse_url( get_option( 'siteurl' ) ); |
849 |
876 |
850 // Don't block requests back to ourselves by default. |
877 // Don't block requests back to ourselves by default. |
851 if ( 'localhost' == $check['host'] || ( isset( $home['host'] ) && $home['host'] == $check['host'] ) ) { |
878 if ( 'localhost' === $check['host'] || ( isset( $home['host'] ) && $home['host'] == $check['host'] ) ) { |
852 /** |
879 /** |
853 * Filters whether to block local requests through the proxy. |
880 * Filters whether to block local HTTP API requests. |
881 * |
|
882 * A local request is one to `localhost` or to the same host as the site itself. |
|
854 * |
883 * |
855 * @since 2.8.0 |
884 * @since 2.8.0 |
856 * |
885 * |
857 * @param bool $block Whether to block local requests through proxy. |
886 * @param bool $block Whether to block local requests. Default false. |
858 * Default false. |
|
859 */ |
887 */ |
860 return apply_filters( 'block_local_requests', false ); |
888 return apply_filters( 'block_local_requests', false ); |
861 } |
889 } |
862 |
890 |
863 if ( ! defined( 'WP_ACCESSIBLE_HOSTS' ) ) { |
891 if ( ! defined( 'WP_ACCESSIBLE_HOSTS' ) ) { |
879 } |
907 } |
880 |
908 |
881 if ( ! empty( $wildcard_regex ) ) { |
909 if ( ! empty( $wildcard_regex ) ) { |
882 return ! preg_match( $wildcard_regex, $check['host'] ); |
910 return ! preg_match( $wildcard_regex, $check['host'] ); |
883 } else { |
911 } else { |
884 return ! in_array( $check['host'], $accessible_hosts ); //Inverse logic, If it's in the array, then we can't access it. |
912 return ! in_array( $check['host'], $accessible_hosts, true ); // Inverse logic, if it's in the array, then don't block it. |
885 } |
913 } |
886 |
914 |
887 } |
915 } |
888 |
916 |
889 /** |
917 /** |
906 * |
934 * |
907 * If an Absolute URL is provided, no processing of that URL is done. |
935 * If an Absolute URL is provided, no processing of that URL is done. |
908 * |
936 * |
909 * @since 3.4.0 |
937 * @since 3.4.0 |
910 * |
938 * |
911 * @param string $maybe_relative_path The URL which might be relative |
939 * @param string $maybe_relative_path The URL which might be relative. |
912 * @param string $url The URL which $maybe_relative_path is relative to |
940 * @param string $url The URL which $maybe_relative_path is relative to. |
913 * @return string An Absolute URL, in a failure condition where the URL cannot be parsed, the relative URL will be returned. |
941 * @return string An Absolute URL, in a failure condition where the URL cannot be parsed, the relative URL will be returned. |
914 */ |
942 */ |
915 public static function make_absolute_url( $maybe_relative_path, $url ) { |
943 public static function make_absolute_url( $maybe_relative_path, $url ) { |
916 if ( empty( $url ) ) { |
944 if ( empty( $url ) ) { |
917 return $maybe_relative_path; |
945 return $maybe_relative_path; |
918 } |
946 } |
919 |
947 |
920 if ( ! $url_parts = wp_parse_url( $url ) ) { |
948 $url_parts = wp_parse_url( $url ); |
949 if ( ! $url_parts ) { |
|
921 return $maybe_relative_path; |
950 return $maybe_relative_path; |
922 } |
951 } |
923 |
952 |
924 if ( ! $relative_url_parts = wp_parse_url( $maybe_relative_path ) ) { |
953 $relative_url_parts = wp_parse_url( $maybe_relative_path ); |
954 if ( ! $relative_url_parts ) { |
|
925 return $maybe_relative_path; |
955 return $maybe_relative_path; |
926 } |
956 } |
927 |
957 |
928 // Check for a scheme on the 'relative' url |
958 // Check for a scheme on the 'relative' URL. |
929 if ( ! empty( $relative_url_parts['scheme'] ) ) { |
959 if ( ! empty( $relative_url_parts['scheme'] ) ) { |
930 return $maybe_relative_path; |
960 return $maybe_relative_path; |
931 } |
961 } |
932 |
962 |
933 $absolute_path = $url_parts['scheme'] . '://'; |
963 $absolute_path = $url_parts['scheme'] . '://'; |
934 |
964 |
935 // Schemeless URL's will make it this far, so we check for a host in the relative url and convert it to a protocol-url |
965 // Schemeless URLs will make it this far, so we check for a host in the relative URL |
966 // and convert it to a protocol-URL. |
|
936 if ( isset( $relative_url_parts['host'] ) ) { |
967 if ( isset( $relative_url_parts['host'] ) ) { |
937 $absolute_path .= $relative_url_parts['host']; |
968 $absolute_path .= $relative_url_parts['host']; |
938 if ( isset( $relative_url_parts['port'] ) ) { |
969 if ( isset( $relative_url_parts['port'] ) ) { |
939 $absolute_path .= ':' . $relative_url_parts['port']; |
970 $absolute_path .= ':' . $relative_url_parts['port']; |
940 } |
971 } |
943 if ( isset( $url_parts['port'] ) ) { |
974 if ( isset( $url_parts['port'] ) ) { |
944 $absolute_path .= ':' . $url_parts['port']; |
975 $absolute_path .= ':' . $url_parts['port']; |
945 } |
976 } |
946 } |
977 } |
947 |
978 |
948 // Start off with the Absolute URL path. |
979 // Start off with the absolute URL path. |
949 $path = ! empty( $url_parts['path'] ) ? $url_parts['path'] : '/'; |
980 $path = ! empty( $url_parts['path'] ) ? $url_parts['path'] : '/'; |
950 |
981 |
951 // If it's a root-relative path, then great. |
982 // If it's a root-relative path, then great. |
952 if ( ! empty( $relative_url_parts['path'] ) && '/' == $relative_url_parts['path'][0] ) { |
983 if ( ! empty( $relative_url_parts['path'] ) && '/' === $relative_url_parts['path'][0] ) { |
953 $path = $relative_url_parts['path']; |
984 $path = $relative_url_parts['path']; |
954 |
985 |
955 // Else it's a relative path. |
986 // Else it's a relative path. |
956 } elseif ( ! empty( $relative_url_parts['path'] ) ) { |
987 } elseif ( ! empty( $relative_url_parts['path'] ) ) { |
957 // Strip off any file components from the absolute path. |
988 // Strip off any file components from the absolute path. |
967 |
998 |
968 // Strip any final leading ../ from the path. |
999 // Strip any final leading ../ from the path. |
969 $path = preg_replace( '!^/(\.\./)+!', '', $path ); |
1000 $path = preg_replace( '!^/(\.\./)+!', '', $path ); |
970 } |
1001 } |
971 |
1002 |
972 // Add the Query string. |
1003 // Add the query string. |
973 if ( ! empty( $relative_url_parts['query'] ) ) { |
1004 if ( ! empty( $relative_url_parts['query'] ) ) { |
974 $path .= '?' . $relative_url_parts['query']; |
1005 $path .= '?' . $relative_url_parts['query']; |
975 } |
1006 } |
976 |
1007 |
977 return $absolute_path . '/' . ltrim( $path, '/' ); |
1008 return $absolute_path . '/' . ltrim( $path, '/' ); |
978 } |
1009 } |
979 |
1010 |
980 /** |
1011 /** |
981 * Handles HTTP Redirects and follows them if appropriate. |
1012 * Handles an HTTP redirect and follows it if appropriate. |
982 * |
1013 * |
983 * @since 3.7.0 |
1014 * @since 3.7.0 |
984 * |
1015 * |
985 * @param string $url The URL which was requested. |
1016 * @param string $url The URL which was requested. |
986 * @param array $args The Arguments which were used to make the request. |
1017 * @param array $args The arguments which were used to make the request. |
987 * @param array $response The Response of the HTTP request. |
1018 * @param array $response The response of the HTTP request. |
988 * @return false|object False if no redirect is present, a WP_HTTP or WP_Error result otherwise. |
1019 * @return array|false|WP_Error An HTTP API response array if the redirect is successfully followed, |
1020 * false if no redirect is present, or a WP_Error object if there's an error. |
|
989 */ |
1021 */ |
990 public static function handle_redirects( $url, $args, $response ) { |
1022 public static function handle_redirects( $url, $args, $response ) { |
991 // If no redirects are present, or, redirects were not requested, perform no action. |
1023 // If no redirects are present, or, redirects were not requested, perform no action. |
992 if ( ! isset( $response['headers']['location'] ) || 0 === $args['_redirection'] ) { |
1024 if ( ! isset( $response['headers']['location'] ) || 0 === $args['_redirection'] ) { |
993 return false; |
1025 return false; |
1011 } |
1043 } |
1012 |
1044 |
1013 $redirect_location = WP_Http::make_absolute_url( $redirect_location, $url ); |
1045 $redirect_location = WP_Http::make_absolute_url( $redirect_location, $url ); |
1014 |
1046 |
1015 // POST requests should not POST to a redirected location. |
1047 // POST requests should not POST to a redirected location. |
1016 if ( 'POST' == $args['method'] ) { |
1048 if ( 'POST' === $args['method'] ) { |
1017 if ( in_array( $response['response']['code'], array( 302, 303 ) ) ) { |
1049 if ( in_array( $response['response']['code'], array( 302, 303 ), true ) ) { |
1018 $args['method'] = 'GET'; |
1050 $args['method'] = 'GET'; |
1019 } |
1051 } |
1020 } |
1052 } |
1021 |
1053 |
1022 // Include valid cookies in the redirect process. |
1054 // Include valid cookies in the redirect process. |
1037 * This function also detects the type of the IP address, returning either |
1069 * This function also detects the type of the IP address, returning either |
1038 * '4' or '6' to represent a IPv4 and IPv6 address respectively. |
1070 * '4' or '6' to represent a IPv4 and IPv6 address respectively. |
1039 * This does not verify if the IP is a valid IP, only that it appears to be |
1071 * This does not verify if the IP is a valid IP, only that it appears to be |
1040 * an IP address. |
1072 * an IP address. |
1041 * |
1073 * |
1042 * @link http://home.deds.nl/~aeron/regex/ for IPv6 regex |
1074 * @link http://home.deds.nl/~aeron/regex/ for IPv6 regex. |
1043 * |
1075 * |
1044 * @since 3.7.0 |
1076 * @since 3.7.0 |
1045 * |
1077 * |
1046 * @param string $maybe_ip A suspected IP address |
1078 * @param string $maybe_ip A suspected IP address. |
1047 * @return integer|bool Upon success, '4' or '6' to represent a IPv4 or IPv6 address, false upon failure |
1079 * @return integer|bool Upon success, '4' or '6' to represent a IPv4 or IPv6 address, false upon failure |
1048 */ |
1080 */ |
1049 public static function is_ip_address( $maybe_ip ) { |
1081 public static function is_ip_address( $maybe_ip ) { |
1050 if ( preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $maybe_ip ) ) { |
1082 if ( preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/', $maybe_ip ) ) { |
1051 return 4; |
1083 return 4; |