From b986c827fbb62fa7e56a95605fe2a4fcf6876392 Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Fri, 17 Apr 2015 11:54:56 +0100
Subject: [PATCH] Issue #2368987 by Wim Leers, Berdir, Schnitzel, epari.siva,
 bircher, vijaycs85, likin: Move internal page caching to a module to avoid
 relying on config get on runtime

---
 core/core.services.yml                        |  7 +-
 core/lib/Drupal/Core/Form/FormCache.php       | 21 +----
 .../Tests/Authentication/BasicAuthTest.php    |  1 -
 core/modules/block/src/Tests/BlockTest.php    |  1 -
 core/modules/file/src/Tests/DownloadTest.php  | 13 ---
 .../src/Tests/ImageStylesPathAndUrlTest.php   | 27 ------
 .../language/src/LanguageNegotiator.php       | 15 +---
 .../LanguageNegotiationBrowser.php            | 10 +--
 ...igrate.migration.d6_system_performance.yml |  1 -
 .../Tests/d6/MigrateSystemPerformanceTest.php |  2 -
 core/modules/page_cache/page_cache.info.yml   |  6 ++
 core/modules/page_cache/page_cache.module     | 50 +++++++++++
 .../page_cache/page_cache.services.yml        |  6 ++
 .../src}/StackMiddleware/PageCache.php        | 49 ++---------
 .../Tests}/PageCacheTagsIntegrationTest.php   |  7 +-
 .../src/Tests}/PageCacheTest.php              | 83 ++++++-------------
 .../modules/page_cache_form_test.info.yml     |  6 ++
 .../modules/page_cache_form_test.install      | 13 +++
 .../tests/modules/page_cache_form_test.module | 20 +++++
 .../modules/page_cache_form_test.routing.yml  |  6 ++
 .../tests/modules/src/Form/TestForm.php       | 35 ++++++++
 .../src/Tests/SearchPageCacheTagsTest.php     |  7 --
 .../config/install/system.performance.yml     |  3 -
 .../system/config/schema/system.schema.yml    |  7 +-
 .../system/src/Form/PerformanceForm.php       | 22 +----
 .../src/Tests/Ajax/AjaxFormPageCacheTest.php  |  1 -
 .../AssertPageCacheContextsAndTagsTrait.php   |  1 -
 .../src/Tests/Cache/PageCacheTagsTestBase.php |  1 -
 .../Tests/Form/FormStoragePageCacheTest.php   |  1 -
 .../system/src/Tests/Session/SessionTest.php  |  6 +-
 .../src/Tests/System/ErrorHandlerTest.php     |  7 +-
 .../src/Tests/System/SiteMaintenanceTest.php  | 23 +----
 .../config/install/system.performance.yml     | 20 -----
 core/profiles/minimal/minimal.info.yml        |  1 +
 .../config/install/system.performance.yml     | 20 -----
 core/profiles/standard/standard.info.yml      |  1 +
 .../config/install/system.performance.yml     | 20 -----
 core/profiles/testing/testing.info.yml        |  4 +
 .../Drupal/Tests/Core/Form/FormCacheTest.php  | 47 +----------
 39 files changed, 201 insertions(+), 370 deletions(-)
 create mode 100644 core/modules/page_cache/page_cache.info.yml
 create mode 100644 core/modules/page_cache/page_cache.module
 create mode 100644 core/modules/page_cache/page_cache.services.yml
 rename core/{lib/Drupal/Core => modules/page_cache/src}/StackMiddleware/PageCache.php (87%)
 rename core/modules/{system/src/Tests/Cache => page_cache/src/Tests}/PageCacheTagsIntegrationTest.php (95%)
 rename core/modules/{system/src/Tests/Bootstrap => page_cache/src/Tests}/PageCacheTest.php (83%)
 create mode 100644 core/modules/page_cache/tests/modules/page_cache_form_test.info.yml
 create mode 100644 core/modules/page_cache/tests/modules/page_cache_form_test.install
 create mode 100644 core/modules/page_cache/tests/modules/page_cache_form_test.module
 create mode 100644 core/modules/page_cache/tests/modules/page_cache_form_test.routing.yml
 create mode 100644 core/modules/page_cache/tests/modules/src/Form/TestForm.php
 delete mode 100644 core/profiles/minimal/config/install/system.performance.yml
 delete mode 100644 core/profiles/standard/config/install/system.performance.yml
 delete mode 100644 core/profiles/testing/config/install/system.performance.yml

diff --git a/core/core.services.yml b/core/core.services.yml
index b1f3db8c878d..6127c8f99bda 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -300,7 +300,7 @@ services:
     arguments: ['@request_stack', '@url_generator']
   form_cache:
     class: Drupal\Core\Form\FormCache
-    arguments: ['@app.root', '@keyvalue.expirable', '@module_handler', '@current_user', '@csrf_token', '@logger.channel.form', '@config.factory', '@request_stack', '@page_cache_request_policy']
+    arguments: ['@app.root', '@keyvalue.expirable', '@module_handler', '@current_user', '@csrf_token', '@logger.channel.form', '@request_stack', '@page_cache_request_policy']
     public: false  # Private to form_builder
   keyvalue:
     class: Drupal\Core\KeyValueStore\KeyValueFactory
@@ -584,11 +584,6 @@ services:
     arguments: ['@settings']
     tags:
       - { name: http_middleware, priority: 300 }
-  http_middleware.page_cache:
-    class: Drupal\Core\StackMiddleware\PageCache
-    arguments: ['@cache.render', '@page_cache_request_policy', '@page_cache_response_policy']
-    tags:
-      - { name: http_middleware, priority: 200 }
   http_middleware.kernel_pre_handle:
     class: Drupal\Core\StackMiddleware\KernelPreHandle
     arguments: ['@kernel']
diff --git a/core/lib/Drupal/Core/Form/FormCache.php b/core/lib/Drupal/Core/Form/FormCache.php
index ea38fd2c60a3..a35000da4ea3 100644
--- a/core/lib/Drupal/Core/Form/FormCache.php
+++ b/core/lib/Drupal/Core/Form/FormCache.php
@@ -10,7 +10,6 @@
 use Drupal\Component\Utility\Crypt;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Access\CsrfTokenGenerator;
-use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
 use Drupal\Core\PageCache\RequestPolicyInterface;
