diff --git a/src/wp-includes/rest-api/rest-functions.php b/src/wp-includes/rest-api/rest-functions.php index 947efce90e..d80e83985e 100644 --- a/src/wp-includes/rest-api/rest-functions.php +++ b/src/wp-includes/rest-api/rest-functions.php @@ -254,6 +254,13 @@ function get_rest_url( $blog_id = null, $path = '/', $scheme = 'rest' ) { $url = add_query_arg( 'rest_route', $path, $url ); } + if ( is_ssl() ) { + // If the current host is the same as the REST URL host, force the REST URL scheme to HTTPS + if ( $_SERVER['SERVER_NAME'] === parse_url( get_home_url( $blog_id ), PHP_URL_HOST ) ) { + $url = set_url_scheme( $url, 'https' ); + } + } + /** * Filter the REST URL. * diff --git a/tests/phpunit/tests/rest-api.php b/tests/phpunit/tests/rest-api.php index 93e627428f..64c14625ca 100644 --- a/tests/phpunit/tests/rest-api.php +++ b/tests/phpunit/tests/rest-api.php @@ -251,5 +251,64 @@ class Tests_REST_API extends WP_UnitTestCase { update_option( 'permalink_structure', '' ); // In non-pretty case, we get a query string to invoke the rest router. $this->assertEquals( 'http://' . WP_TESTS_DOMAIN . '/?rest_route=/', get_rest_url() ); + } + + /** + * @ticket 34299 + */ + public function test_rest_url_scheme() { + if ( isset( $_SERVER['HTTPS'] ) ) { + $_https = $_SERVER['HTTPS']; + } + if ( isset( $_SERVER['SERVER_NAME'] ) ) { + $_name = $_SERVER['SERVER_NAME']; + } + $_SERVER['SERVER_NAME'] = parse_url( home_url(), PHP_URL_HOST ); + $_siteurl = get_option( 'siteurl' ); + + // Test an HTTP URL + unset( $_SERVER['HTTPS'] ); + $url = get_rest_url(); + $this->assertSame( 'http', parse_url( $url, PHP_URL_SCHEME ) ); + + // Test an HTTPS URL + $_SERVER['HTTPS'] = 'on'; + $url = get_rest_url(); + $this->assertSame( 'https', parse_url( $url, PHP_URL_SCHEME ) ); + + // Switch to an admin request on a different domain name + $_SERVER['SERVER_NAME'] = 'admin.example.org'; + update_option( 'siteurl', 'http://admin.example.org' ); + $this->assertNotEquals( $_SERVER['SERVER_NAME'], parse_url( home_url(), PHP_URL_HOST ) ); + + set_current_screen( 'edit.php' ); + $this->assertTrue( is_admin() ); + + // Test an HTTP URL + unset( $_SERVER['HTTPS'] ); + $url = get_rest_url(); + $this->assertSame( 'http', parse_url( $url, PHP_URL_SCHEME ) ); + + // Test an HTTPS URL + $_SERVER['HTTPS'] = 'on'; + $url = get_rest_url(); + $this->assertSame( 'http', parse_url( $url, PHP_URL_SCHEME ) ); + + // Reset + if ( isset( $_https ) ) { + $_SERVER['HTTPS'] = $_https; + } else { + unset( $_SERVER['HTTPS'] ); + } + if ( isset( $_name ) ) { + $_SERVER['SERVER_NAME'] = $_name; + } else { + unset( $_SERVER['SERVER_NAME'] ); + } + update_option( 'siteurl', $_siteurl ); + set_current_screen( 'front' ); + + } + }