function PageCache::storeResponse
Same name in other branches
- 9 core/modules/page_cache/src/StackMiddleware/PageCache.php \Drupal\page_cache\StackMiddleware\PageCache::storeResponse()
- 8.9.x core/modules/page_cache/src/StackMiddleware/PageCache.php \Drupal\page_cache\StackMiddleware\PageCache::storeResponse()
- 10 core/modules/page_cache/src/StackMiddleware/PageCache.php \Drupal\page_cache\StackMiddleware\PageCache::storeResponse()
Stores a response in the page cache.
Parameters
\Symfony\Component\HttpFoundation\Request $request: A request object.
\Symfony\Component\HttpFoundation\Response $response: A response object that should be stored in the page cache.
Return value
bool TRUE if the response has been stored successfully, FALSE otherwise.
1 call to PageCache::storeResponse()
- PageCache::fetch in core/
modules/ page_cache/ src/ StackMiddleware/ PageCache.php - Fetches a response from the backend and stores it in the cache.
File
-
core/
modules/ page_cache/ src/ StackMiddleware/ PageCache.php, line 223
Class
- PageCache
- Executes the page caching before the main kernel takes over the request.
Namespace
Drupal\page_cache\StackMiddlewareCode
protected function storeResponse(Request $request, Response $response) {
// Drupal's primary cache invalidation architecture is cache tags: any
// response that varies by a configuration value or data in a content
// entity should have cache tags, to allow for instant cache invalidation
// when that data is updated. However, HTTP does not standardize how to
// encode cache tags in a response. Different CDNs implement their own
// approaches, and configurable reverse proxies (e.g., Varnish) allow for
// custom implementations. To keep Drupal's internal page cache simple, we
// only cache CacheableResponseInterface responses, since those provide a
// defined API for retrieving cache tags. For responses that do not
// implement CacheableResponseInterface, there's no easy way to distinguish
// responses that truly don't depend on any site data from responses that
// contain invalidation information customized to a particular proxy or
// CDN.
// - Drupal modules are encouraged to use CacheableResponseInterface
// responses where possible and to leave the encoding of that information
// into response headers to the corresponding proxy/CDN integration
// modules.
// - Custom applications that wish to provide internal page cache support
// for responses that do not implement CacheableResponseInterface may do
// so by replacing/extending this middleware service or adding another
// one.
if (!$response instanceof CacheableResponseInterface) {
$response->headers
->set(static::HEADER, 'UNCACHEABLE (no cacheability)');
return FALSE;
}
// Currently it is not possible to cache binary file or streamed responses:
// https://github.com/symfony/symfony/issues/9128#issuecomment-25088678.
// Therefore exclude them, even for subclasses that implement
// CacheableResponseInterface.
if ($response instanceof BinaryFileResponse || $response instanceof StreamedResponse) {
return FALSE;
}
// Allow policy rules to further restrict which responses to cache.
if ($this->responsePolicy
->check($response, $request) === ResponsePolicyInterface::DENY) {
$response->headers
->set(static::HEADER, 'UNCACHEABLE (response policy)');
return FALSE;
}
$request_time = $request->server
->get('REQUEST_TIME');
// The response passes all of the above checks, so cache it. Page cache
// entries default to Cache::PERMANENT since they will be expired via cache
// tags locally. Because of this, page cache ignores max age.
// - Get the tags from CacheableResponseInterface per the earlier comments.
// - Get the time expiration from the Expires header, rather than the
// interface, but see https://www.drupal.org/node/2352009 about possibly
// changing that.
$expire = 0;
// 403 and 404 responses can fill non-LRU cache backends and generally are
// likely to have a low cache hit rate. So do not cache them permanently.
if ($response->isClientError()) {
// Cache for an hour by default. If the 'cache_ttl_4xx' setting is
// set to 0 then do not cache the response.
$cache_ttl_4xx = Settings::get('cache_ttl_4xx', 3600);
if ($cache_ttl_4xx > 0) {
$expire = $request_time + $cache_ttl_4xx;
}
}
elseif ($expires = $response->getExpires()) {
$date = $expires->getTimestamp();
$expire = $date > $request_time ? $date : Cache::PERMANENT;
}
else {
$expire = Cache::PERMANENT;
}
if ($expire === Cache::PERMANENT || $expire > $request_time) {
$tags = $response->getCacheableMetadata()
->getCacheTags();
$this->set($request, $response, $expire, $tags);
}
return TRUE;
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.