diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index 2a0c879b10..2f90b74dbd 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -993,9 +993,32 @@ function download_url( $url, $timeout = 300 ) { return $response; } - if ( 200 != wp_remote_retrieve_response_code( $response ) ) { + $response_code = wp_remote_retrieve_response_code( $response ); + + if ( 200 != $response_code ) { + $data = array( + 'code' => $response_code, + ); + + // Retrieve a sample of the response body for debugging purposes. + $tmpf = fopen( $tmpfname, 'rb' ); + if ( $tmpf ) { + /** + * Filters the maximum error response body size in `download_url()`. + * + * @since 5.0.0 + * + * @see download_url() + * + * @param int $size The maximum error response body size. Default 1 KB. + */ + $response_size = apply_filters( 'download_url_error_max_body_size', KB_IN_BYTES ); + $data['body'] = fread( $tmpf, $response_size ); + fclose( $tmpf ); + } + unlink( $tmpfname ); - return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ) ); + return new WP_Error( 'http_404', trim( wp_remote_retrieve_response_message( $response ) ), $data ); } $content_md5 = wp_remote_retrieve_header( $response, 'content-md5' ); diff --git a/tests/phpunit/tests/admin/includesFile.php b/tests/phpunit/tests/admin/includesFile.php index 7ecbd0ef2b..a25e79974e 100644 --- a/tests/phpunit/tests/admin/includesFile.php +++ b/tests/phpunit/tests/admin/includesFile.php @@ -31,4 +31,44 @@ class Tests_Admin_includesFile extends WP_UnitTestCase { update_option( 'siteurl', $siteurl ); $_SERVER['SCRIPT_FILENAME'] = $sfn; } + + /** + * @ticket 43329 + */ + public function test_download_url_non_200_response_code() { + add_filter( 'pre_http_request', array( $this, '_fake_download_url_non_200_response_code' ), 10, 3 ); + + $error = download_url( 'test_download_url_non_200' ); + $this->assertWPError( $error ); + $this->assertEquals( array( + 'code' => 418, + 'body' => 'This is an unexpected error message from your favorite server.', + ), $error->get_error_data() ); + + add_filter( 'download_url_error_max_body_size', array( $this, '__return_5' ) ); + + $error = download_url( 'test_download_url_non_200' ); + $this->assertWPError( $error ); + $this->assertEquals( array( + 'code' => 418, + 'body' => 'This ', + ), $error->get_error_data() ); + + remove_filter( 'download_url_error_max_body_size', array( $this, '__return_5' ) ); + remove_filter( 'pre_http_request', array( $this, '_fake_download_url_non_200_response_code' ) ); + } + + public function _fake_download_url_non_200_response_code( $response, $args, $url ) { + file_put_contents( $args['filename'], 'This is an unexpected error message from your favorite server.' ); + return array( + 'response' => array( + 'code' => 418, + 'message' => "I'm a teapot!", + ), + ); + } + + public function __return_5() { + return 5; + } }