diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 0d6c25e6b1..934d312e72 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -239,7 +239,7 @@ function install_state_defaults() { // The server URL where the interface translation files can be downloaded. // Tokens in the pattern will be replaced by appropriate values for the // required translation file. - 'server_pattern' => 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po', + 'server_pattern' => 'https://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po', // Installation tasks can set this to TRUE to force the page request to // end (even if there is no themable output), in the case of an interactive // installation. This is needed only rarely; for example, it would be used diff --git a/core/modules/locale/config/install/locale.settings.yml b/core/modules/locale/config/install/locale.settings.yml index 857a369351..a6cd4f3043 100644 --- a/core/modules/locale/config/install/locale.settings.yml +++ b/core/modules/locale/config/install/locale.settings.yml @@ -5,7 +5,7 @@ javascript: translation: use_source: remote_and_local default_filename: '%project-%version.%language.po' - default_server_pattern: 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po' + default_server_pattern: 'https://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po' overwrite_customized: false overwrite_not_customized: true update_interval_days: 0 diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index b1298e4b67..9e424484b8 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -99,7 +99,7 @@ * * @see locale_translation_default_translation_server(). */ -const LOCALE_TRANSLATION_DEFAULT_SERVER_PATTERN = 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po'; +const LOCALE_TRANSLATION_DEFAULT_SERVER_PATTERN = 'https://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po'; /** * The number of seconds that the translations status entry should be considered. diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal6.php b/core/modules/migrate_drupal/tests/fixtures/drupal6.php index 4ca588b9c7..d9b7f95819 100644 --- a/core/modules/migrate_drupal/tests/fixtures/drupal6.php +++ b/core/modules/migrate_drupal/tests/fixtures/drupal6.php @@ -45250,7 +45250,7 @@ 'name' => 'update', 'type' => 'module', 'owner' => '', - 'status' => '0', + 'status' => '1', 'throttle' => '0', 'bootstrap' => '0', 'schema_version' => '-1', diff --git a/core/modules/update/config/schema/update.source.schema.yml b/core/modules/update/config/schema/update.source.schema.yml new file mode 100644 index 0000000000..02777ac809 --- /dev/null +++ b/core/modules/update/config/schema/update.source.schema.yml @@ -0,0 +1,12 @@ +# Schema for the migration source plugins. + +migrate.source.update_settings: + type: migrate_source_sql + label: 'Drupal update settings' + mapping: + variables: + type: sequence + label: 'Variables' + sequence: + type: string + label: 'Variable' diff --git a/core/modules/update/migration_templates/update_settings.yml b/core/modules/update/migration_templates/update_settings.yml index a7adfd7dc6..5dcdf2922c 100644 --- a/core/modules/update/migration_templates/update_settings.yml +++ b/core/modules/update/migration_templates/update_settings.yml @@ -4,7 +4,7 @@ migration_tags: - Drupal 6 - Drupal 7 source: - plugin: variable + plugin: update_settings variables: - update_max_fetch_attempts - update_fetch_url diff --git a/core/modules/update/src/Plugin/migrate/source/UpdateSettings.php b/core/modules/update/src/Plugin/migrate/source/UpdateSettings.php new file mode 100644 index 0000000000..27137fd883 --- /dev/null +++ b/core/modules/update/src/Plugin/migrate/source/UpdateSettings.php @@ -0,0 +1,28 @@ +fetchUrl = $config_factory->get('update.settings')->get('fetch.url'); $this->httpClient = $http_client; $this->updateSettings = $config_factory->get('update.settings'); + $this->withHttpFallback = $settings->get('update_fetch_with_http_fallback', FALSE); } /** @@ -59,6 +70,25 @@ public function __construct(ConfigFactoryInterface $config_factory, ClientInterf */ public function fetchProjectData(array $project, $site_key = '') { $url = $this->buildFetchUrl($project, $site_key); + return $this->doRequest($url, ['headers' => ['Accept' => 'text/xml']], $this->withHttpFallback); + } + + /** + * Applies a GET request with a http fallback. + * + * This method falls back to http in case there was some certificate + * problem. + * + * @param string $url + * The URL. + * @param array $options. + * The guzzle client options. + * @param bool $with_http_fallback + * Should the function fall back to http. + * + * @return string + */ + protected function doRequest($url, array $options, $with_http_fallback) { $data = ''; try { $data = (string) $this->httpClient @@ -67,6 +97,11 @@ public function fetchProjectData(array $project, $site_key = '') { } catch (RequestException $exception) { watchdog_exception('update', $exception); + + if ($with_http_fallback && strpos($exception->getMessage(), 'SSL certificate problem: Invalid') !== FALSE) { + $url = str_replace('https://', 'http://', $url); + return $this->doRequest($url, $options, FALSE); + } } return $data; } diff --git a/core/modules/update/tests/src/Kernel/Migrate/d6/MigrateUpdateConfigsTest.php b/core/modules/update/tests/src/Kernel/Migrate/d6/MigrateUpdateConfigsTest.php index aa3563c608..ba3144ced5 100644 --- a/core/modules/update/tests/src/Kernel/Migrate/d6/MigrateUpdateConfigsTest.php +++ b/core/modules/update/tests/src/Kernel/Migrate/d6/MigrateUpdateConfigsTest.php @@ -33,7 +33,7 @@ protected function setUp() { public function testUpdateSettings() { $config = $this->config('update.settings'); $this->assertIdentical(2, $config->get('fetch.max_attempts')); - $this->assertIdentical('http://updates.drupal.org/release-history', $config->get('fetch.url')); + $this->assertIdentical('https://updates.drupal.org/release-history', $config->get('fetch.url')); $this->assertIdentical('all', $config->get('notification.threshold')); $this->assertIdentical([], $config->get('notification.emails')); $this->assertIdentical(7, $config->get('check.interval_days')); diff --git a/core/modules/update/tests/src/Unit/UpdateFetcherTest.php b/core/modules/update/tests/src/Unit/UpdateFetcherTest.php index c3e447d1fc..e89b7b3a8f 100644 --- a/core/modules/update/tests/src/Unit/UpdateFetcherTest.php +++ b/core/modules/update/tests/src/Unit/UpdateFetcherTest.php @@ -2,6 +2,7 @@ namespace Drupal\Tests\update\Unit; +use Drupal\Core\Site\Settings; use Drupal\Tests\UnitTestCase; use Drupal\update\UpdateFetcher; @@ -29,7 +30,8 @@ class UpdateFetcherTest extends UnitTestCase { protected function setUp() { $config_factory = $this->getConfigFactoryStub(['update.settings' => ['fetch_url' => 'http://www.example.com']]); $http_client_mock = $this->getMock('\GuzzleHttp\ClientInterface'); - $this->updateFetcher = new UpdateFetcher($config_factory, $http_client_mock); + $settings = new Settings([]); + $this->updateFetcher = new UpdateFetcher($config_factory, $http_client_mock, $settings); } /** diff --git a/core/modules/update/update.services.yml b/core/modules/update/update.services.yml index fc176d6f7b..cbbd498ae9 100644 --- a/core/modules/update/update.services.yml +++ b/core/modules/update/update.services.yml @@ -12,7 +12,7 @@ services: arguments: ['@config.factory', '@queue', '@update.fetcher', '@state', '@private_key', '@keyvalue', '@keyvalue.expirable'] update.fetcher: class: Drupal\update\UpdateFetcher - arguments: ['@config.factory', '@http_client'] + arguments: ['@config.factory', '@http_client', '@settings'] update.root: class: SplString factory: update.root.factory:get diff --git a/core/profiles/testing/config/optional/locale.settings.yml b/core/profiles/testing/config/optional/locale.settings.yml index f1842a0207..acdee550ec 100644 --- a/core/profiles/testing/config/optional/locale.settings.yml +++ b/core/profiles/testing/config/optional/locale.settings.yml @@ -4,7 +4,7 @@ javascript: translation: use_source: remote_and_local default_filename: '%project-%version.%language.po' - default_server_pattern: 'http://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po' + default_server_pattern: 'https://ftp.drupal.org/files/translations/%core/%project/%project-%version.%language.po' overwrite_customized: false overwrite_not_customized: true update_interval_days: 0 diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index c7dd194350..1e1e2cdb76 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -320,6 +320,17 @@ */ $settings['update_free_access'] = FALSE; +/** + * Fallback to HTTP for update status. + * + * If your Drupal site fails to connect to drupal.org using HTTPS to fetch + * Drupal core and module update status, you may uncomment this setting + * and set to TRUE to allow an insecure fallback to HTTP. + * + * @see \Drupal\update\UpdateFetcher + */ +# $settings['update_fetch_with_http_fallback'] = FALSE; + /** * External access proxy settings: *