diff --git a/core/core.services.yml b/core/core.services.yml index af7be21..cbcaa60 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -296,7 +296,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 @@ -580,11 +580,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 ea38fd2..a35000d 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 8a61f5b..fcc2239 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 f543476..d6e0999 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 9de1b3a..22bee7a 100644 --- a/core/modules/file/src/Tests/DownloadTest.php +++ b/core/modules/file/src/Tests/DownloadTest.php @@ -52,19 +52,6 @@ public function testPrivateFileTransferWithoutPageCache() { } /** - * 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. */ protected function doPrivateFileTransferTest() { diff --git a/core/modules/image/src/Tests/ImageStylesPathAndUrlTest.php b/core/modules/image/src/Tests/ImageStylesPathAndUrlTest.php index abe8ffb..16fc8e6 100644 --- a/core/modules/image/src/Tests/ImageStylesPathAndUrlTest.php +++ b/core/modules/image/src/Tests/ImageStylesPathAndUrlTest.php @@ -79,22 +79,6 @@ function testImageStyleUrlAndPathPrivateUnclean() { } /** - * 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. */ function testImageStyleUrlExtraSlash() { @@ -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 bc924fb..2354d88 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 af36c75..00c1fde 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 2b6f478..c27f3a9 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 168e2e6..2f13720 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 0000000..af72fab --- /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 0000000..6322363 --- /dev/null +++ b/core/modules/page_cache/page_cache.module @@ -0,0 +1,50 @@ +' . t('About') . ''; + $output .= '
' . t('The Internal page cache module caches pages for anonymous users in the database.') . '
'; + $output .= '' . 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 .= '
' . 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.)') . '
'; + $output .= '' . t('On the Performance settings page, 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'))) . '
'; + $output .= 'oh hai this is html.
', '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.'); @@ -152,7 +150,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(); @@ -197,7 +194,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(); @@ -257,9 +253,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(); @@ -312,7 +307,6 @@ function testPageCacheAnonymousRolePermissions() { */ public function testPageCacheWithoutVaryCookie() { $config = $this->config('system.performance'); - $config->set('cache.page.use_internal', 1); $config->set('cache.page.max_age', 300); $config->save(); @@ -326,58 +320,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(); + 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(); - // 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('