Skip to content

Commit

Permalink
Merge pull request #186 from wp-cli/fix/disable-http-request-retry-by…
Browse files Browse the repository at this point in the history
…-default
  • Loading branch information
schlessera authored May 10, 2021
2 parents 12bcc24 + c1b1187 commit cc32c8a
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 44 deletions.
90 changes: 46 additions & 44 deletions src/Core_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use WP_CLI\Iterators\Table as TableIterator;
use WP_CLI\Utils;
use WP_CLI\Formatter;
use WP_CLI\WpOrgApi;

/**
* Downloads, installs, updates, and manages a WordPress installation.
Expand Down Expand Up @@ -116,6 +117,9 @@ public function check_update( $_, $assoc_args ) {
* [--force]
* : Overwrites existing files, if present.
*
* [--insecure]
* : Retry download without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
*
* ## EXAMPLES
*
* $ wp core download --locale=nl_NL
Expand Down Expand Up @@ -153,8 +157,9 @@ public function download( $args, $assoc_args ) {
WP_CLI::error( "'{$download_dir}' is not writable by current user." );
}

$locale = Utils\get_flag_value( $assoc_args, 'locale', 'en_US' );
$skip_content = Utils\get_flag_value( $assoc_args, 'skip-content' );
$locale = (string) Utils\get_flag_value( $assoc_args, 'locale', 'en_US' );
$skip_content = (bool) Utils\get_flag_value( $assoc_args, 'skip-content', false );
$insecure = (bool) Utils\get_flag_value( $assoc_args, 'insecure', false );

$download_url = array_shift( $args );
$from_url = ! empty( $download_url );
Expand All @@ -180,12 +185,17 @@ public function download( $args, $assoc_args ) {

$download_url = $this->get_download_url( $version, $locale, $extension );
} else {
$offer = $this->get_download_offer( $locale );
try {
$offer = ( new WpOrgApi( [ 'insecure' => $insecure ] ) )
->get_core_download_offer( $locale );
} catch ( Exception $exception ) {
WP_CLI::error( $exception );
}
if ( ! $offer ) {
WP_CLI::error( "The requested locale ({$locale}) was not found." );
}
$version = $offer->current;
$download_url = $offer->download;
$version = $offer['current'];
$download_url = $offer['download'];
if ( ! $skip_content ) {
$download_url = str_replace( '.zip', '.tar.gz', $download_url );
}
Expand Down Expand Up @@ -256,6 +266,7 @@ function () use ( $temp ) {
$options = [
'timeout' => 600, // 10 minutes ought to be enough for everybody
'filename' => $temp,
'insecure' => $insecure,
];

$response = Utils\http_request( 'GET', $download_url, null, $headers, $options );
Expand All @@ -267,7 +278,8 @@ function () use ( $temp ) {
}

if ( 'nightly' !== $version ) {
$md5_response = Utils\http_request( 'GET', $download_url . '.md5' );
unset( $options['filename'] );
$md5_response = Utils\http_request( 'GET', $download_url . '.md5', null, [], $options );
if ( $md5_response->status_code >= 200 && $md5_response->status_code < 300 ) {
$md5_file = md5_file( $temp );

Expand Down Expand Up @@ -299,37 +311,12 @@ function () use ( $temp ) {
}

if ( $wordpress_present ) {
$this->cleanup_extra_files( $from_version, $version, $locale );
$this->cleanup_extra_files( $from_version, $version, $locale, $insecure );
}

WP_CLI::success( 'WordPress downloaded.' );
}

private static function read( $url ) {
$headers = [ 'Accept' => 'application/json' ];
$response = Utils\http_request( 'GET', $url, null, $headers, [ 'timeout' => 30 ] );
if ( 200 === $response->status_code ) {
return $response->body;
} else {
WP_CLI::error( "Couldn't fetch response from {$url} (HTTP code {$response->status_code})." );
}
}

private function get_download_offer( $locale ) {
$out = self::read( 'https://api.wordpress.org/core/version-check/1.7/?locale=' . $locale );
$out = function_exists( 'wp_json_decode' )
? wp_json_decode( $out )
: json_decode( $out );

$offer = $out->offers[0];

if ( $offer->locale !== $locale ) {
return false;
}

return $offer;
}

/**
* Checks if WordPress is installed.
*
Expand Down Expand Up @@ -952,16 +939,20 @@ private static function find_var( $var_name, $code ) {
/**
* Security copy of the core function with Requests - Gets the checksums for the given version of WordPress.
*
* @param string $version Version string to query.
* @param string $locale Locale to query.
* @param string $version Version string to query.
* @param string $locale Locale to query.
* @param bool $insecure Whether to retry without certificate validation on TLS handshake failure.
* @return string|array String message on failure. An array of checksums on success.
*/
private static function get_core_checksums( $version, $locale ) {
private static function get_core_checksums( $version, $locale, $insecure ) {
$query = http_build_query( compact( 'version', 'locale' ), null, '&' );
$url = "https://api.wordpress.org/core/checksums/1.0/?{$query}";

$options = [ 'timeout' => 30 ];
$headers = [ 'Accept' => 'application/json' ];
$options = [
'timeout' => 30,
'insecure' => $insecure,
];

$response = Utils\http_request( 'GET', $url, null, $headers, $options );

Expand Down Expand Up @@ -1007,6 +998,9 @@ private static function get_core_checksums( $version, $locale ) {
* [--locale=<locale>]
* : Select which language you want to download.
*
* [--insecure]
* : Retry download without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
*
* ## EXAMPLES
*
* # Update WordPress
Expand Down Expand Up @@ -1043,7 +1037,6 @@ public function update( $args, $assoc_args ) {
global $wp_version;

$update = null;
$from_api = null;
$upgrader = 'WP_CLI\\Core\\CoreUpgrader';

if ( 'trunk' === Utils\get_flag_value( $assoc_args, 'version' ) ) {
Expand Down Expand Up @@ -1094,7 +1087,7 @@ public function update( $args, $assoc_args ) {
list( $update ) = $from_api->updates;
}
}
} elseif ( \WP_CLI\Utils\wp_version_compare( $assoc_args['version'], '<' )
} elseif ( Utils\wp_version_compare( $assoc_args['version'], '<' )
|| 'nightly' === $assoc_args['version']
|| Utils\get_flag_value( $assoc_args, 'force' ) ) {

Expand Down Expand Up @@ -1133,9 +1126,10 @@ public function update( $args, $assoc_args ) {
}

$from_version = $wp_version;
$insecure = (bool) Utils\get_flag_value( $assoc_args, 'insecure', false );

$GLOBALS['wpcli_core_update_obj'] = $update;
$result = Utils\get_upgrader( $upgrader )->upgrade( $update );
$result = Utils\get_upgrader( $upgrader, $insecure )->upgrade( $update );
unset( $GLOBALS['wpcli_core_update_obj'] );

if ( is_wp_error( $result ) ) {
Expand All @@ -1153,8 +1147,8 @@ public function update( $args, $assoc_args ) {
$to_version = $wp_details['wp_version'];
}

$locale = Utils\get_flag_value( $assoc_args, 'locale', get_locale() );
$this->cleanup_extra_files( $from_version, $to_version, $locale );
$locale = (string) Utils\get_flag_value( $assoc_args, 'locale', get_locale() );
$this->cleanup_extra_files( $from_version, $to_version, $locale, $insecure );

WP_CLI::success( 'WordPress updated successfully.' );
}
Expand Down Expand Up @@ -1347,18 +1341,26 @@ private function get_updates( $assoc_args ) {
return array_values( $updates );
}

private function cleanup_extra_files( $version_from, $version_to, $locale ) {
/**
* Clean up extra files.
*
* @param string $version_from Starting version that the installation was updated from.
* @param string $version_to Target version that the installation is updated to.
* @param string $locale Locale of the installation.
* @param bool $insecure Whether to retry without certificate validation on TLS handshake failure.
*/
private function cleanup_extra_files( $version_from, $version_to, $locale, $insecure ) {
if ( ! $version_from || ! $version_to ) {
WP_CLI::warning( 'Failed to find WordPress version. Please cleanup files manually.' );
return;
}

$old_checksums = self::get_core_checksums( $version_from, $locale ?: 'en_US' );
$old_checksums = self::get_core_checksums( $version_from, $locale ?: 'en_US', $insecure );
if ( ! is_array( $old_checksums ) ) {
WP_CLI::warning( "{$old_checksums} Please cleanup files manually." );
return;
}
$new_checksums = self::get_core_checksums( $version_to, $locale ?: 'en_US' );
$new_checksums = self::get_core_checksums( $version_to, $locale ?: 'en_US', $insecure );
if ( ! is_array( $new_checksums ) ) {
WP_CLI::warning( "{$new_checksums} Please cleanup files manually." );
return;
Expand Down
18 changes: 18 additions & 0 deletions src/WP_CLI/Core/CoreUpgrader.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,23 @@
*/
class CoreUpgrader extends DefaultCoreUpgrader {

/**
* Whether to retry without certificate validation on TLS handshake failure.
*
* @var bool
*/
private $insecure;

/**
* CoreUpgrader constructor.
*
* @param WP_Upgrader_Skin|null $skin
*/
public function __construct( $skin = null, $insecure = false ) {
$this->insecure = $insecure;
parent::__construct( $skin );
}

/**
* Caches the download, and uses cached if available.
*
Expand Down Expand Up @@ -93,6 +110,7 @@ function () use ( $temp ) {
'timeout' => 600, // 10 minutes ought to be enough for everybody.
'filename' => $temp,
'halt_on_error' => false,
'insecure' => $this->insecure,
];

$this->skin->feedback( 'downloading_package', $package );
Expand Down

0 comments on commit cc32c8a

Please sign in to comment.