wp/wp-includes/http.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 13 d255fe9cd479
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    43  * @param array  $args Optional. Request arguments. Default empty array.
    43  * @param array  $args Optional. Request arguments. Default empty array.
    44  * @return WP_Error|array The response or WP_Error on failure.
    44  * @return WP_Error|array The response or WP_Error on failure.
    45  */
    45  */
    46 function wp_safe_remote_request( $url, $args = array() ) {
    46 function wp_safe_remote_request( $url, $args = array() ) {
    47 	$args['reject_unsafe_urls'] = true;
    47 	$args['reject_unsafe_urls'] = true;
    48 	$http = _wp_http_get_object();
    48 	$http                       = _wp_http_get_object();
    49 	return $http->request( $url, $args );
    49 	return $http->request( $url, $args );
    50 }
    50 }
    51 
    51 
    52 /**
    52 /**
    53  * Retrieve the raw response from a safe HTTP request using the GET method.
    53  * Retrieve the raw response from a safe HTTP request using the GET method.
    64  * @param array  $args Optional. Request arguments. Default empty array.
    64  * @param array  $args Optional. Request arguments. Default empty array.
    65  * @return WP_Error|array The response or WP_Error on failure.
    65  * @return WP_Error|array The response or WP_Error on failure.
    66  */
    66  */
    67 function wp_safe_remote_get( $url, $args = array() ) {
    67 function wp_safe_remote_get( $url, $args = array() ) {
    68 	$args['reject_unsafe_urls'] = true;
    68 	$args['reject_unsafe_urls'] = true;
    69 	$http = _wp_http_get_object();
    69 	$http                       = _wp_http_get_object();
    70 	return $http->get( $url, $args );
    70 	return $http->get( $url, $args );
    71 }
    71 }
    72 
    72 
    73 /**
    73 /**
    74  * Retrieve the raw response from a safe HTTP request using the POST method.
    74  * Retrieve the raw response from a safe HTTP request using the POST method.
    85  * @param array  $args Optional. Request arguments. Default empty array.
    85  * @param array  $args Optional. Request arguments. Default empty array.
    86  * @return WP_Error|array The response or WP_Error on failure.
    86  * @return WP_Error|array The response or WP_Error on failure.
    87  */
    87  */
    88 function wp_safe_remote_post( $url, $args = array() ) {
    88 function wp_safe_remote_post( $url, $args = array() ) {
    89 	$args['reject_unsafe_urls'] = true;
    89 	$args['reject_unsafe_urls'] = true;
    90 	$http = _wp_http_get_object();
    90 	$http                       = _wp_http_get_object();
    91 	return $http->post( $url, $args );
    91 	return $http->post( $url, $args );
    92 }
    92 }
    93 
    93 
    94 /**
    94 /**
    95  * Retrieve the raw response from a safe HTTP request using the HEAD method.
    95  * Retrieve the raw response from a safe HTTP request using the HEAD method.
   106  * @param array $args Optional. Request arguments. Default empty array.
   106  * @param array $args Optional. Request arguments. Default empty array.
   107  * @return WP_Error|array The response or WP_Error on failure.
   107  * @return WP_Error|array The response or WP_Error on failure.
   108  */
   108  */
   109 function wp_safe_remote_head( $url, $args = array() ) {
   109 function wp_safe_remote_head( $url, $args = array() ) {
   110 	$args['reject_unsafe_urls'] = true;
   110 	$args['reject_unsafe_urls'] = true;
   111 	$http = _wp_http_get_object();
   111 	$http                       = _wp_http_get_object();
   112 	return $http->head( $url, $args );
   112 	return $http->head( $url, $args );
   113 }
   113 }
   114 
   114 
   115 /**
   115 /**
   116  * Retrieve the raw response from the HTTP request.
   116  * Retrieve the raw response from the HTTP request.
   146  *
   146  *
   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 	$http = _wp_http_get_object();
   152 	$http = _wp_http_get_object();
   153 	return $http->request( $url, $args );
   153 	return $http->request( $url, $args );
   154 }
   154 }
   155 
   155 
   156 /**
   156 /**
   163  *
   163  *
   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 	$http = _wp_http_get_object();
   169 	$http = _wp_http_get_object();
   170 	return $http->get( $url, $args );
   170 	return $http->get( $url, $args );
   171 }
   171 }
   172 
   172 
   173 /**
   173 /**
   180  *
   180  *
   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 	$http = _wp_http_get_object();
   186 	$http = _wp_http_get_object();
   187 	return $http->post( $url, $args );
   187 	return $http->post( $url, $args );
   188 }
   188 }
   189 
   189 
   190 /**
   190 /**
   197  *
   197  *
   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 	$http = _wp_http_get_object();
   203 	$http = _wp_http_get_object();
   204 	return $http->head( $url, $args );
   204 	return $http->head( $url, $args );
   205 }
   205 }
   206 
   206 
   207 /**
   207 /**
   236 	if ( is_wp_error( $response ) || ! isset( $response['headers'] ) ) {
   236 	if ( is_wp_error( $response ) || ! isset( $response['headers'] ) ) {
   237 		return '';
   237 		return '';
   238 	}
   238 	}
   239 
   239 
   240 	if ( isset( $response['headers'][ $header ] ) ) {
   240 	if ( isset( $response['headers'][ $header ] ) ) {
   241 		return $response['headers'][$header];
   241 		return $response['headers'][ $header ];
   242 	}
   242 	}
   243 
   243 
   244 	return '';
   244 	return '';
   245 }
   245 }
   246 
   246 
   253  *
   253  *
   254  * @param array $response HTTP response.
   254  * @param array $response HTTP response.
   255  * @return int|string The response code as an integer. Empty string on incorrect parameter given.
   255  * @return int|string The response code as an integer. Empty string on incorrect parameter given.
   256  */
   256  */
   257 function wp_remote_retrieve_response_code( $response ) {
   257 function wp_remote_retrieve_response_code( $response ) {
   258 	if ( is_wp_error($response) || ! isset($response['response']) || ! is_array($response['response']))
   258 	if ( is_wp_error( $response ) || ! isset( $response['response'] ) || ! is_array( $response['response'] ) ) {
   259 		return '';
   259 		return '';
       
   260 	}
   260 
   261 
   261 	return $response['response']['code'];
   262 	return $response['response']['code'];
   262 }
   263 }
   263 
   264 
   264 /**
   265 /**
   270  *
   271  *
   271  * @param array $response HTTP response.
   272  * @param array $response HTTP response.
   272  * @return string The response message. Empty string on incorrect parameter given.
   273  * @return string The response message. Empty string on incorrect parameter given.
   273  */
   274  */
   274 function wp_remote_retrieve_response_message( $response ) {
   275 function wp_remote_retrieve_response_message( $response ) {
   275 	if ( is_wp_error($response) || ! isset($response['response']) || ! is_array($response['response']))
   276 	if ( is_wp_error( $response ) || ! isset( $response['response'] ) || ! is_array( $response['response'] ) ) {
   276 		return '';
   277 		return '';
       
   278 	}
   277 
   279 
   278 	return $response['response']['message'];
   280 	return $response['response']['message'];
   279 }
   281 }
   280 
   282 
   281 /**
   283 /**
   285  *
   287  *
   286  * @param array $response HTTP response.
   288  * @param array $response HTTP response.
   287  * @return string The body of the response. Empty string if no body or incorrect parameter given.
   289  * @return string The body of the response. Empty string if no body or incorrect parameter given.
   288  */
   290  */
   289 function wp_remote_retrieve_body( $response ) {
   291 function wp_remote_retrieve_body( $response ) {
   290 	if ( is_wp_error($response) || ! isset($response['body']) )
   292 	if ( is_wp_error( $response ) || ! isset( $response['body'] ) ) {
   291 		return '';
   293 		return '';
       
   294 	}
   292 
   295 
   293 	return $response['body'];
   296 	return $response['body'];
   294 }
   297 }
   295 
   298 
   296 /**
   299 /**
   374 	// If we have a numeric $capabilities array, spoof a wp_remote_request() associative $args array
   377 	// If we have a numeric $capabilities array, spoof a wp_remote_request() associative $args array
   375 	if ( $count && count( array_filter( array_keys( $capabilities ), 'is_numeric' ) ) == $count ) {
   378 	if ( $count && count( array_filter( array_keys( $capabilities ), 'is_numeric' ) ) == $count ) {
   376 		$capabilities = array_combine( array_values( $capabilities ), array_fill( 0, $count, true ) );
   379 		$capabilities = array_combine( array_values( $capabilities ), array_fill( 0, $count, true ) );
   377 	}
   380 	}
   378 
   381 
   379 	if ( $url && !isset( $capabilities['ssl'] ) ) {
   382 	if ( $url && ! isset( $capabilities['ssl'] ) ) {
   380 		$scheme = parse_url( $url, PHP_URL_SCHEME );
   383 		$scheme = parse_url( $url, PHP_URL_SCHEME );
   381 		if ( 'https' == $scheme || 'ssl' == $scheme ) {
   384 		if ( 'https' == $scheme || 'ssl' == $scheme ) {
   382 			$capabilities['ssl'] = true;
   385 			$capabilities['ssl'] = true;
   383 		}
   386 		}
   384 	}
   387 	}
   393  *
   396  *
   394  * @return string URL of the origin. Empty string if no origin.
   397  * @return string URL of the origin. Empty string if no origin.
   395  */
   398  */
   396 function get_http_origin() {
   399 function get_http_origin() {
   397 	$origin = '';
   400 	$origin = '';
   398 	if ( ! empty ( $_SERVER[ 'HTTP_ORIGIN' ] ) )
   401 	if ( ! empty( $_SERVER['HTTP_ORIGIN'] ) ) {
   399 		$origin = $_SERVER[ 'HTTP_ORIGIN' ];
   402 		$origin = $_SERVER['HTTP_ORIGIN'];
       
   403 	}
   400 
   404 
   401 	/**
   405 	/**
   402 	 * Change the origin of an HTTP request.
   406 	 * Change the origin of an HTTP request.
   403 	 *
   407 	 *
   404 	 * @since 3.4.0
   408 	 * @since 3.4.0
   415  *
   419  *
   416  * @return array Array of origin URLs.
   420  * @return array Array of origin URLs.
   417  */
   421  */
   418 function get_allowed_http_origins() {
   422 function get_allowed_http_origins() {
   419 	$admin_origin = parse_url( admin_url() );
   423 	$admin_origin = parse_url( admin_url() );
   420 	$home_origin = parse_url( home_url() );
   424 	$home_origin  = parse_url( home_url() );
   421 
   425 
   422 	// @todo preserve port?
   426 	// @todo preserve port?
   423 	$allowed_origins = array_unique( array(
   427 	$allowed_origins = array_unique(
   424 		'http://' . $admin_origin[ 'host' ],
   428 		array(
   425 		'https://' . $admin_origin[ 'host' ],
   429 			'http://' . $admin_origin['host'],
   426 		'http://' . $home_origin[ 'host' ],
   430 			'https://' . $admin_origin['host'],
   427 		'https://' . $home_origin[ 'host' ],
   431 			'http://' . $home_origin['host'],
   428 	) );
   432 			'https://' . $home_origin['host'],
       
   433 		)
       
   434 	);
   429 
   435 
   430 	/**
   436 	/**
   431 	 * Change the origin types allowed for HTTP requests.
   437 	 * Change the origin types allowed for HTTP requests.
   432 	 *
   438 	 *
   433 	 * @since 3.4.0
   439 	 * @since 3.4.0
   438 	 *     @type string Secure URL for admin origin.
   444 	 *     @type string Secure URL for admin origin.
   439 	 *     @type string Non-secure URL for home origin.
   445 	 *     @type string Non-secure URL for home origin.
   440 	 *     @type string Secure URL for home origin.
   446 	 *     @type string Secure URL for home origin.
   441 	 * }
   447 	 * }
   442 	 */
   448 	 */
   443 	return apply_filters( 'allowed_http_origins' , $allowed_origins );
   449 	return apply_filters( 'allowed_http_origins', $allowed_origins );
   444 }
   450 }
   445 
   451 
   446 /**
   452 /**
   447  * Determines if the HTTP origin is an authorized one.
   453  * Determines if the HTTP origin is an authorized one.
   448  *
   454  *
   452  * @return string Origin URL if allowed, empty string if not.
   458  * @return string Origin URL if allowed, empty string if not.
   453  */
   459  */
   454 function is_allowed_http_origin( $origin = null ) {
   460 function is_allowed_http_origin( $origin = null ) {
   455 	$origin_arg = $origin;
   461 	$origin_arg = $origin;
   456 
   462 
   457 	if ( null === $origin )
   463 	if ( null === $origin ) {
   458 		$origin = get_http_origin();
   464 		$origin = get_http_origin();
   459 
   465 	}
   460 	if ( $origin && ! in_array( $origin, get_allowed_http_origins() ) )
   466 
       
   467 	if ( $origin && ! in_array( $origin, get_allowed_http_origins() ) ) {
   461 		$origin = '';
   468 		$origin = '';
       
   469 	}
   462 
   470 
   463 	/**
   471 	/**
   464 	 * Change the allowed HTTP origin result.
   472 	 * Change the allowed HTTP origin result.
   465 	 *
   473 	 *
   466 	 * @since 3.4.0
   474 	 * @since 3.4.0
   486  */
   494  */
   487 function send_origin_headers() {
   495 function send_origin_headers() {
   488 	$origin = get_http_origin();
   496 	$origin = get_http_origin();
   489 
   497 
   490 	if ( is_allowed_http_origin( $origin ) ) {
   498 	if ( is_allowed_http_origin( $origin ) ) {
   491 		@header( 'Access-Control-Allow-Origin: ' .  $origin );
   499 		@header( 'Access-Control-Allow-Origin: ' . $origin );
   492 		@header( 'Access-Control-Allow-Credentials: true' );
   500 		@header( 'Access-Control-Allow-Credentials: true' );
   493 		if ( 'OPTIONS' === $_SERVER['REQUEST_METHOD'] )
   501 		if ( 'OPTIONS' === $_SERVER['REQUEST_METHOD'] ) {
   494 			exit;
   502 			exit;
       
   503 		}
   495 		return $origin;
   504 		return $origin;
   496 	}
   505 	}
   497 
   506 
   498 	if ( 'OPTIONS' === $_SERVER['REQUEST_METHOD'] ) {
   507 	if ( 'OPTIONS' === $_SERVER['REQUEST_METHOD'] ) {
   499 		status_header( 403 );
   508 		status_header( 403 );
   511  * @param string $url
   520  * @param string $url
   512  * @return false|string URL or false on failure.
   521  * @return false|string URL or false on failure.
   513  */
   522  */
   514 function wp_http_validate_url( $url ) {
   523 function wp_http_validate_url( $url ) {
   515 	$original_url = $url;
   524 	$original_url = $url;
   516 	$url = wp_kses_bad_protocol( $url, array( 'http', 'https' ) );
   525 	$url          = wp_kses_bad_protocol( $url, array( 'http', 'https' ) );
   517 	if ( ! $url || strtolower( $url ) !== strtolower( $original_url ) )
   526 	if ( ! $url || strtolower( $url ) !== strtolower( $original_url ) ) {
   518 		return false;
   527 		return false;
       
   528 	}
   519 
   529 
   520 	$parsed_url = @parse_url( $url );
   530 	$parsed_url = @parse_url( $url );
   521 	if ( ! $parsed_url || empty( $parsed_url['host'] ) )
   531 	if ( ! $parsed_url || empty( $parsed_url['host'] ) ) {
   522 		return false;
   532 		return false;
   523 
   533 	}
   524 	if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) )
   534 
       
   535 	if ( isset( $parsed_url['user'] ) || isset( $parsed_url['pass'] ) ) {
   525 		return false;
   536 		return false;
   526 
   537 	}
   527 	if ( false !== strpbrk( $parsed_url['host'], ':#?[]' ) )
   538 
       
   539 	if ( false !== strpbrk( $parsed_url['host'], ':#?[]' ) ) {
   528 		return false;
   540 		return false;
       
   541 	}
   529 
   542 
   530 	$parsed_home = @parse_url( get_option( 'home' ) );
   543 	$parsed_home = @parse_url( get_option( 'home' ) );
   531 
   544 
   532 	if ( isset( $parsed_home['host'] ) ) {
   545 	if ( isset( $parsed_home['host'] ) ) {
   533 		$same_host = strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] );
   546 		$same_host = strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] );
   539 		$host = trim( $parsed_url['host'], '.' );
   552 		$host = trim( $parsed_url['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 ) ) {
   553 		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 ) ) {
   541 			$ip = $host;
   554 			$ip = $host;
   542 		} else {
   555 		} else {
   543 			$ip = gethostbyname( $host );
   556 			$ip = gethostbyname( $host );
   544 			if ( $ip === $host ) // Error condition for gethostbyname()
   557 			if ( $ip === $host ) { // Error condition for gethostbyname()
   545 				$ip = false;
   558 				$ip = false;
       
   559 			}
   546 		}
   560 		}
   547 		if ( $ip ) {
   561 		if ( $ip ) {
   548 			$parts = array_map( 'intval', explode( '.', $ip ) );
   562 			$parts = array_map( 'intval', explode( '.', $ip ) );
   549 			if ( 127 === $parts[0] || 10 === $parts[0] || 0 === $parts[0]
   563 			if ( 127 === $parts[0] || 10 === $parts[0] || 0 === $parts[0]
   550 				|| ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )
   564 				|| ( 172 === $parts[0] && 16 <= $parts[1] && 31 >= $parts[1] )
   560 				 *
   574 				 *
   561 				 * @param bool   false Whether HTTP request is external or not.
   575 				 * @param bool   false Whether HTTP request is external or not.
   562 				 * @param string $host IP of the requested host.
   576 				 * @param string $host IP of the requested host.
   563 				 * @param string $url  URL of the requested host.
   577 				 * @param string $url  URL of the requested host.
   564 				 */
   578 				 */
   565 				if ( ! apply_filters( 'http_request_host_is_external', false, $host, $url ) )
   579 				if ( ! apply_filters( 'http_request_host_is_external', false, $host, $url ) ) {
   566 					return false;
   580 					return false;
       
   581 				}
   567 			}
   582 			}
   568 		}
   583 		}
   569 	}
   584 	}
   570 
   585 
   571 	if ( empty( $parsed_url['port'] ) )
   586 	if ( empty( $parsed_url['port'] ) ) {
   572 		return $url;
   587 		return $url;
       
   588 	}
   573 
   589 
   574 	$port = $parsed_url['port'];
   590 	$port = $parsed_url['port'];
   575 	if ( 80 === $port || 443 === $port || 8080 === $port )
   591 	if ( 80 === $port || 443 === $port || 8080 === $port ) {
   576 		return $url;
   592 		return $url;
   577 
   593 	}
   578 	if ( $parsed_home && $same_host && isset( $parsed_home['port'] ) && $parsed_home['port'] === $port )
   594 
       
   595 	if ( $parsed_home && $same_host && isset( $parsed_home['port'] ) && $parsed_home['port'] === $port ) {
   579 		return $url;
   596 		return $url;
       
   597 	}
   580 
   598 
   581 	return false;
   599 	return false;
   582 }
   600 }
   583 
   601 
   584 /**
   602 /**
   591  * @param bool   $is_external
   609  * @param bool   $is_external
   592  * @param string $host
   610  * @param string $host
   593  * @return bool
   611  * @return bool
   594  */
   612  */
   595 function allowed_http_request_hosts( $is_external, $host ) {
   613 function allowed_http_request_hosts( $is_external, $host ) {
   596 	if ( ! $is_external && wp_validate_redirect( 'http://' . $host ) )
   614 	if ( ! $is_external && wp_validate_redirect( 'http://' . $host ) ) {
   597 		$is_external = true;
   615 		$is_external = true;
       
   616 	}
   598 	return $is_external;
   617 	return $is_external;
   599 }
   618 }
   600 
   619 
   601 /**
   620 /**
   602  * Whitelists any domain in a multisite installation for safe HTTP requests.
   621  * Whitelists any domain in a multisite installation for safe HTTP requests.
   613  * @return bool
   632  * @return bool
   614  */
   633  */
   615 function ms_allowed_http_request_hosts( $is_external, $host ) {
   634 function ms_allowed_http_request_hosts( $is_external, $host ) {
   616 	global $wpdb;
   635 	global $wpdb;
   617 	static $queried = array();
   636 	static $queried = array();
   618 	if ( $is_external )
   637 	if ( $is_external ) {
   619 		return $is_external;
   638 		return $is_external;
   620 	if ( $host === get_network()->domain )
   639 	}
       
   640 	if ( $host === get_network()->domain ) {
   621 		return true;
   641 		return true;
   622 	if ( isset( $queried[ $host ] ) )
   642 	}
       
   643 	if ( isset( $queried[ $host ] ) ) {
   623 		return $queried[ $host ];
   644 		return $queried[ $host ];
       
   645 	}
   624 	$queried[ $host ] = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT domain FROM $wpdb->blogs WHERE domain = %s LIMIT 1", $host ) );
   646 	$queried[ $host ] = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT domain FROM $wpdb->blogs WHERE domain = %s LIMIT 1", $host ) );
   625 	return $queried[ $host ];
   647 	return $queried[ $host ];
   626 }
   648 }
   627 
   649 
   628 /**
   650 /**
   639  *
   661  *
   640  * Error suppression is used as prior to PHP 5.3.3, an E_WARNING would be generated
   662  * Error suppression is used as prior to PHP 5.3.3, an E_WARNING would be generated
   641  * when URL parsing failed.
   663  * when URL parsing failed.
   642  *
   664  *
   643  * @since 4.4.0
   665  * @since 4.4.0
   644  * @since 4.7.0 The $component parameter was added for parity with PHP's parse_url().
   666  * @since 4.7.0 The `$component` parameter was added for parity with PHP's `parse_url()`.
   645  *
   667  *
   646  * @link https://secure.php.net/manual/en/function.parse-url.php
   668  * @link https://secure.php.net/manual/en/function.parse-url.php
   647  *
   669  *
   648  * @param string $url       The URL to parse.
   670  * @param string $url       The URL to parse.
   649  * @param int    $component The specific component to retrieve. Use one of the PHP
   671  * @param int    $component The specific component to retrieve. Use one of the PHP
   654  *               doesn't exist in the given URL; a string or - in the case of
   676  *               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.
   677  *               PHP_URL_PORT - integer when it does. See parse_url()'s return values.
   656  */
   678  */
   657 function wp_parse_url( $url, $component = -1 ) {
   679 function wp_parse_url( $url, $component = -1 ) {
   658 	$to_unset = array();
   680 	$to_unset = array();
   659 	$url = strval( $url );
   681 	$url      = strval( $url );
   660 
   682 
   661 	if ( '//' === substr( $url, 0, 2 ) ) {
   683 	if ( '//' === substr( $url, 0, 2 ) ) {
   662 		$to_unset[] = 'scheme';
   684 		$to_unset[] = 'scheme';
   663 		$url = 'placeholder:' . $url;
   685 		$url        = 'placeholder:' . $url;
   664 	} elseif ( '/' === substr( $url, 0, 1 ) ) {
   686 	} elseif ( '/' === substr( $url, 0, 1 ) ) {
   665 		$to_unset[] = 'scheme';
   687 		$to_unset[] = 'scheme';
   666 		$to_unset[] = 'host';
   688 		$to_unset[] = 'host';
   667 		$url = 'placeholder://placeholder' . $url;
   689 		$url        = 'placeholder://placeholder' . $url;
   668 	}
   690 	}
   669 
   691 
   670 	$parts = @parse_url( $url );
   692 	$parts = @parse_url( $url );
   671 
   693 
   672 	if ( false === $parts ) {
   694 	if ( false === $parts ) {