From 9f90177b3f310ecb37de6748ef7ec5d2255cf368 Mon Sep 17 00:00:00 2001 From: Jonathan Desrosiers Date: Tue, 20 Oct 2020 14:48:50 +0000 Subject: [PATCH] Site Health: Improve the reliability of asynchronous tests. This change adds additional logic to catch HTTP failures that do not return a `WP_Error` object (for example, a wp-json REST API error error). This also fixes instances where REST API callbacks performed from cron do not work due to a lack of authentication by introducing a direct callback route that asynchronous tests can register. Props dd32, clorith, timothyblynjacobs. Fixes #51547. git-svn-id: https://develop.svn.wordpress.org/trunk@49232 602fd350-edb4-49c9-b593-d223f7449a82 --- .../includes/class-wp-site-health.php | 46 ++++++++++++------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php index dce08eba0d..31bec1145c 100644 --- a/src/wp-admin/includes/class-wp-site-health.php +++ b/src/wp-admin/includes/class-wp-site-health.php @@ -2155,19 +2155,22 @@ class WP_Site_Health { ), 'async' => array( 'dotorg_communication' => array( - 'label' => __( 'Communication with WordPress.org' ), - 'test' => rest_url( 'wp-site-health/v1/tests/dotorg-communication' ), - 'has_rest' => true, + 'label' => __( 'Communication with WordPress.org' ), + 'test' => rest_url( 'wp-site-health/v1/tests/dotorg-communication' ), + 'has_rest' => true, + 'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_dotorg_communication' ), ), 'background_updates' => array( - 'label' => __( 'Background updates' ), - 'test' => rest_url( 'wp-site-health/v1/tests/background-updates' ), - 'has_rest' => true, + 'label' => __( 'Background updates' ), + 'test' => rest_url( 'wp-site-health/v1/tests/background-updates' ), + 'has_rest' => true, + 'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_background_updates' ), ), 'loopback_requests' => array( - 'label' => __( 'Loopback request' ), - 'test' => rest_url( 'wp-site-health/v1/tests/loopback-requests' ), - 'has_rest' => true, + 'label' => __( 'Loopback request' ), + 'test' => rest_url( 'wp-site-health/v1/tests/loopback-requests' ), + 'has_rest' => true, + 'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_loopback_requests' ), ), ), ); @@ -2204,10 +2207,13 @@ class WP_Site_Health { * Plugins and themes are encouraged to prefix test identifiers with their slug * to avoid any collisions between tests. * - * @type string $label A friendly label for your test to identify it by. - * @type mixed $test A callable to perform a direct test, or a string AJAX action to be - * called to perform an async test. - * @type boolean $has_rest Optional. Denote if `$test` has a REST API endpoint. + * @type string $label A friendly label for your test to identify it by. + * @type mixed $test A callable to perform a direct test, or a string AJAX action to be + * called to perform an async test. + * @type boolean $has_rest Optional. Denote if `$test` has a REST API endpoint. + * @type callable $async_direct_test A manner of directly calling the test marked as asynchronous, as + * the scheduled event can not authenticate, and endpoints may require + * authentication. * } * } */ @@ -2550,10 +2556,18 @@ class WP_Site_Health { } foreach ( $tests['async'] as $test ) { + // Local endpoints may require authentication, so asynchronous tests can pass a direct test runner as well. + if ( ! empty( $test['async_direct_test'] ) && is_callable( $test['async_direct_test'] ) ) { + // This test is callable, do so and continue to the next asynchronous check. + $results[] = $this->perform_test( $test['async_direct_test'] ); + continue; + } + if ( is_string( $test['test'] ) ) { + // Check if this test has a REST API endpoint. if ( isset( $test['has_rest'] ) && $test['has_rest'] ) { - $result_fetch = wp_remote_post( - rest_url( $test['test'] ), + $result_fetch = wp_remote_get( + $test['test'], array( 'body' => array( '_wpnonce' => wp_create_nonce( 'wp_rest' ), @@ -2572,7 +2586,7 @@ class WP_Site_Health { ); } - if ( ! is_wp_error( $result_fetch ) ) { + if ( ! is_wp_error( $result_fetch ) && 200 === wp_remote_retrieve_response_code( $result_fetch ) ) { $result = json_decode( wp_remote_retrieve_body( $result_fetch ), true ); } else { $result = false;