@@ -104,20 +103,17 @@ class FormCache implements FormCacheInterface {
    *   The CSRF token generator.
    * @param \Psr\Log\LoggerInterface $logger
    *   A logger instance.
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
-   *   The configuration factory.
    * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
    *   The request stack.
    * @param \Drupal\Core\PageCache\RequestPolicyInterface $request_policy
    *   A policy rule determining the cacheability of a request.
    */
-  public function __construct($root, KeyValueExpirableFactoryInterface $key_value_expirable_factory, ModuleHandlerInterface $module_handler, AccountInterface $current_user, CsrfTokenGenerator $csrf_token, LoggerInterface $logger, ConfigFactoryInterface $config_factory, RequestStack $request_stack, RequestPolicyInterface $request_policy) {
+  public function __construct($root, KeyValueExpirableFactoryInterface $key_value_expirable_factory, ModuleHandlerInterface $module_handler, AccountInterface $current_user, CsrfTokenGenerator $csrf_token, LoggerInterface $logger, RequestStack $request_stack, RequestPolicyInterface $request_policy) {
     $this->root = $root;
     $this->keyValueExpirableFactory = $key_value_expirable_factory;
     $this->moduleHandler = $module_handler;
     $this->currentUser = $current_user;
     $this->logger = $logger;
-    $this->configFactory = $config_factory;
     $this->csrfToken = $csrf_token;
     $this->requestStack = $request_stack;
     $this->requestPolicy = $request_policy;
@@ -210,11 +206,6 @@ public function setCache($form_build_id, $form, FormStateInterface $form_state)
       $this->keyValueExpirableFactory->get('form')->setWithExpire($form_build_id, $form, $expire);
     }
 
-    // Cache form state.
-    if ($this->configFactory->get('system.performance')->get('cache.page.use_internal') && $this->isPageCacheable()) {
-      $form_state->addBuildInfo('immutable', TRUE);
-    }
-
     // Store the known list of safe strings for form re-use.
     // @todo Ensure we are not storing an excessively large string list in:
     //   https://www.drupal.org/node/2295823
@@ -225,14 +216,4 @@ public function setCache($form_build_id, $form, FormStateInterface $form_state)
     }
   }
 
-  /**
-   * Checks if the page is cacheable.
-   *
-   * @return bool
-   *   TRUE is the page is cacheable, FALSE if not.
-   */
-  protected function isPageCacheable() {
-    return ($this->requestPolicy->check($this->requestStack->getCurrentRequest()) === RequestPolicyInterface::ALLOW);
-  }
-
 }
