diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php index 3db181a..a8826e3 100644 --- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php @@ -3,6 +3,7 @@ namespace Drupal\Core\EventSubscriber; use Drupal\Component\Datetime\DateTimePlus; +use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheableResponseInterface; use Drupal\Core\Cache\Context\CacheContextsManager; use Drupal\Core\Config\ConfigFactoryInterface; @@ -227,7 +228,16 @@ protected function setResponseCacheable(Response $response, Request $request) { $this->setExpiresNoCache($response); } - $max_age = $this->config->get('cache.page.max_age'); + if ($this->config->get('cache.page.max_age_provider') == 'dynamic') { + $max_age = $response->getCacheableMetadata()->getCacheMaxAge(); + if ($max_age === Cache::PERMANENT) { + // Cache for 30 days. + $max_age = 30 * 24 * 60 * 60; + } + } + else { + $max_age = $this->config->get('cache.page.max_age'); + } $response->headers->set('Cache-Control', 'public, max-age=' . $max_age); // In order to support HTTP cache-revalidation, ensure that there is a diff --git a/core/modules/node/config/optional/views.view.glossary.yml b/core/modules/node/config/optional/views.view.glossary.yml index ca17caa..04e4bd8 100644 --- a/core/modules/node/config/optional/views.view.glossary.yml +++ b/core/modules/node/config/optional/views.view.glossary.yml @@ -355,7 +355,7 @@ display: - url.query_args - 'user.node_grants:view' - user.permissions - max-age: 0 + max-age: -1 tags: { } attachment_1: id: attachment_1 diff --git a/core/modules/page_cache/src/StackMiddleware/PageCache.php b/core/modules/page_cache/src/StackMiddleware/PageCache.php index 3a031db..74514ce 100644 --- a/core/modules/page_cache/src/StackMiddleware/PageCache.php +++ b/core/modules/page_cache/src/StackMiddleware/PageCache.php @@ -284,8 +284,23 @@ protected function storeResponse(Request $request, Response $response) { } } else { - $date = $response->getExpires()->getTimestamp(); - $expire = ($date > $request_time) ? $date : Cache::PERMANENT; + $expires_header = $response->getExpires()->getTimestamp(); + // First check the expires header, respect that if set to a future date. + if ($expires_header > $request_time) { + $expire = $expires_header; + } + elseif ($response instanceof CacheableResponseInterface) { + $max_age = $response->getCacheableMetadata()->getCacheMaxAge(); + // Fall back to checking the max age, which can either be unlimited, in + // which case it should be used as-is, a positive value for a certain + // expiration date or 0 if the page is not cacheable. 0 means that + // expire is the request time, which means it will not be cached below. + $expire = $max_age > Cache::PERMANENT ? $request_time + $max_age : Cache::PERMANENT; + } + else { + $date = $response->getExpires()->getTimestamp(); + $expire = ($date > $request_time) ? $date : Cache::PERMANENT; + } } if ($expire === Cache::PERMANENT || $expire > $request_time) { diff --git a/core/modules/system/config/install/system.performance.yml b/core/modules/system/config/install/system.performance.yml index 11392bd..b71e128 100644 --- a/core/modules/system/config/install/system.performance.yml +++ b/core/modules/system/config/install/system.performance.yml @@ -1,6 +1,7 @@ cache: page: max_age: 0 + max_age_provider: fixed css: preprocess: true gzip: true diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml index c23ed7e..11372fe 100644 --- a/core/modules/system/config/schema/system.schema.yml +++ b/core/modules/system/config/schema/system.schema.yml @@ -149,6 +149,9 @@ system.performance: max_age: type: integer label: 'Max age' + max_age_provider: + type: string + label: 'Max age provider' 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 d9e0917..e7240a8 100644 --- a/core/modules/system/src/Form/PerformanceForm.php +++ b/core/modules/system/src/Form/PerformanceForm.php @@ -118,6 +118,16 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#open' => TRUE, '#description' => $this->t('Note: Drupal provides an internal page cache module that is recommended for small to medium-sized websites.'), ); + $form['caching']['page_cache_maximum_age_provider'] = array( + '#type' => 'select', + '#title' => t('Cache period'), + '#options' => array( + 'fixed' => t('Fixed'), + 'dynamic' => t('Dynamic'), + ), + '#default_value' => $config->get('cache.page.max_age_provider') ?: 'fixed', + '#description' => $this->t('Select how to set max age of page cache. Allowed values are fixed: Fixed number of time (from period field below). Dynamic: Allows page components to decide.'), + ); // Identical options to the ones for block caching. // @see \Drupal\Core\Block\BlockBase::buildConfigurationForm() $period = array(0, 60, 180, 300, 600, 900, 1800, 2700, 3600, 10800, 21600, 32400, 43200, 86400); @@ -129,6 +139,11 @@ public function buildForm(array $form, FormStateInterface $form_state) { '#default_value' => $config->get('cache.page.max_age'), '#options' => $period, '#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.'), + '#states' => array( + 'visible' => array( + 'select[name="page_cache_maximum_age_provider"]' => array('value' => 'fixed'), + ), + ), ); $directory = 'public://'; @@ -174,6 +189,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { $this->renderCache->deleteAll(); $this->config('system.performance') + ->set('cache.page.max_age_provider', $form_state->getValue('page_cache_maximum_age_provider')) ->set('cache.page.max_age', $form_state->getValue('page_cache_maximum_age')) ->set('css.preprocess', $form_state->getValue('preprocess_css')) ->set('js.preprocess', $form_state->getValue('preprocess_js')) diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 6dc2663..116122a 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -1794,3 +1794,12 @@ function system_update_8203() { ->set('logging', 1) ->save(TRUE); } + +/** + * Set default page cache max-age provider to 'fixed' + */ +function system_update_8204() { + \Drupal::configFactory()->getEditable('system.performance') + ->set('cache.page.max_age_provider', 'fixed') + ->save(); +} diff --git a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php index 22e9ba7..8b2d1fe 100644 --- a/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php +++ b/core/modules/system/tests/src/Kernel/Migrate/d7/MigrateSystemConfigurationTest.php @@ -74,6 +74,7 @@ class MigrateSystemConfigurationTest extends MigrateDrupal7TestBase { 'cache' => [ 'page' => [ 'max_age' => 300, + 'max_age_provider' => 'fixed', ], ], 'css' => [ diff --git a/core/modules/views/src/Plugin/views/style/Table.php b/core/modules/views/src/Plugin/views/style/Table.php index c49f6e9..c4e94fc 100644 --- a/core/modules/views/src/Plugin/views/style/Table.php +++ b/core/modules/views/src/Plugin/views/style/Table.php @@ -3,6 +3,7 @@ namespace Drupal\views\Plugin\views\style; use Drupal\Component\Utility\Html; +use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\wizard\WizardInterface; @@ -425,7 +426,7 @@ public function wizardSubmit(&$form, FormStateInterface $form_state, WizardInter * {@inheritdoc} */ public function getCacheMaxAge() { - return 0; + return Cache::PERMANENT; } /**