From 3ce8ab3adc3d5eb3046530973d2c5c6edeebc15c Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Thu, 14 Jun 2018 13:01:27 +1200 Subject: [PATCH] Improve handling of deprecated apis --- docs/en/04_Changelogs/4.2.0.md | 12 +++++ src/Control/HTTP.php | 44 ++++++++++++++----- .../Middleware/HTTPCacheControlMiddleware.php | 4 ++ src/Control/RSS/RSSFeed.php | 5 ++- src/ORM/DataObject.php | 7 --- 5 files changed, 53 insertions(+), 19 deletions(-) diff --git a/docs/en/04_Changelogs/4.2.0.md b/docs/en/04_Changelogs/4.2.0.md index 807985480..d94fbc699 100644 --- a/docs/en/04_Changelogs/4.2.0.md +++ b/docs/en/04_Changelogs/4.2.0.md @@ -236,6 +236,18 @@ that the response should be considered not cacheable. See [Developer Guide: Performance > HTTP Cache Headers](/developer_guide/performance/http_cache_headers) for details on the new API. +#### Disabling legacy cache headers + +In order to forcibly disable all deprecated HTTP APIs you can set the below config: + +```yaml +SilverStripe\Control\HTTP: + ignoreDeprecatedCaching: true +``` + +This will ensure that any code paths that use the old API will not interefere with upgraded code +that interferes with the new behaviour. + #### Example Usage ##### Global opt-in for page content diff --git a/src/Control/HTTP.php b/src/Control/HTTP.php index d50a82091..1e5bcb25a 100644 --- a/src/Control/HTTP.php +++ b/src/Control/HTTP.php @@ -53,6 +53,13 @@ class HTTP */ private static $disable_http_cache = false; + /** + * Set to true to disable all deprecated HTTP Cache settings + * + * @var bool + */ + private static $ignoreDeprecatedCaching = false; + /** * Mapping of extension to mime types * @@ -424,6 +431,11 @@ class HTTP { Deprecation::notice('5.0', 'Headers are added automatically by HTTPCacheControlMiddleware instead.'); + // Skip if deprecated API is disabled + if (Config::inst()->get(HTTP::class, 'ignoreDeprecatedCaching')) { + return; + } + // Ensure a valid response object is provided if (!$response instanceof HTTPResponse) { user_error("HTTP::add_cache_headers() must be passed an HTTPResponse object", E_USER_WARNING); @@ -449,11 +461,30 @@ class HTTP /** @var HTTPRequest $request */ $request = Injector::inst()->get(HTTPRequest::class); - $config = Config::forClass(__CLASS__); + // Run middleware + ChangeDetectionMiddleware::singleton()->process($request, function (HTTPRequest $request) use ($response) { + return HTTPCacheControlMiddleware::singleton()->process($request, function (HTTPRequest $request) use ($response) { + return $response; + }); + }); + } + + /** + * Ensure that all deprecated HTTP cache settings are respected + * + * @deprecated 4.2..5.0 Use HTTPCacheControlMiddleware instead + * @param HTTPRequest $request + * @param HTTPResponse $response + */ + public static function augmentState(HTTPRequest $request, HTTPResponse $response) + { + // Skip if deprecated API is disabled + $config = Config::forClass(HTTP::class); + if ($config->get('ignoreDeprecatedCaching')) { + return; + } - // Get current cache control state $cacheControlMiddleware = HTTPCacheControlMiddleware::singleton(); - $changeDetectionMiddleware = ChangeDetectionMiddleware::singleton(); // if http caching is disabled by config, disable it - used on dev environments due to frequently changing // templates and other data. will be overridden by forced publicCache(true) or privateCache(true) calls @@ -489,13 +520,6 @@ class HTTP Deprecation::notice('5.0', 'Etag should not be set explicitly'); $response->addHeader('ETag', self::$etag); } - - // Run middleware - $changeDetectionMiddleware->process($request, function (HTTPRequest $request) use ($cacheControlMiddleware, $response) { - return $cacheControlMiddleware->process($request, function (HTTPRequest $request) use ($response) { - return $response; - }); - }); } /** diff --git a/src/Control/Middleware/HTTPCacheControlMiddleware.php b/src/Control/Middleware/HTTPCacheControlMiddleware.php index 3d7fdc01d..5038493a7 100644 --- a/src/Control/Middleware/HTTPCacheControlMiddleware.php +++ b/src/Control/Middleware/HTTPCacheControlMiddleware.php @@ -3,6 +3,7 @@ namespace SilverStripe\Control\Middleware; use InvalidArgumentException; +use SilverStripe\Control\HTTP; use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPResponse; use SilverStripe\Control\HTTPResponse_Exception; @@ -49,6 +50,9 @@ class HTTPCacheControlMiddleware implements HTTPMiddleware, Resettable // Update state based on current request and response objects $this->augmentState($request, $response); + // Update state based on deprecated HTTP settings + HTTP::augmentState($request, $response); + // Add all headers to this response object $this->applyToResponse($response); diff --git a/src/Control/RSS/RSSFeed.php b/src/Control/RSS/RSSFeed.php index 12bc4e876..804c7c756 100644 --- a/src/Control/RSS/RSSFeed.php +++ b/src/Control/RSS/RSSFeed.php @@ -2,6 +2,7 @@ namespace SilverStripe\Control\RSS; +use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware; use SilverStripe\ORM\SS_List; use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\FieldType\DBHTMLText; @@ -226,11 +227,11 @@ class RSSFeed extends ViewableData $response = Controller::curr()->getResponse(); if (is_int($this->lastModified)) { - HTTP::register_modification_timestamp($this->lastModified); + HTTPCacheControlMiddleware::singleton()->registerModificationDate($this->lastModified); $response->addHeader("Last-Modified", gmdate("D, d M Y H:i:s", $this->lastModified) . ' GMT'); } if (!empty($this->etag)) { - HTTP::register_etag($this->etag); + $response->addHeader('ETag', "\"{$this->etag}\""); } $response->addHeader("Content-Type", "application/rss+xml; charset=utf-8"); diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index 04edcb964..d66a25d2b 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -380,13 +380,6 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $this->original = $this->record; - // Keep track of the modification date of all the data sourced to make this page - // From this we create a Last-Modified HTTP header - if (isset($record['LastEdited'])) { - HTTPCacheControlMiddleware::singleton() - ->registerModificationDate($record['LastEdited']); - } - // Must be called after parent constructor if (!$isSingleton && (!isset($this->record['ID']) || !$this->record['ID'])) { $this->populateDefaults();