From cacd0158567429cd4b4ff8dafc6524d490eec143 Mon Sep 17 00:00:00 2001 From: Dion Hulse Date: Fri, 23 Oct 2015 05:53:05 +0000 Subject: [PATCH] WP_HTTP: Promote the `WP_HTTP::parse_url()` method to a more generic `wp_parse_url()` function. Fixes #34408 git-svn-id: https://develop.svn.wordpress.org/trunk@35369 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/class-http.php | 39 ++++--------------------- src/wp-includes/http-functions.php | 46 ++++++++++++++++++++++++++++++ tests/phpunit/tests/http/http.php | 21 ++++---------- 3 files changed, 57 insertions(+), 49 deletions(-) diff --git a/src/wp-includes/class-http.php b/src/wp-includes/class-http.php index a600752388..1941c87d3a 100644 --- a/src/wp-includes/class-http.php +++ b/src/wp-includes/class-http.php @@ -688,45 +688,16 @@ class WP_Http { /** * A wrapper for PHP's parse_url() function that handles edgecases in < PHP 5.4.7 * - * PHP 5.4.7 expanded parse_url()'s ability to handle non-absolute url's, including - * schemeless and relative url's with :// in the path, this works around those - * limitations providing a standard output on PHP 5.2~5.4+. - * - * Error suppression is used as prior to PHP 5.3.3, an E_WARNING would be generated - * when URL parsing failed. - * - * @since 4.1.0 - * - * @static * @access protected + * @deprecated 4.4.0 See wp_parse_url() * * @param string $url The URL to parse. * @return bool|array False on failure; Array of URL components on success; * See parse_url()'s return values. */ protected static function parse_url( $url ) { - $parts = @parse_url( $url ); - if ( ! $parts ) { - // < PHP 5.4.7 compat, trouble with relative paths including a scheme break in the path - if ( '/' == $url[0] && false !== strpos( $url, '://' ) ) { - // Since we know it's a relative path, prefix with a scheme/host placeholder and try again - if ( ! $parts = @parse_url( 'placeholder://placeholder' . $url ) ) { - return $parts; - } - // Remove the placeholder values - unset( $parts['scheme'], $parts['host'] ); - } else { - return $parts; - } - } - - // < PHP 5.4.7 compat, doesn't detect schemeless URL's host field - if ( '//' == substr( $url, 0, 2 ) && ! isset( $parts['host'] ) ) { - list( $parts['host'], $slashless_path ) = explode( '/', substr( $parts['path'], 2 ), 2 ); - $parts['path'] = "/{$slashless_path}"; - } - - return $parts; + _deprecated_function( __METHOD__, '4.4.0', 'wp_parse_url()' ); + return wp_parse_url( $url ); } /** @@ -747,11 +718,11 @@ class WP_Http { if ( empty( $url ) ) return $maybe_relative_path; - if ( ! $url_parts = WP_Http::parse_url( $url ) ) { + if ( ! $url_parts = wp_parse_url( $url ) ) { return $maybe_relative_path; } - if ( ! $relative_url_parts = WP_Http::parse_url( $maybe_relative_path ) ) { + if ( ! $relative_url_parts = wp_parse_url( $maybe_relative_path ) ) { return $maybe_relative_path; } diff --git a/src/wp-includes/http-functions.php b/src/wp-includes/http-functions.php index 4b10b6a808..e2d1977adf 100644 --- a/src/wp-includes/http-functions.php +++ b/src/wp-includes/http-functions.php @@ -612,3 +612,49 @@ function ms_allowed_http_request_hosts( $is_external, $host ) { $queried[ $host ] = (bool) $wpdb->get_var( $wpdb->prepare( "SELECT domain FROM $wpdb->blogs WHERE domain = %s LIMIT 1", $host ) ); return $queried[ $host ]; } + +/** + * A wrapper for PHP's parse_url() function that handles edgecases in < PHP 5.4.7 + * + * PHP 5.4.7 expanded parse_url()'s ability to handle non-absolute url's, including + * schemeless and relative url's with :// in the path, this works around those + * limitations providing a standard output on PHP 5.2~5.4+. + * + * Error suppression is used as prior to PHP 5.3.3, an E_WARNING would be generated + * when URL parsing failed. + * + * @since 4.4.0 + * + * @param string $url The URL to parse. + * @return bool|array False on failure; Array of URL components on success; + * See parse_url()'s return values. + */ +function wp_parse_url( $url ) { + $parts = @parse_url( $url ); + if ( ! $parts ) { + // < PHP 5.4.7 compat, trouble with relative paths including a scheme break in the path + if ( '/' == $url[0] && false !== strpos( $url, '://' ) ) { + // Since we know it's a relative path, prefix with a scheme/host placeholder and try again + if ( ! $parts = @parse_url( 'placeholder://placeholder' . $url ) ) { + return $parts; + } + // Remove the placeholder values + unset( $parts['scheme'], $parts['host'] ); + } else { + return $parts; + } + } + + // < PHP 5.4.7 compat, doesn't detect schemeless URL's host field + if ( '//' == substr( $url, 0, 2 ) && ! isset( $parts['host'] ) ) { + $path_parts = explode( '/', substr( $parts['path'], 2 ), 2 ); + $parts['host'] = $path_parts[0]; + if ( isset( $path_parts[1] ) ) { + $parts['path'] = '/' . $path_parts[1]; + } else { + unset( $parts['path'] ); + } + } + + return $parts; +} diff --git a/tests/phpunit/tests/http/http.php b/tests/phpunit/tests/http/http.php index d1d669553e..80b83f9d33 100644 --- a/tests/phpunit/tests/http/http.php +++ b/tests/phpunit/tests/http/http.php @@ -70,12 +70,8 @@ class Tests_HTTP_HTTP extends WP_UnitTestCase { /** * @dataProvider parse_url_testcases */ - function test_parse_url( $url, $expected ) { - if ( ! is_callable( array( 'WP_HTTP_Testable', 'parse_url' ) ) ) { - $this->markTestSkipped( "This version of WP_HTTP doesn't support WP_HTTP::parse_url()" ); - return; - } - $actual = WP_HTTP_Testable::parse_url( $url ); + function test_wp_parse_url( $url, $expected ) { + $actual = wp_parse_url( $url ); $this->assertEquals( $expected, $actual ); } @@ -92,6 +88,10 @@ class Tests_HTTP_HTTP extends WP_UnitTestCase { // < PHP 5.4.7: Scheme seperator in the URL array( 'http://example.com/http://example.net/', array( 'scheme' => 'http', 'host' => 'example.com', 'path' => '/http://example.net/' ) ), array( '/path/http://example.net/', array( 'path' => '/path/http://example.net/' ) ), + + // < PHP 5.4.7: IPv6 literals in schemeless URLs are handled incorrectly. + array( '//[::FFFF::127.0.0.1]/', array( 'host' => '[::FFFF::127.0.0.1]', 'path' => '/' ) ), + // PHP's parse_url() calls this an invalid url, we handle it as a path array( '/://example.com/', array( 'path' => '/://example.com/' ) ), @@ -103,12 +103,3 @@ class Tests_HTTP_HTTP extends WP_UnitTestCase { */ } } - -/** - * A Wrapper of WP_Http to make parse_url() publicaly accessible for testing purposes. - */ -class WP_HTTP_Testable extends WP_Http { - public static function parse_url( $url ) { - return parent::parse_url( $url ); - } -} \ No newline at end of file