diff --git a/core/modules/basic_auth/src/Tests/Authentication/BasicAuthTest.php b/core/modules/basic_auth/src/Tests/Authentication/BasicAuthTest.php
index 8a61f5bef093..fcc22393101a 100644
--- a/core/modules/basic_auth/src/Tests/Authentication/BasicAuthTest.php
+++ b/core/modules/basic_auth/src/Tests/Authentication/BasicAuthTest.php
@@ -32,7 +32,6 @@ class BasicAuthTest extends WebTestBase {
   public function testBasicAuth() {
     // Enable page caching.
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
 
diff --git a/core/modules/block/src/Tests/BlockTest.php b/core/modules/block/src/Tests/BlockTest.php
index f543476d470a..d6e0999ecbb7 100644
--- a/core/modules/block/src/Tests/BlockTest.php
+++ b/core/modules/block/src/Tests/BlockTest.php
@@ -313,7 +313,6 @@ public function testBlockCacheTags() {
 
     // Enable page caching.
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
 
diff --git a/core/modules/file/src/Tests/DownloadTest.php b/core/modules/file/src/Tests/DownloadTest.php
index 9de1b3a9276d..22bee7a56de5 100644
--- a/core/modules/file/src/Tests/DownloadTest.php
+++ b/core/modules/file/src/Tests/DownloadTest.php
@@ -51,19 +51,6 @@ public function testPrivateFileTransferWithoutPageCache() {
     $this->doPrivateFileTransferTest();
   }
 
-  /**
-   * Test the private file transfer system with page cache.
-   */
-  public function testPrivateFileTransferWithPageCache() {
-    // Turn on page caching and rerun the test.
-    $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
-    $config->set('cache.page.max_age', 300);
-    $config->save();
-
-    $this->doPrivateFileTransferTest();
-  }
-
   /**
    * Test the private file transfer system.
    */
diff --git a/core/modules/image/src/Tests/ImageStylesPathAndUrlTest.php b/core/modules/image/src/Tests/ImageStylesPathAndUrlTest.php
index abe8ffb01c03..16fc8e646d55 100644
--- a/core/modules/image/src/Tests/ImageStylesPathAndUrlTest.php
+++ b/core/modules/image/src/Tests/ImageStylesPathAndUrlTest.php
@@ -78,22 +78,6 @@ function testImageStyleUrlAndPathPrivateUnclean() {
     $this->doImageStyleUrlAndPathTests('private', FALSE);
   }
 
-  /**
-   * Tests an image style URL using the "public://" scheme and page cache.
-   */
-  public function testImageStyleUrlAndPathPublicWithPageCache() {
-    $this->enablePageCache();
-    $this->doImageStyleUrlAndPathTests('public');
-  }
-
-  /**
-   * Tests an image style URL using the "private://" scheme and page cache.
-   */
-  public function testImageStyleUrlAndPathPrivateWithPageCache() {
-    $this->enablePageCache();
-    $this->doImageStyleUrlAndPathTests('private');
-  }
-
   /**
    * Tests an image style URL with a file URL that has an extra slash in it.
    */
@@ -242,15 +226,4 @@ function doImageStyleUrlAndPathTests($scheme, $clean_url = TRUE, $extra_slash =
     $this->assertResponse(200, 'Image was accessible at the URL with a missing token.');
   }
 
-  /**
-   * Turn on page caching.
-   */
-  protected function enablePageCache() {
-    // Turn on page caching and rerun the test.
-    $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
-    $config->set('cache.page.max_age', 300);
-    $config->save();
-  }
-
 }
diff --git a/core/modules/language/src/LanguageNegotiator.php b/core/modules/language/src/LanguageNegotiator.php
index bc924fbf2a50..2354d888eea5 100644
--- a/core/modules/language/src/LanguageNegotiator.php
+++ b/core/modules/language/src/LanguageNegotiator.php
@@ -188,20 +188,7 @@ protected function negotiateLanguage($type, $method_id) {
     $method = $this->negotiatorManager->getDefinition($method_id);
 
     if (!isset($method['types']) || in_array($type, $method['types'])) {
-
-      // Check for a cache mode force from settings.php.
-      if ($this->settings->get('page_cache_without_database')) {
-        $cache_enabled = TRUE;
-      }
-      else {
-        $cache_enabled = $this->configFactory->get('system.performance')->get('cache.page.use_internal');
-      }
-
-      // If the language negotiation method has no cache preference or this is
-      // satisfied we can execute the callback.
-      if ($cache = !isset($method['cache']) || $this->currentUser->isAuthenticated() || $method['cache'] == $cache_enabled) {
-        $langcode = $this->getNegotiationMethodInstance($method_id)->getLangcode($this->requestStack->getCurrentRequest());
-      }
+      $langcode = $this->getNegotiationMethodInstance($method_id)->getLangcode($this->requestStack->getCurrentRequest());
     }
 
     $languages = $this->languageManager->getLanguages();
diff --git a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationBrowser.php b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationBrowser.php
index af36c7553d91..00c1fde60684 100644
--- a/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationBrowser.php
+++ b/core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationBrowser.php
@@ -35,16 +35,16 @@ class LanguageNegotiationBrowser extends LanguageNegotiationMethodBase {
   public function getLangcode(Request $request = NULL) {
     $langcode = NULL;
 
-    // Whenever browser-based language negotiation is used, the page cannot be
-    // cached by reverse proxies.
-    // @todo Solve more elegantly in https://www.drupal.org/node/2430335.
-    \Drupal::service('page_cache_kill_switch')->trigger();
-
     if ($this->languageManager && $request && $request->server->get('HTTP_ACCEPT_LANGUAGE')) {
       $http_accept_language = $request->server->get('HTTP_ACCEPT_LANGUAGE');
       $langcodes = array_keys($this->languageManager->getLanguages());
       $mappings = $this->config->get('language.mappings')->get('map');
       $langcode = UserAgent::getBestMatchingLangcode($http_accept_language, $langcodes, $mappings);
+      // Internal page cache with multiple languages and browser negotiation
+      // could lead to wrong cached sites. Therefore disabling the internal
+      // page cache.
+      // @todo Solve more elegantly in https://www.drupal.org/node/2430335.
+      \Drupal::service('page_cache_kill_switch')->trigger();
     }
 
     return $langcode;
diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_system_performance.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_system_performance.yml
index 2b6f478e9d2f..c27f3a9024a6 100644
--- a/core/modules/migrate_drupal/config/install/migrate.migration.d6_system_performance.yml
+++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_system_performance.yml
@@ -14,7 +14,6 @@ process:
   'css/preprocess': preprocess_css
   'js/preprocess': preprocess_js
   'cache/page/max_age': cache_lifetime
-  'cache/page/use_internal': cache
   'response/gzip': page_compression
 destination:
   plugin: config
diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemPerformanceTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemPerformanceTest.php
index 168e2e6f0020..2f137202a7bf 100644
--- a/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemPerformanceTest.php
+++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateSystemPerformanceTest.php
@@ -40,8 +40,6 @@ public function testSystemPerformance() {
     $this->assertIdentical(FALSE, $config->get('css.preprocess'));
     $this->assertIdentical(FALSE, $config->get('js.preprocess'));
     $this->assertIdentical(0, $config->get('cache.page.max_age'));
-    $this->assertIdentical(TRUE, $config->get('cache.page.use_internal'));
-    $this->assertIdentical(TRUE, $config->get('response.gzip'));
   }
 
 }
diff --git a/core/modules/page_cache/page_cache.info.yml b/core/modules/page_cache/page_cache.info.yml
new file mode 100644
index 000000000000..af72fab03616
--- /dev/null
+++ b/core/modules/page_cache/page_cache.info.yml
@@ -0,0 +1,6 @@
+name: Internal page cache
+type: module
+description: 'Caches pages for anonymous users. Works well for small to medium-sized websites.'
+package: Core
+version: VERSION
+core: 8.x
diff --git a/core/modules/page_cache/page_cache.module b/core/modules/page_cache/page_cache.module
new file mode 100644
index 000000000000..6322363b4a8d
--- /dev/null
+++ b/core/modules/page_cache/page_cache.module
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @file
+ * Caches responses for anonymous users, request and response policies allowing.
+ */
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\PageCache\RequestPolicyInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+
+/**
+ * Implements hook_help().
+ */
+function page_cache_help($route_name, RouteMatchInterface $route_match) {
+  switch ($route_name) {
+    case 'help.page.page_cache':
+      $output = '<h3>' . t('About') . '</h3>';
+      $output .= '<p>' . t('The Internal page cache module caches pages for anonymous users in the database.') . '</p>';
+      $output .= '<h3>' . t('Uses') . '</h3>';
+      $output .= '<dl>';
+      $output .= '<dt>' . t('Speeding up your site') . '</dt>';
+      $output .= '<dd>';
+      $output .= '<p>' . t('Pages requested by anonymous users are stored the first time they are requested and then reused; depending on your site configuration and the amount of your web traffic tied to anonymous visitors, the caching system may significantly increase the speed of your site.');
+      $output .= '<p>' . t('(For authenticated users, pages need to be assembled for each user individually, but anonymous users all get the exact same version of each page.)') . '</p>';
+      $output .= '</dd>';
+      $output .= '<dt>' . t('Configuring Internal page cache') . '</dt>';
+      $output .= '<dd>';
+      $output .= '<p>' . t('On the <a href="@cache-settings">Performance settings page</a>, you can configure how long browsers and proxies may cache pages, that setting is also respected by the Internal page cache module. There is no other configuration.', array('@cache-settings' => \Drupal::url('system.performance_settings')))  . '</p>';
+      $output .= '</dd>';
+      $output .= '</dl>';
+
+      return $output;
+  }
+}
+
+/**
+ * Implements hook_form_alter().
+ */
+function page_cache_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+  // If the page that's being built is cacheable, set the 'immutable' flag, to
+  // ensure that when the form is used, a new form build ID is generated when
+  // appropriate, to prevent information disclosure.
+  $request_policy = \Drupal::service('page_cache_request_policy');
+  $request = \Drupal::requestStack()->getCurrentRequest();
+  $request_is_cacheable = $request_policy->check($request) === RequestPolicyInterface::ALLOW;
+  if ($request_is_cacheable) {
+    $form_state->addBuildInfo('immutable', TRUE);
+  }
+}
diff --git a/core/modules/page_cache/page_cache.services.yml b/core/modules/page_cache/page_cache.services.yml
new file mode 100644
index 000000000000..bbddfa701090
--- /dev/null
+++ b/core/modules/page_cache/page_cache.services.yml
@@ -0,0 +1,6 @@
+services:
+  http_middleware.page_cache:
+    class: Drupal\page_cache\StackMiddleware\PageCache
+    arguments: ['@cache.render', '@page_cache_request_policy', '@page_cache_response_policy']
+    tags:
+      - { name: http_middleware, priority: 200 }
diff --git a/core/lib/Drupal/Core/StackMiddleware/PageCache.php b/core/modules/page_cache/src/StackMiddleware/PageCache.php
similarity index 87%
rename from core/lib/Drupal/Core/StackMiddleware/PageCache.php
rename to core/modules/page_cache/src/StackMiddleware/PageCache.php
index d4ec291494e6..b0dcce81f8df 100644
--- a/core/lib/Drupal/Core/StackMiddleware/PageCache.php
+++ b/core/modules/page_cache/src/StackMiddleware/PageCache.php
@@ -2,11 +2,12 @@
 
 /**
  * @file
- * Contains \Drupal\Core\StackMiddleware\PageCache.
+ * Contains \Drupal\page_cache\StackMiddleware\PageCache.
  */
 
-namespace Drupal\Core\StackMiddleware;
+namespace Drupal\page_cache\StackMiddleware;
 
+use Drupal\Component\Utility\UserAgent;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\PageCache\RequestPolicyInterface;
@@ -52,7 +53,7 @@ class PageCache implements HttpKernelInterface {
   protected $responsePolicy;
 
   /**
-   * Constructs a ReverseProxyMiddleware object.
+   * Constructs a PageCache object.
    *
    * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
    *   The decorated kernel.
@@ -74,20 +75,8 @@ public function __construct(HttpKernelInterface $http_kernel, CacheBackendInterf
    * {@inheritdoc}
    */
   public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
-    if ($type !== static::MASTER_REQUEST) {
-      // Only allow page caching on master request.
-      $cache_enabled = FALSE;
-    }
-    elseif (Settings::get('page_cache_without_database')) {
-      // Check for a cache mode force from settings.php.
-      $cache_enabled = TRUE;
-    }
-    else {
-      $config = $this->config('system.performance');
-      $cache_enabled = $config->get('cache.page.use_internal');
-    }
-
-    if ($cache_enabled && $this->requestPolicy->check($request) === RequestPolicyInterface::ALLOW) {
+    // Only allow page caching on master request.
+    if ($type === static::MASTER_REQUEST && $this->requestPolicy->check($request) === RequestPolicyInterface::ALLOW) {
       $response = $this->lookup($request, $type, $catch);
     }
     else {
@@ -232,20 +221,6 @@ protected function fetch(Request $request, $type = self::MASTER_REQUEST, $catch
       return $response;
     }
 
-    // Check if the current page may be compressed.
-    if (extension_loaded('zlib') && !$response->headers->get('Content-Encoding') && $this->config('system.performance')->get('response.gzip')) {
-      $content = $response->getContent();
-      if ($content) {
-        $response->setContent(gzencode($content, 9, FORCE_GZIP));
-        $response->headers->set('Content-Encoding', 'gzip');
-      }
-
-      // When page compression is enabled, ensure that proxy caches will record
-      // and deliver different versions of a page depending on whether the
-      // client supports gzip or not.
-      $response->setVary('Accept-Encoding', FALSE);
-    }
-
     // Use the actual timestamp from an Expires header, if available.
     $date = $response->getExpires();
     $expire = ($date > (new \DateTime())) ? $date->getTimestamp() : Cache::PERMANENT;
@@ -326,16 +301,4 @@ protected function getCacheId(Request $request) {
     return implode(':', $cid_parts);
   }
 
-  /**
-   * Wraps Drupal::config().
-   *
-   * Config factory is not injected into this class in order to prevent
-   * premature initialization of config storage (database).
-   *
-   * @see \Drupal::config()
-   */
-  protected function config($name) {
-    return \Drupal::config($name);
-  }
-
 }
diff --git a/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php b/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php
similarity index 95%
rename from core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php
rename to core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php
index 119ecdf28364..c6af0ac19dc0 100644
--- a/core/modules/system/src/Tests/Cache/PageCacheTagsIntegrationTest.php
+++ b/core/modules/page_cache/src/Tests/PageCacheTagsIntegrationTest.php
@@ -2,19 +2,20 @@
 
 /**
  * @file
- * Contains \Drupal\system\Tests\Cache\PageCacheTagsIntegrationTest.
+ * Contains \Drupal\page_cache\Tests\PageCacheTagsIntegrationTest.
  */
 
-namespace Drupal\system\Tests\Cache;
+namespace Drupal\page_cache\Tests;
 
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\simpletest\WebTestBase;
+use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
 
 /**
  * Enables the page cache and tests its cache tags in various scenarios.
  *
  * @group Cache
- * @see \Drupal\system\Tests\Bootstrap\PageCacheTest
+ * @see \Drupal\page_cache\Tests\PageCacheTest
  * @see \Drupal\node\Tests\NodePageCacheTest
  * @see \Drupal\menu_ui\Tests\MenuTest::testMenuBlockPageCacheTags()
  */
diff --git a/core/modules/system/src/Tests/Bootstrap/PageCacheTest.php b/core/modules/page_cache/src/Tests/PageCacheTest.php
similarity index 83%
rename from core/modules/system/src/Tests/Bootstrap/PageCacheTest.php
rename to core/modules/page_cache/src/Tests/PageCacheTest.php
index 6746368d3411..b3b0430cbcd6 100644
--- a/core/modules/system/src/Tests/Bootstrap/PageCacheTest.php
+++ b/core/modules/page_cache/src/Tests/PageCacheTest.php
@@ -2,13 +2,12 @@
 
 /**
  * @file
- * Definition of Drupal\system\Tests\Bootstrap\PageCacheTest.
+ * Contains \Drupal\page_cache\Tests\PageCacheTest.
  */
 
-namespace Drupal\system\Tests\Bootstrap;
+namespace Drupal\page_cache\Tests;
 
 use Drupal\Component\Datetime\DateTimePlus;
-use Drupal\Core\Routing\RequestContext;
 use Drupal\Core\Url;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\simpletest\WebTestBase;
@@ -19,7 +18,7 @@
 /**
  * Enables the page cache and tests it with various HTTP requests.
  *
- * @group Bootstrap
+ * @group page_cache
  */
 class PageCacheTest extends WebTestBase {
 
@@ -32,6 +31,9 @@ class PageCacheTest extends WebTestBase {
    */
   public static $modules = array('test_page_test', 'system_test', 'entity_test');
 
+  /**
+   * {@inheritdoc}
+   */
   protected function setUp() {
     parent::setUp();
 
@@ -49,7 +51,6 @@ protected function setUp() {
    */
   function testPageCacheTags() {
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
 
@@ -82,24 +83,21 @@ function testPageCacheTags() {
    */
   function testAcceptHeaderRequests() {
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
 
-    $url_generator = \Drupal::urlGenerator();
-    $url_generator->setContext(new RequestContext());
-    $accept_header_cache_uri = $url_generator->getPathFromRoute('system_test.page_cache_accept_header');
+    $accept_header_cache_url = Url::fromRoute('system_test.page_cache_accept_header');
     $json_accept_header = array('Accept: application/json');
 
-    $this->drupalGet($accept_header_cache_uri);
+    $this->drupalGet($accept_header_cache_url);
     $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'HTML page was not yet cached.');
-    $this->drupalGet($accept_header_cache_uri);
+    $this->drupalGet($accept_header_cache_url);
     $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'HTML page was cached.');
     $this->assertRaw('<p>oh hai this is html.</p>', 'The correct HTML response was returned.');
 
-    $this->drupalGet($accept_header_cache_uri, array(), $json_accept_header);
+    $this->drupalGet($accept_header_cache_url, array(), $json_accept_header);
     $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Json response was not yet cached.');
-    $this->drupalGet($accept_header_cache_uri, array(), $json_accept_header);
+    $this->drupalGet($accept_header_cache_url, array(), $json_accept_header);
     $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Json response was cached.');
     $this->assertRaw('{"content":"oh hai this is json"}', 'The correct Json response was returned.');
 
@@ -153,7 +151,6 @@ function testAcceptHeaderRequests() {
    */
   function testConditionalRequests() {
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
 
@@ -198,7 +195,6 @@ function testConditionalRequests() {
    */
   function testPageCache() {
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->set('response.gzip', 1);
     $config->save();
@@ -258,9 +254,8 @@ function testPageCache() {
    * This test verifies that, and it verifies that it does not happen for other
    * roles.
    */
-  function testPageCacheAnonymousRolePermissions() {
+  public function testPageCacheAnonymousRolePermissions() {
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
 
@@ -359,7 +354,6 @@ function testPageCacheAnonymous403404() {
    */
   public function testPageCacheWithoutVaryCookie() {
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
 
@@ -373,58 +367,33 @@ public function testPageCacheWithoutVaryCookie() {
     $this->drupalGet('');
     $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.');
     $this->assertTrue(strpos($this->drupalGetHeader('Vary'), 'Cookie') === FALSE, 'Vary: Cookie header was not sent.');
+    $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public', 'Cache-Control header was sent.');
 
     // Check cache.
     $this->drupalGet('');
     $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.');
     $this->assertTrue(strpos($this->drupalGetHeader('Vary'), 'Cookie') === FALSE, 'Vary: Cookie header was not sent.');
+    $this->assertEqual($this->drupalGetHeader('Cache-Control'), 'max-age=300, public', 'Cache-Control header was sent.');
   }
 
   /**
-   * Tests page compression.
-   *
-   * The test should pass even if zlib.output_compression is enabled in php.ini,
-   * .htaccess or similar, or if compression is done outside PHP, e.g. by the
-   * mod_deflate Apache module.
+   * Test the setting of forms to be immutable.
    */
-  function testPageCompression() {
-    $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
-    $config->set('cache.page.max_age', 300);
-    $config->set('response.gzip', 1);
-    $config->save();
-
-    // Fill the cache and verify that output is compressed.
-    $this->drupalGet('', array(), array('Accept-Encoding: gzip,deflate'));
-    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.');
-    $this->setRawContent(gzinflate(substr($this->getRawContent(), 10, -8)));
-    $this->assertRaw('</html>', 'Page was gzip compressed.');
+  public function testFormImmutability() {
+    // Install the module that provides the test form.
+    $this->container->get('module_installer')
+      ->install(['page_cache_form_test']);
+    \Drupal::service('router.builder')->rebuild();
 
-    // Verify that cached output is compressed.
-    $this->drupalGet('', array(), array('Accept-Encoding: gzip,deflate'));
-    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.');
-    $this->assertEqual($this->drupalGetHeader('Content-Encoding'), 'gzip', 'A Content-Encoding header was sent.');
-    $this->setRawContent(gzinflate(substr($this->getRawContent(), 10, -8)));
-    $this->assertRaw('</html>', 'Page was gzip compressed.');
+    $this->drupalGet('page_cache_form_test_immutability');
 
-    // Verify that a client without compression support gets an uncompressed page.
-    $this->drupalGet('');
-    $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.');
-    $this->assertFalse($this->drupalGetHeader('Content-Encoding'), 'A Content-Encoding header was not sent.');
-    $this->assertTitle(t('Test page | @site-name', array('@site-name' => $this->config('system.site')->get('name'))), 'Site title matches.');
-    $this->assertRaw('</html>', 'Page was not compressed.');
+    $this->assertText("Immutable: TRUE", "Form is immutable.");
 
-    // Disable compression mode.
-    $config->set('response.gzip', 0);
-    $config->save();
+    // Uninstall the page_cache module, verify the flag is not set.
+    $this->container->get('module_installer')->uninstall(['page_cache']);
 
-    // Verify if cached page is still available for a client with compression support.
-    $this->drupalGet('', array(), array('Accept-Encoding: gzip,deflate'));
-    $this->setRawContent(gzinflate(substr($this->getRawContent(), 10, -8)));
-    $this->assertRaw('</html>', 'Page was delivered after compression mode is changed (compression support enabled).');
+    $this->drupalGet('page_cache_form_test_immutability');
 
-    // Verify if cached page is still available for a client without compression support.
-    $this->drupalGet('');
-    $this->assertRaw('</html>', 'Page was delivered after compression mode is changed (compression support disabled).');
+    $this->assertText("Immutable: FALSE", "Form is not immutable,");
   }
 }
diff --git a/core/modules/page_cache/tests/modules/page_cache_form_test.info.yml b/core/modules/page_cache/tests/modules/page_cache_form_test.info.yml
new file mode 100644
index 000000000000..e18bb53498b4
--- /dev/null
+++ b/core/modules/page_cache/tests/modules/page_cache_form_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Page Cache Form Test'
+type: module
+description: 'Support module for the Page Cache module tests.'
+core: 8.x
+package: Testing
+version: VERSION
diff --git a/core/modules/page_cache/tests/modules/page_cache_form_test.install b/core/modules/page_cache/tests/modules/page_cache_form_test.install
new file mode 100644
index 000000000000..ecd7db803e53
--- /dev/null
+++ b/core/modules/page_cache/tests/modules/page_cache_form_test.install
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ *
+ * Install hooks for page_cache_form_test.
+ */
+
+function page_cache_form_test_install() {
+  // Set an explicit module weight, to ensure that the form alter hook is
+  // always called after page_cache_form_alter().
+  module_set_weight('page_cache_form_test', 10);
+}
diff --git a/core/modules/page_cache/tests/modules/page_cache_form_test.module b/core/modules/page_cache/tests/modules/page_cache_form_test.module
new file mode 100644
index 000000000000..506cf8a1cf4f
--- /dev/null
+++ b/core/modules/page_cache/tests/modules/page_cache_form_test.module
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @file
+ * Provides functionality for testing form caching.
+ */
+
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+* Implements hook_form_FORM_ID_alter().
+*/
+function page_cache_form_test_form_page_cache_form_test_alter(&$form, FormStateInterface $form_state, $form_id) {
+  if (isset($form_state->getBuildInfo()['immutable']) && $form_state->getBuildInfo()['immutable']) {
+    $form['#suffix'] = 'Immutable: TRUE';
+  }
+  else {
+    $form['#suffix'] = 'Immutable: FALSE';
+  }
+}
diff --git a/core/modules/page_cache/tests/modules/page_cache_form_test.routing.yml b/core/modules/page_cache/tests/modules/page_cache_form_test.routing.yml
new file mode 100644
index 000000000000..fce728d74d52
--- /dev/null
+++ b/core/modules/page_cache/tests/modules/page_cache_form_test.routing.yml
@@ -0,0 +1,6 @@
+page_cache_form_test.test_immutability:
+  path: '/page_cache_form_test_immutability'
+  defaults:
+    _form: '\Drupal\page_cache_form_test\Form\TestForm'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/page_cache/tests/modules/src/Form/TestForm.php b/core/modules/page_cache/tests/modules/src/Form/TestForm.php
new file mode 100644
index 000000000000..535f2b238a12
--- /dev/null
+++ b/core/modules/page_cache/tests/modules/src/Form/TestForm.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\page_cache_form_test\Form\TestForm.
+ */
+
+namespace Drupal\page_cache_form_test\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+
+class TestForm extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'page_cache_form_test';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $form['#prefix'] = '<p>Llamas are awesome, but kittens are pretty cool too!</p>';
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) { }
+
+}
diff --git a/core/modules/search/src/Tests/SearchPageCacheTagsTest.php b/core/modules/search/src/Tests/SearchPageCacheTagsTest.php
index f54662f8dd55..cd5db6814552 100644
--- a/core/modules/search/src/Tests/SearchPageCacheTagsTest.php
+++ b/core/modules/search/src/Tests/SearchPageCacheTagsTest.php
@@ -39,13 +39,6 @@ class SearchPageCacheTagsTest extends SearchTestBase {
   protected function setUp() {
     parent::setUp();
 
-    // Enable the page cache.
-    // @todo Remove in https://www.drupal.org/node/606840.
-    $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
-    $config->set('cache.page.max_age', 300);
-    $config->save();
-
     // Create user.
     $this->searchingUser = $this->drupalCreateUser(array('search content', 'access user profiles'));
 
diff --git a/core/modules/system/config/install/system.performance.yml b/core/modules/system/config/install/system.performance.yml
index 1e75b4b86903..11392bd1e4ab 100644
--- a/core/modules/system/config/install/system.performance.yml
+++ b/core/modules/system/config/install/system.performance.yml
@@ -1,6 +1,5 @@
 cache:
   page:
-    use_internal: false
     max_age: 0
 css:
   preprocess: true
@@ -13,6 +12,4 @@ fast_404:
 js:
   preprocess: true
   gzip: true
-response:
-  gzip: false
 stale_file_threshold: 2592000
diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml
index 3ba947eb84ed..7cde50d5a1b2 100644
--- a/core/modules/system/config/schema/system.schema.yml
+++ b/core/modules/system/config/schema/system.schema.yml
@@ -155,14 +155,11 @@ system.performance:
       mapping:
         page:
           type: mapping
-          label: 'Page cache'
+          label: 'Page caching'
           mapping:
-            use_internal:
-              type: boolean
-              label: 'Use internal page cache'
             max_age:
               type: integer
-              label: 'Max age of page cache'
+              label: 'Max age'
     css:
       type: mapping
       label: 'CSS performance settings'
diff --git a/core/modules/system/src/Form/PerformanceForm.php b/core/modules/system/src/Form/PerformanceForm.php
index bb8c9b148ea2..7171a4118109 100644
--- a/core/modules/system/src/Form/PerformanceForm.php
+++ b/core/modules/system/src/Form/PerformanceForm.php
@@ -121,6 +121,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#type' => 'details',
       '#title' => t('Caching'),
       '#open' => TRUE,
+      '#description' => $this->t('Note: Drupal provides an internal page cache module that is recommended for small to medium-sized websites.'),
     );
     // Identical options to the ones for block caching.
     // @see \Drupal\Core\Block\BlockBase::buildConfigurationForm()
@@ -132,14 +133,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#title' => t('Page cache maximum age'),
       '#default_value' => $config->get('cache.page.max_age'),
       '#options' => $period,
-      '#description' => t('The maximum time a page can be cached. This is used as the value for max-age in Cache-Control headers.'),
-    );
-
-    $form['caching']['cache'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Use internal page cache'),
-      '#description' => t("If a reverse proxy cache isn't available, use Drupal's internal cache system to store cached pages."),
-      '#default_value' => $config->get('cache.page.use_internal'),
+      '#description' => t('The maximum time a page can be cached by browsers and proxies. This is used as the value for max-age in Cache-Control headers.'),
     );
 
     $directory = 'public://';
@@ -157,16 +151,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#description' => t('External resources can be optimized automatically, which can reduce both the size and number of requests made to your website.') . $disabled_message,
     );
 
-    $form['bandwidth_optimization']['page_compression'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Compress cached pages'),
-      '#default_value' => $config->get('response.gzip'),
-      '#states' => array(
-        'visible' => array(
-          'input[name="cache"]' => array('checked' => TRUE),
-        ),
-      ),
-    );
     $form['bandwidth_optimization']['preprocess_css'] = array(
       '#type' => 'checkbox',
       '#title' => t('Aggregate CSS files'),
@@ -195,9 +179,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->renderCache->deleteAll();
 
     $this->config('system.performance')
-      ->set('cache.page.use_internal', $form_state->getValue('cache'))
       ->set('cache.page.max_age', $form_state->getValue('page_cache_maximum_age'))
-      ->set('response.gzip', $form_state->getValue('page_compression'))
       ->set('css.preprocess', $form_state->getValue('preprocess_css'))
       ->set('js.preprocess', $form_state->getValue('preprocess_js'))
       ->save();
diff --git a/core/modules/system/src/Tests/Ajax/AjaxFormPageCacheTest.php b/core/modules/system/src/Tests/Ajax/AjaxFormPageCacheTest.php
index 13125b892a62..c5dafbe11185 100644
--- a/core/modules/system/src/Tests/Ajax/AjaxFormPageCacheTest.php
+++ b/core/modules/system/src/Tests/Ajax/AjaxFormPageCacheTest.php
@@ -21,7 +21,6 @@ public function setUp() {
     parent::setUp();
 
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
   }
diff --git a/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php b/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php
index a9330baa8e33..43e24ec46abf 100644
--- a/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php
+++ b/core/modules/system/src/Tests/Cache/AssertPageCacheContextsAndTagsTrait.php
@@ -21,7 +21,6 @@ trait AssertPageCacheContextsAndTagsTrait {
    */
   protected function enablePageCaching() {
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
   }
diff --git a/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php b/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php
index 87958bf92964..b4f40bddb0a4 100644
--- a/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php
+++ b/core/modules/system/src/Tests/Cache/PageCacheTagsTestBase.php
@@ -31,7 +31,6 @@ protected function setUp() {
 
     // Enable page caching.
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 3600);
     $config->save();
   }
diff --git a/core/modules/system/src/Tests/Form/FormStoragePageCacheTest.php b/core/modules/system/src/Tests/Form/FormStoragePageCacheTest.php
index d04be90406b9..5fa8c34bec1d 100644
--- a/core/modules/system/src/Tests/Form/FormStoragePageCacheTest.php
+++ b/core/modules/system/src/Tests/Form/FormStoragePageCacheTest.php
@@ -28,7 +28,6 @@ protected function setUp() {
     parent::setUp();
 
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
   }
diff --git a/core/modules/system/src/Tests/Session/SessionTest.php b/core/modules/system/src/Tests/Session/SessionTest.php
index 4e67192871e2..632cbcd3d430 100644
--- a/core/modules/system/src/Tests/Session/SessionTest.php
+++ b/core/modules/system/src/Tests/Session/SessionTest.php
@@ -155,16 +155,14 @@ public function testSessionPersistenceOnLogin() {
   function testEmptyAnonymousSession() {
     // Verify that no session is automatically created for anonymous user when
     // page caching is disabled.
-    $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 0);
-    $config->save();
+    $this->container->get('module_installer')->uninstall(['page_cache']);
     $this->drupalGet('');
     $this->assertSessionCookie(FALSE);
     $this->assertSessionEmpty(TRUE);
 
     // The same behavior is expected when caching is enabled.
+    $this->container->get('module_installer')->install(['page_cache']);
     $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
     $config->set('cache.page.max_age', 300);
     $config->save();
     $this->drupalGet('');
diff --git a/core/modules/system/src/Tests/System/ErrorHandlerTest.php b/core/modules/system/src/Tests/System/ErrorHandlerTest.php
index ed03bcc2c24b..a42686bf06cd 100644
--- a/core/modules/system/src/Tests/System/ErrorHandlerTest.php
+++ b/core/modules/system/src/Tests/System/ErrorHandlerTest.php
@@ -160,12 +160,7 @@ function testExceptionHandler() {
     $this->assertTrue(strpos($this->drupalGetHeader(':status'), '500 Service unavailable (with message)'), 'Received expected HTTP status line.');
     $this->assertErrorMessage($error_renderer_exception);
 
-    // Enable the page cache and disable error reporting, ensure that 5xx
-    // responses are not cached.
-    $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
-    $config->set('cache.page.max_age', 300);
-    $config->save();
+    // Disable error reporting, ensure that 5xx responses are not cached.
     $this->config('system.logging')
       ->set('error_level', ERROR_REPORTING_HIDE)
       ->save();
diff --git a/core/modules/system/src/Tests/System/SiteMaintenanceTest.php b/core/modules/system/src/Tests/System/SiteMaintenanceTest.php
index 4ce0a828a920..95e474719874 100644
--- a/core/modules/system/src/Tests/System/SiteMaintenanceTest.php
+++ b/core/modules/system/src/Tests/System/SiteMaintenanceTest.php
@@ -38,31 +38,10 @@ protected function setUp() {
     $this->drupalLogin($this->adminUser);
   }
 
-  /**
-   * Verify site maintenance mode functionality with page cache disabled.
-   */
-  function testSiteMaintenanceWithoutPageCache() {
-    $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 0);
-    $config->save();
-    $this->doTestSiteMaintenance();
-  }
-
-  /**
-   * Verify site maintenance mode functionality with page cache enabled.
-   */
-  function testSiteMaintenanceWithPageCache() {
-    $config = $this->config('system.performance');
-    $config->set('cache.page.use_internal', 1);
-    $config->set('cache.page.max_age', 300);
-    $config->save();
-    $this->doTestSiteMaintenance();
-  }
-
   /**
    * Verify site maintenance mode functionality.
    */
-  protected function doTestSiteMaintenance() {
+  protected function testSiteMaintenance() {
     // Turn on maintenance mode.
     $edit = array(
       'maintenance_mode' => 1,
diff --git a/core/profiles/minimal/config/install/system.performance.yml b/core/profiles/minimal/config/install/system.performance.yml
deleted file mode 100644
index 18238d5baa1f..000000000000
--- a/core/profiles/minimal/config/install/system.performance.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-cache:
-  page:
-    # @todo: Remove this file in https://www.drupal.org/node/2368987, update the
-    #   install profile's YAML file to depend on the page_cache module instead.
-    use_internal: true
-    max_age: 0
-css:
-  preprocess: true
-  gzip: true
-fast_404:
-  enabled: true
-  paths: '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'
-  exclude_paths: '/\/(?:styles|imagecache)\//'
-  html: '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>'
-js:
-  preprocess: true
-  gzip: true
-response:
-  gzip: false
-stale_file_threshold: 2592000
diff --git a/core/profiles/minimal/minimal.info.yml b/core/profiles/minimal/minimal.info.yml
index d1f83de86ea6..206b8e7fc23c 100644
--- a/core/profiles/minimal/minimal.info.yml
+++ b/core/profiles/minimal/minimal.info.yml
@@ -7,5 +7,6 @@ dependencies:
   - node
   - block
   - dblog
+  - page_cache
 themes:
   - stark
diff --git a/core/profiles/standard/config/install/system.performance.yml b/core/profiles/standard/config/install/system.performance.yml
deleted file mode 100644
index 18238d5baa1f..000000000000
--- a/core/profiles/standard/config/install/system.performance.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-cache:
-  page:
-    # @todo: Remove this file in https://www.drupal.org/node/2368987, update the
-    #   install profile's YAML file to depend on the page_cache module instead.
-    use_internal: true
-    max_age: 0
-css:
-  preprocess: true
-  gzip: true
-fast_404:
-  enabled: true
-  paths: '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'
-  exclude_paths: '/\/(?:styles|imagecache)\//'
-  html: '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>'
-js:
-  preprocess: true
-  gzip: true
-response:
-  gzip: false
-stale_file_threshold: 2592000
diff --git a/core/profiles/standard/standard.info.yml b/core/profiles/standard/standard.info.yml
index a1c07b23815b..a356ae85b770 100644
--- a/core/profiles/standard/standard.info.yml
+++ b/core/profiles/standard/standard.info.yml
@@ -25,6 +25,7 @@ dependencies:
   - menu_ui
   - options
   - path
+  - page_cache
   - taxonomy
   - dblog
   - search
diff --git a/core/profiles/testing/config/install/system.performance.yml b/core/profiles/testing/config/install/system.performance.yml
deleted file mode 100644
index 18238d5baa1f..000000000000
--- a/core/profiles/testing/config/install/system.performance.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-cache:
-  page:
-    # @todo: Remove this file in https://www.drupal.org/node/2368987, update the
-    #   install profile's YAML file to depend on the page_cache module instead.
-    use_internal: true
-    max_age: 0
-css:
-  preprocess: true
-  gzip: true
-fast_404:
-  enabled: true
-  paths: '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i'
-  exclude_paths: '/\/(?:styles|imagecache)\//'
-  html: '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>'
-js:
-  preprocess: true
-  gzip: true
-response:
-  gzip: false
-stale_file_threshold: 2592000
diff --git a/core/profiles/testing/testing.info.yml b/core/profiles/testing/testing.info.yml
index 1eb843d28ed9..5ded376b9a32 100644
--- a/core/profiles/testing/testing.info.yml
+++ b/core/profiles/testing/testing.info.yml
@@ -4,6 +4,10 @@ description: 'Minimal profile for running tests. Includes absolutely required mo
 version: VERSION
 core: 8.x
 hidden: true
+dependencies:
+  # Enable page_cache in testing, to ensure that as many tests as possible run
+  # with page caching enabled.
+  - page_cache
 # @todo: Remove this in https://www.drupal.org/node/2352949
 themes:
   - classy
diff --git a/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php b/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php
index 138309e6e9b8..4f145dc5ba98 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormCacheTest.php
@@ -74,13 +74,6 @@ class FormCacheTest extends UnitTestCase {
    */
   protected $logger;
 
-  /**
-   * The config factory.
-   *
-   * @var \Drupal\Core\Config\ConfigFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $configFactory;
-
   /**
    * The request stack.
    *
@@ -121,11 +114,10 @@ protected function setUp() {
     $this->account = $this->getMock('Drupal\Core\Session\AccountInterface');
 
     $this->logger = $this->getMock('Psr\Log\LoggerInterface');
-    $this->configFactory = $this->getConfigFactoryStub(['system.performance' => ['cache.page.use_internal' => FALSE]]);
     $this->requestStack = $this->getMock('\Symfony\Component\HttpFoundation\RequestStack');
     $this->requestPolicy = $this->getMock('\Drupal\Core\PageCache\RequestPolicyInterface');
 
-    $this->formCache = new FormCache($this->root, $this->keyValueExpirableFactory, $this->moduleHandler, $this->account, $this->csrfToken, $this->logger, $this->configFactory, $this->requestStack, $this->requestPolicy);
+    $this->formCache = new FormCache($this->root, $this->keyValueExpirableFactory, $this->moduleHandler, $this->account, $this->csrfToken, $this->logger, $this->requestStack, $this->requestPolicy);
   }
 
   /**
@@ -486,43 +478,6 @@ public function testSetCacheBuildIdMismatch() {
     $this->formCache->setCache($form_build_id, $form, $form_state);
   }
 
-  /**
-   * @covers ::setCache
-   */
-  public function testSetCacheImmutableForm() {
-    $form_build_id = 'the_form_build_id';
-    $form = [
-      '#form_id' => 'the_form_id',
-    ];
-    $form_state = new FormState();
-
-    $this->formCacheStore->expects($this->once())
-      ->method('setWithExpire')
-      ->with($form_build_id, $form, $this->isType('int'));
-    $form_state_data = $form_state->getCacheableArray();
-    $form_state_data['build_info']['safe_strings'] = [];
-    // Ensure that the form is marked immutable.
-    $form_state_data['build_info']['immutable'] = TRUE;
-    $this->formStateCacheStore->expects($this->once())
-      ->method('setWithExpire')
-      ->with($form_build_id, $form_state_data, $this->isType('int'));
-
-    // Rebuild the FormCache with a config factory that will return a config
-    // object with the internal page cache enabled.
-    $this->configFactory = $this->getConfigFactoryStub(['system.performance' => ['cache.page.use_internal' => TRUE]]);
-    $root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
-    $this->formCache = $this->getMockBuilder('Drupal\Core\Form\FormCache')
-      ->setConstructorArgs([$root, $this->keyValueExpirableFactory, $this->moduleHandler, $this->account, $this->csrfToken, $this->logger, $this->configFactory, $this->requestStack, $this->requestPolicy])
-      ->setMethods(['isPageCacheable'])
-      ->getMock();
-
-    $this->formCache->expects($this->once())
-      ->method('isPageCacheable')
-      ->willReturn(TRUE);
-
-    $this->formCache->setCache($form_build_id, $form, $form_state);
-  }
-
   /**
    * Ensures SafeMarkup does not bleed from one test to another.
    */
-- 
GitLab