wp/wp-includes/http.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
     1 <?php
     1 <?php
     2 /**
     2 /**
     3  * Simple and uniform HTTP request API.
     3  * Core HTTP Request API
     4  *
     4  *
     5  * Will eventually replace and standardize the WordPress HTTP requests made.
     5  * Standardizes the HTTP requests for WordPress. Handles cookies, gzip encoding and decoding, chunk
     6  *
     6  * decoding, if HTTP 1.1 and various other difficult HTTP protocol implementations.
     7  * @link https://core.trac.wordpress.org/ticket/4779 HTTP API Proposal
       
     8  *
     7  *
     9  * @package WordPress
     8  * @package WordPress
    10  * @subpackage HTTP
     9  * @subpackage HTTP
    11  * @since 2.7.0
       
    12  */
    10  */
    13 
    11 
    14 /**
    12 /**
    15  * Returns the initialized WP_Http Object
    13  * Returns the initialized WP_Http Object
    16  *
    14  *
    17  * @since 2.7.0
    15  * @since 2.7.0
    18  * @access private
    16  * @access private
    19  *
    17  *
       
    18  * @staticvar WP_Http $http
       
    19  *
    20  * @return WP_Http HTTP Transport object.
    20  * @return WP_Http HTTP Transport object.
    21  */
    21  */
    22 function _wp_http_get_object() {
    22 function _wp_http_get_object() {
    23 	static $http;
    23 	static $http = null;
    24 
    24 
    25 	if ( is_null($http) )
    25 	if ( is_null( $http ) ) {
    26 		$http = new WP_Http();
    26 		$http = new WP_Http();
    27 
    27 	}
    28 	return $http;
    28 	return $http;
    29 }
    29 }
    30 
    30 
    31 /**
    31 /**
    32  * Retrieve the raw response from a safe HTTP request.
    32  * Retrieve the raw response from a safe HTTP request.
   147  * @param string $url  Site URL to retrieve.
   147  * @param string $url  Site URL to retrieve.
   148  * @param array  $args Optional. Request arguments. Default empty array.
   148  * @param array  $args Optional. Request arguments. Default empty array.
   149  * @return WP_Error|array The response or WP_Error on failure.
   149  * @return WP_Error|array The response or WP_Error on failure.
   150  */
   150  */
   151 function wp_remote_request($url, $args = array()) {
   151 function wp_remote_request($url, $args = array()) {
   152 	$objFetchSite = _wp_http_get_object();
   152 	$http = _wp_http_get_object();
   153 	return $objFetchSite->request($url, $args);
   153 	return $http->request( $url, $args );
   154 }
   154 }
   155 
   155 
   156 /**
   156 /**
   157  * Retrieve the raw response from the HTTP request using the GET method.
   157  * Retrieve the raw response from the HTTP request using the GET method.
   158  *
   158  *
   164  * @param string $url  Site URL to retrieve.
   164  * @param string $url  Site URL to retrieve.
   165  * @param array  $args Optional. Request arguments. Default empty array.
   165  * @param array  $args Optional. Request arguments. Default empty array.
   166  * @return WP_Error|array The response or WP_Error on failure.
   166  * @return WP_Error|array The response or WP_Error on failure.
   167  */
   167  */
   168 function wp_remote_get($url, $args = array()) {
   168 function wp_remote_get($url, $args = array()) {
   169 	$objFetchSite = _wp_http_get_object();
   169 	$http = _wp_http_get_object();
   170 	return $objFetchSite->get($url, $args);
   170 	return $http->get( $url, $args );
   171 }
   171 }
   172 
   172 
   173 /**
   173 /**
   174  * Retrieve the raw response from the HTTP request using the POST method.
   174  * Retrieve the raw response from the HTTP request using the POST method.
   175  *
   175  *
   181  * @param string $url  Site URL to retrieve.
   181  * @param string $url  Site URL to retrieve.
   182  * @param array  $args Optional. Request arguments. Default empty array.
   182  * @param array  $args Optional. Request arguments. Default empty array.
   183  * @return WP_Error|array The response or WP_Error on failure.
   183  * @return WP_Error|array The response or WP_Error on failure.
   184  */
   184  */
   185 function wp_remote_post($url, $args = array()) {
   185 function wp_remote_post($url, $args = array()) {
   186 	$objFetchSite = _wp_http_get_object();
   186 	$http = _wp_http_get_object();
   187 	return $objFetchSite->post($url, $args);
   187 	return $http->post( $url, $args );
   188 }
   188 }
   189 
   189 
   190 /**
   190 /**
   191  * Retrieve the raw response from the HTTP request using the HEAD method.
   191  * Retrieve the raw response from the HTTP request using the HEAD method.
   192  *
   192  *
   198  * @param string $url  Site URL to retrieve.
   198  * @param string $url  Site URL to retrieve.
   199  * @param array  $args Optional. Request arguments. Default empty array.
   199  * @param array  $args Optional. Request arguments. Default empty array.
   200  * @return WP_Error|array The response or WP_Error on failure.
   200  * @return WP_Error|array The response or WP_Error on failure.
   201  */
   201  */
   202 function wp_remote_head($url, $args = array()) {
   202 function wp_remote_head($url, $args = array()) {
   203 	$objFetchSite = _wp_http_get_object();
   203 	$http = _wp_http_get_object();
   204 	return $objFetchSite->head($url, $args);
   204 	return $http->head( $url, $args );
   205 }
   205 }
   206 
   206 
   207 /**
   207 /**
   208  * Retrieve only the headers from the raw response.
   208  * Retrieve only the headers from the raw response.
   209  *
   209  *
   210  * @since 2.7.0
   210  * @since 2.7.0
       
   211  * @since 4.6.0 Return value changed from an array to an Requests_Utility_CaseInsensitiveDictionary instance.
       
   212  *
       
   213  * @see \Requests_Utility_CaseInsensitiveDictionary
   211  *
   214  *
   212  * @param array $response HTTP response.
   215  * @param array $response HTTP response.
   213  * @return array The headers of the response. Empty array if incorrect parameter given.
   216  * @return array|\Requests_Utility_CaseInsensitiveDictionary The headers of the response. Empty array if incorrect parameter given.
   214  */
   217  */
   215 function wp_remote_retrieve_headers( $response ) {
   218 function wp_remote_retrieve_headers( $response ) {
   216 	if ( is_wp_error($response) || ! isset($response['headers']) || ! is_array($response['headers']))
   219 	if ( is_wp_error( $response ) || ! isset( $response['headers'] ) ) {
   217 		return array();
   220 		return array();
       
   221 	}
   218 
   222 
   219 	return $response['headers'];
   223 	return $response['headers'];
   220 }
   224 }
   221 
   225 
   222 /**
   226 /**
   223  * Retrieve a single header by name from the raw response.
   227  * Retrieve a single header by name from the raw response.
   224  *
   228  *
   225  * @since 2.7.0
   229  * @since 2.7.0
   226  *
   230  *
   227  * @param array $response
   231  * @param array  $response
   228  * @param string $header Header name to retrieve value from.
   232  * @param string $header Header name to retrieve value from.
   229  * @return string The header value. Empty string on if incorrect parameter given, or if the header doesn't exist.
   233  * @return string The header value. Empty string on if incorrect parameter given, or if the header doesn't exist.
   230  */
   234  */
   231 function wp_remote_retrieve_header( $response, $header ) {
   235 function wp_remote_retrieve_header( $response, $header ) {
   232 	if ( is_wp_error($response) || ! isset($response['headers']) || ! is_array($response['headers']))
   236 	if ( is_wp_error( $response ) || ! isset( $response['headers'] ) ) {
   233 		return '';
   237 		return '';
   234 
   238 	}
   235 	if ( array_key_exists($header, $response['headers']) )
   239 
       
   240 	if ( isset( $response['headers'][ $header ] ) ) {
   236 		return $response['headers'][$header];
   241 		return $response['headers'][$header];
       
   242 	}
   237 
   243 
   238 	return '';
   244 	return '';
   239 }
   245 }
   240 
   246 
   241 /**
   247 /**
   286 
   292 
   287 	return $response['body'];
   293 	return $response['body'];
   288 }
   294 }
   289 
   295 
   290 /**
   296 /**
       
   297  * Retrieve only the cookies from the raw response.
       
   298  *
       
   299  * @since 4.4.0
       
   300  *
       
   301  * @param array $response HTTP response.
       
   302  * @return array An array of `WP_Http_Cookie` objects from the response. Empty array if there are none, or the response is a WP_Error.
       
   303  */
       
   304 function wp_remote_retrieve_cookies( $response ) {
       
   305 	if ( is_wp_error( $response ) || empty( $response['cookies'] ) ) {
       
   306 		return array();
       
   307 	}
       
   308 
       
   309 	return $response['cookies'];
       
   310 }
       
   311 
       
   312 /**
       
   313  * Retrieve a single cookie by name from the raw response.
       
   314  *
       
   315  * @since 4.4.0
       
   316  *
       
   317  * @param array  $response HTTP response.
       
   318  * @param string $name     The name of the cookie to retrieve.
       
   319  * @return WP_Http_Cookie|string The `WP_Http_Cookie` object. Empty string if the cookie isn't present in the response.
       
   320  */
       
   321 function wp_remote_retrieve_cookie( $response, $name ) {
       
   322 	$cookies = wp_remote_retrieve_cookies( $response );
       
   323 
       
   324 	if ( empty( $cookies ) ) {
       
   325 		return '';
       
   326 	}
       
   327 
       
   328 	foreach ( $cookies as $cookie ) {
       
   329 		if ( $cookie->name === $name ) {
       
   330 			return $cookie;
       
   331 		}
       
   332 	}
       
   333 
       
   334 	return '';
       
   335 }
       
   336 
       
   337 /**
       
   338  * Retrieve a single cookie's value by name from the raw response.
       
   339  *
       
   340  * @since 4.4.0
       
   341  *
       
   342  * @param array  $response HTTP response.
       
   343  * @param string $name     The name of the cookie to retrieve.
       
   344  * @return string The value of the cookie. Empty string if the cookie isn't present in the response.
       
   345  */
       
   346 function wp_remote_retrieve_cookie_value( $response, $name ) {
       
   347 	$cookie = wp_remote_retrieve_cookie( $response, $name );
       
   348 
       
   349 	if ( ! is_a( $cookie, 'WP_Http_Cookie' ) ) {
       
   350 		return '';
       
   351 	}
       
   352 
       
   353 	return $cookie->value;
       
   354 }
       
   355 
       
   356 /**
   291  * Determines if there is an HTTP Transport that can process this request.
   357  * Determines if there is an HTTP Transport that can process this request.
   292  *
   358  *
   293  * @since 3.2.0
   359  * @since 3.2.0
   294  *
   360  *
   295  * @param array  $capabilities Array of capabilities to test or a wp_remote_request() $args array.
   361  * @param array  $capabilities Array of capabilities to test or a wp_remote_request() $args array.
   296  * @param string $url Optional. If given, will check if the URL requires SSL and adds that requirement to the capabilities array.
   362  * @param string $url          Optional. If given, will check if the URL requires SSL and adds
       
   363  *                             that requirement to the capabilities array.
   297  *
   364  *
   298  * @return bool
   365  * @return bool
   299  */
   366  */
   300 function wp_http_supports( $capabilities = array(), $url = null ) {
   367 function wp_http_supports( $capabilities = array(), $url = null ) {
   301 	$objFetchSite = _wp_http_get_object();
   368 	$http = _wp_http_get_object();
   302 
   369 
   303 	$capabilities = wp_parse_args( $capabilities );
   370 	$capabilities = wp_parse_args( $capabilities );
   304 
   371 
   305 	$count = count( $capabilities );
   372 	$count = count( $capabilities );
   306 
   373 
   314 		if ( 'https' == $scheme || 'ssl' == $scheme ) {
   381 		if ( 'https' == $scheme || 'ssl' == $scheme ) {
   315 			$capabilities['ssl'] = true;
   382 			$capabilities['ssl'] = true;
   316 		}
   383 		}
   317 	}
   384 	}
   318 
   385 
   319 	return (bool) $objFetchSite->_get_first_available_transport( $capabilities );
   386 	return (bool) $http->_get_first_available_transport( $capabilities );
   320 }
   387 }
   321 
   388 
   322 /**
   389 /**
   323  * Get the HTTP Origin of the current request.
   390  * Get the HTTP Origin of the current request.
   324  *
   391  *
   380  * Determines if the HTTP origin is an authorized one.
   447  * Determines if the HTTP origin is an authorized one.
   381  *
   448  *
   382  * @since 3.4.0
   449  * @since 3.4.0
   383  *
   450  *
   384  * @param null|string $origin Origin URL. If not provided, the value of get_http_origin() is used.
   451  * @param null|string $origin Origin URL. If not provided, the value of get_http_origin() is used.
   385  * @return bool|null True if the origin is allowed. False otherwise.
   452  * @return string Origin URL if allowed, empty string if not.
   386  */
   453  */
   387 function is_allowed_http_origin( $origin = null ) {
   454 function is_allowed_http_origin( $origin = null ) {
   388 	$origin_arg = $origin;
   455 	$origin_arg = $origin;
   389 
   456 
   390 	if ( null === $origin )
   457 	if ( null === $origin )
   396 	/**
   463 	/**
   397 	 * Change the allowed HTTP origin result.
   464 	 * Change the allowed HTTP origin result.
   398 	 *
   465 	 *
   399 	 * @since 3.4.0
   466 	 * @since 3.4.0
   400 	 *
   467 	 *
   401 	 * @param string $origin Result of check for allowed origin.
   468 	 * @param string $origin     Origin URL if allowed, empty string if not.
   402 	 * @param string $origin_arg original origin string passed into is_allowed_http_origin function.
   469 	 * @param string $origin_arg Original origin string passed into is_allowed_http_origin function.
   403 	 */
   470 	 */
   404 	return apply_filters( 'allowed_http_origin', $origin, $origin_arg );
   471 	return apply_filters( 'allowed_http_origin', $origin, $origin_arg );
   405 }
   472 }
   406 
   473 
   407 /**
   474 /**
   412  * control headers sent, or a 403 response if the origin is not allowed. For
   479  * control headers sent, or a 403 response if the origin is not allowed. For
   413  * other request methods, you will receive a return value.
   480  * other request methods, you will receive a return value.
   414  *
   481  *
   415  * @since 3.4.0
   482  * @since 3.4.0
   416  *
   483  *
   417  * @return bool|string Returns the origin URL if headers are sent. Returns false
   484  * @return string|false Returns the origin URL if headers are sent. Returns false
   418  * if headers are not sent.
   485  *                      if headers are not sent.
   419  */
   486  */
   420 function send_origin_headers() {
   487 function send_origin_headers() {
   421 	$origin = get_http_origin();
   488 	$origin = get_http_origin();
   422 
   489 
   423 	if ( is_allowed_http_origin( $origin ) ) {
   490 	if ( is_allowed_http_origin( $origin ) ) {
   460 	if ( false !== strpbrk( $parsed_url['host'], ':#?[]' ) )
   527 	if ( false !== strpbrk( $parsed_url['host'], ':#?[]' ) )
   461 		return false;
   528 		return false;
   462 
   529 
   463 	$parsed_home = @parse_url( get_option( 'home' ) );
   530 	$parsed_home = @parse_url( get_option( 'home' ) );
   464 
   531 
   465 	$same_host = strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] );
   532 	if ( isset( $parsed_home['host'] ) ) {
       
   533 		$same_host = strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] );
       
   534 	} else {
       
   535 		$same_host = false;
       
   536 	}
   466 
   537 
   467 	if ( ! $same_host ) {
   538 	if ( ! $same_host ) {
   468 		$host = trim( $parsed_url['host'], '.' );
   539 		$host = trim( $parsed_url['host'], '.' );
   469 		if ( preg_match( '#^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $host ) ) {
   540 		if ( preg_match( '#^(([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)\.){3}([1-9]?\d|1\d\d|25[0-5]|2[0-4]\d)$#', $host ) ) {
   470 			$ip = $host;
   541 			$ip = $host;
   471 		} else {
   542 		} else {
   472 			$ip = gethostbyname( $host );
   543 			$ip = gethostbyname( $host );
   473 			if ( $ip === $host ) // Error condition for gethostbyname()
   544 			if ( $ip === $host ) // Error condition for gethostbyname()
   474 				$ip = false;
   545 				$ip = false;
   475 		}
   546 		}
   476 		if ( $ip ) {
   547 		if ( $ip ) {
   477 			$parts = array_map( 'intval', explode( '.', $ip ) );
   548 			$parts = array_map( 'intval', explode( '.', $ip ) );
   478 			if ( 127 === $parts[0] || 10 === $parts[0]
   549 			if ( 127 === $parts[0] || 10 === $parts[0] || 0 === $parts[0]
   479 				|| ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )
   550 				|| ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )
   480 				|| ( 192 === $parts[0] && 168 === $parts[1] )
   551 				|| ( 192 === $parts[0] && 168 === $parts[1] )
   481 			) {
   552 			) {
   482 				// If host appears local, reject unless specifically allowed.
   553 				// If host appears local, reject unless specifically allowed.
   483 				/**
   554 				/**
   485 				 *
   556 				 *
   486 				 * Allows to change and allow external requests for the HTTP request.
   557 				 * Allows to change and allow external requests for the HTTP request.
   487 				 *
   558 				 *
   488 				 * @since 3.6.0
   559 				 * @since 3.6.0
   489 				 *
   560 				 *
   490 				 * @param bool false Whether HTTP request is external or not.
   561 				 * @param bool   false Whether HTTP request is external or not.
   491 				 * @param string $host IP of the requested host.
   562 				 * @param string $host IP of the requested host.
   492 				 * @param string $url URL of the requested host.
   563 				 * @param string $url  URL of the requested host.
   493 				 */
   564 				 */
   494 				if ( ! apply_filters( 'http_request_host_is_external', false, $host, $url ) )
   565 				if ( ! apply_filters( 'http_request_host_is_external', false, $host, $url ) )
   495 					return false;
   566 					return false;
   496 			}
   567 			}
   497 		}
   568 		}
   511 }
   582 }
   512 
   583 
   513 /**
   584 /**
   514  * Whitelists allowed redirect hosts for safe HTTP requests as well.
   585  * Whitelists allowed redirect hosts for safe HTTP requests as well.
   515  *
   586  *
   516  * Attached to the http_request_host_is_external filter.
   587  * Attached to the {@see 'http_request_host_is_external'} filter.
   517  *
   588  *
   518  * @since 3.6.0
   589  * @since 3.6.0
   519  *
   590  *
   520  * @param bool $is_external
   591  * @param bool   $is_external
   521  * @param string $host
   592  * @param string $host
   522  * @return bool
   593  * @return bool
   523  */
   594  */
   524 function allowed_http_request_hosts( $is_external, $host ) {
   595 function allowed_http_request_hosts( $is_external, $host ) {
   525 	if ( ! $is_external && wp_validate_redirect( 'http://' . $host ) )
   596 	if ( ! $is_external && wp_validate_redirect( 'http://' . $host ) )
   528 }
   599 }
   529 
   600 
   530 /**
   601 /**
   531  * Whitelists any domain in a multisite installation for safe HTTP requests.
   602  * Whitelists any domain in a multisite installation for safe HTTP requests.
   532  *
   603  *
   533  * Attached to the http_request_host_is_external filter.
   604  * Attached to the {@see 'http_request_host_is_external'} filter.
   534  *
   605  *
   535  * @since 3.6.0
   606  * @since 3.6.0
   536  *
   607  *
   537  * @param bool $is_external
   608  * @global wpdb $wpdb WordPress database abstraction object.
       
   609  * @staticvar array $queried
       
   610  *
       
   611  * @param bool   $is_external
   538  * @param string $host
   612  * @param string $host
   539  * @return bool
   613  * @return bool
   540  */
   614  */
   541 function ms_allowed_http_request_hosts( $is_external, $host ) {
   615 function ms_allowed_http_request_hosts( $is_external, $host ) {
   542 	global $wpdb;
   616 	global $wpdb;
   543 	static $queried = array();
   617 	static $queried = array();
   544 	if ( $is_external )
   618 	if ( $is_external )
   545 		return $is_external;
   619 		return $is_external;
   546 	if ( $host === get_current_site()->domain )
   620 	if ( $host === get_network()->domain )
   547 		return true;
   621 		return true;
   548 	if ( isset( $queried[ $host ] ) )
   622 	if ( isset( $queried[ $host ] ) )
   549 		return $queried[ $host ];
   623 		return $queried[ $host ];
   550 	$queried[ $host ] = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT domain FROM $wpdb->blogs WHERE domain = %s LIMIT 1", $host ) );
   624 	$queried[ $host ] = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT domain FROM $wpdb->blogs WHERE domain = %s LIMIT 1", $host ) );
   551 	return $queried[ $host ];
   625 	return $queried[ $host ];
   552 }
   626 }
       
   627 
       
   628 /**
       
   629  * A wrapper for PHP's parse_url() function that handles consistency in the return
       
   630  * values across PHP versions.
       
   631  *
       
   632  * PHP 5.4.7 expanded parse_url()'s ability to handle non-absolute url's, including
       
   633  * schemeless and relative url's with :// in the path. This function works around
       
   634  * those limitations providing a standard output on PHP 5.2~5.4+.
       
   635  *
       
   636  * Secondly, across various PHP versions, schemeless URLs starting containing a ":"
       
   637  * in the query are being handled inconsistently. This function works around those
       
   638  * differences as well.
       
   639  *
       
   640  * Error suppression is used as prior to PHP 5.3.3, an E_WARNING would be generated
       
   641  * when URL parsing failed.
       
   642  *
       
   643  * @since 4.4.0
       
   644  * @since 4.7.0 The $component parameter was added for parity with PHP's parse_url().
       
   645  *
       
   646  * @link https://secure.php.net/manual/en/function.parse-url.php
       
   647  *
       
   648  * @param string $url       The URL to parse.
       
   649  * @param int    $component The specific component to retrieve. Use one of the PHP
       
   650  *                          predefined constants to specify which one.
       
   651  *                          Defaults to -1 (= return all parts as an array).
       
   652  * @return mixed False on parse failure; Array of URL components on success;
       
   653  *               When a specific component has been requested: null if the component
       
   654  *               doesn't exist in the given URL; a string or - in the case of
       
   655  *               PHP_URL_PORT - integer when it does. See parse_url()'s return values.
       
   656  */
       
   657 function wp_parse_url( $url, $component = -1 ) {
       
   658 	$to_unset = array();
       
   659 	$url = strval( $url );
       
   660 
       
   661 	if ( '//' === substr( $url, 0, 2 ) ) {
       
   662 		$to_unset[] = 'scheme';
       
   663 		$url = 'placeholder:' . $url;
       
   664 	} elseif ( '/' === substr( $url, 0, 1 ) ) {
       
   665 		$to_unset[] = 'scheme';
       
   666 		$to_unset[] = 'host';
       
   667 		$url = 'placeholder://placeholder' . $url;
       
   668 	}
       
   669 
       
   670 	$parts = @parse_url( $url );
       
   671 
       
   672 	if ( false === $parts ) {
       
   673 		// Parsing failure.
       
   674 		return $parts;
       
   675 	}
       
   676 
       
   677 	// Remove the placeholder values.
       
   678 	foreach ( $to_unset as $key ) {
       
   679 		unset( $parts[ $key ] );
       
   680 	}
       
   681 
       
   682 	return _get_component_from_parsed_url_array( $parts, $component );
       
   683 }
       
   684 
       
   685 /**
       
   686  * Retrieve a specific component from a parsed URL array.
       
   687  *
       
   688  * @internal
       
   689  *
       
   690  * @since 4.7.0
       
   691  * @access private
       
   692  *
       
   693  * @link https://secure.php.net/manual/en/function.parse-url.php
       
   694  *
       
   695  * @param array|false $url_parts The parsed URL. Can be false if the URL failed to parse.
       
   696  * @param int    $component The specific component to retrieve. Use one of the PHP
       
   697  *                          predefined constants to specify which one.
       
   698  *                          Defaults to -1 (= return all parts as an array).
       
   699  * @return mixed False on parse failure; Array of URL components on success;
       
   700  *               When a specific component has been requested: null if the component
       
   701  *               doesn't exist in the given URL; a string or - in the case of
       
   702  *               PHP_URL_PORT - integer when it does. See parse_url()'s return values.
       
   703  */
       
   704 function _get_component_from_parsed_url_array( $url_parts, $component = -1 ) {
       
   705 	if ( -1 === $component ) {
       
   706 		return $url_parts;
       
   707 	}
       
   708 
       
   709 	$key = _wp_translate_php_url_constant_to_key( $component );
       
   710 	if ( false !== $key && is_array( $url_parts ) && isset( $url_parts[ $key ] ) ) {
       
   711 		return $url_parts[ $key ];
       
   712 	} else {
       
   713 		return null;
       
   714 	}
       
   715 }
       
   716 
       
   717 /**
       
   718  * Translate a PHP_URL_* constant to the named array keys PHP uses.
       
   719  *
       
   720  * @internal
       
   721  *
       
   722  * @since 4.7.0
       
   723  * @access private
       
   724  *
       
   725  * @link https://secure.php.net/manual/en/url.constants.php
       
   726  *
       
   727  * @param int $constant PHP_URL_* constant.
       
   728  * @return string|bool The named key or false.
       
   729  */
       
   730 function _wp_translate_php_url_constant_to_key( $constant ) {
       
   731 	$translation = array(
       
   732 		PHP_URL_SCHEME   => 'scheme',
       
   733 		PHP_URL_HOST     => 'host',
       
   734 		PHP_URL_PORT     => 'port',
       
   735 		PHP_URL_USER     => 'user',
       
   736 		PHP_URL_PASS     => 'pass',
       
   737 		PHP_URL_PATH     => 'path',
       
   738 		PHP_URL_QUERY    => 'query',
       
   739 		PHP_URL_FRAGMENT => 'fragment',
       
   740 	);
       
   741 
       
   742 	if ( isset( $translation[ $constant ] ) ) {
       
   743 		return $translation[ $constant ];
       
   744 	} else {
       
   745 		return false;
       
   746 	}
       
   747 }