diff --git a/src/wp-includes/https-detection.php b/src/wp-includes/https-detection.php index f6562bbca0..2ced175047 100644 --- a/src/wp-includes/https-detection.php +++ b/src/wp-includes/https-detection.php @@ -88,6 +88,23 @@ function wp_is_https_supported() { * @access private */ function wp_update_https_detection_errors() { + /** + * Short-circuits the process of detecting errors related to HTTPS support. + * + * Returning a `WP_Error` from the filter will effectively short-circuit the default logic of trying a remote + * request to the site over HTTPS, storing the errors array from the returned `WP_Error` instead. + * + * @since 5.7.0 + * + * @param null|WP_Error $pre Error object to short-circuit detection, + * or null to continue with the default behavior. + */ + $support_errors = apply_filters( 'pre_wp_update_https_detection_errors', null ); + if ( is_wp_error( $support_errors ) ) { + update_option( 'https_detection_errors', $support_errors->errors ); + return; + } + $support_errors = new WP_Error(); $response = wp_remote_request( diff --git a/tests/phpunit/tests/https-detection.php b/tests/phpunit/tests/https-detection.php index b51284b6fc..3fcd8bcbb9 100644 --- a/tests/phpunit/tests/https-detection.php +++ b/tests/phpunit/tests/https-detection.php @@ -109,6 +109,37 @@ class Tests_HTTPS_Detection extends WP_UnitTestCase { $this->assertEquals( 'https://example.com/', $this->last_request_url ); } + /** + * @ticket 47577 + */ + public function test_pre_wp_update_https_detection_errors() { + // Override to enforce no errors being detected. + add_filter( + 'pre_wp_update_https_detection_errors', + function() { + return new WP_Error(); + } + ); + wp_update_https_detection_errors(); + $this->assertEquals( array(), get_option( 'https_detection_errors' ) ); + + // Override to enforce an error being detected. + add_filter( + 'pre_wp_update_https_detection_errors', + function() { + return new WP_Error( + 'ssl_verification_failed', + 'Bad SSL certificate.' + ); + } + ); + wp_update_https_detection_errors(); + $this->assertEquals( + array( 'ssl_verification_failed' => array( 'Bad SSL certificate.' ) ), + get_option( 'https_detection_errors' ) + ); + } + /** * @ticket 47577 */