diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index c2bb1b4..ef5c14c 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -900,26 +900,23 @@ function drupal_serve_page_from_cache(Response $response, Request $request) { } // Perform HTTP revalidation. + // @todo Use Response::isNotModified() as per https://drupal.org/node/2259489 $last_modified = $response->getLastModified(); if ($last_modified) { // See if the client has provided the required HTTP headers. $if_modified_since = $request->server->has('HTTP_IF_MODIFIED_SINCE') ? strtotime($request->server->get('HTTP_IF_MODIFIED_SINCE')) : FALSE; $if_none_match = $request->server->has('HTTP_IF_NONE_MATCH') ? stripslashes($request->server->get('HTTP_IF_NONE_MATCH')) : FALSE; - $last_modified_match = $if_modified_since === $last_modified->getTimestamp(); - $etag_match = $if_none_match == $response->getEtag(); - - if (($if_modified_since && $if_none_match && $last_modified_match && $etag_match) // If both revalidation request headers are present, apply both. - || ($if_modified_since && !$if_none_match && $last_modified_match) // Only Last-Modified must match. - || ($if_none_match && !$if_modified_since && $etag_match) // Only ETag must match. - ) { + if ($if_modified_since && $if_none_match + && $if_none_match == $response->getEtag() // etag must match + && $if_modified_since == $last_modified->getTimestamp()) { // if-modified-since must match $response->setStatusCode(304); $response->setContent(NULL); // In the case of a 304 response, certain headers must be sent, and the // remaining may not (see RFC 2616, section 10.3.5). foreach (array_keys($response->headers->all()) as $name) { - if (!in_array($name, array('etag', 'content-location', 'expires', 'cache-control', 'vary'))) { + if (!in_array($name, array('content-location', 'expires', 'cache-control', 'vary'))) { $response->headers->remove($name); } } diff --git a/core/includes/common.inc b/core/includes/common.inc index 963f4dd..1f8e387 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -2830,13 +2830,8 @@ function drupal_page_set_cache(Response $response, Request $request) { } // Use the actual timestamp from an Expires header, if available. - $expire = Cache::PERMANENT; - if ($response->headers->has('Expires')) { - $timestamp = $response->getExpires()->getTimestamp(); - if ($timestamp > REQUEST_TIME) { - $expire = $timestamp; - } - } + $date = $response->getExpires(); + $expire = ($date > (new DateTime())) ? $date->getTimestamp() : Cache::PERMANENT; $cid = drupal_page_cache_get_cid($request); $tags = HtmlViewSubscriber::convertHeaderToCacheTags($response->headers->get('X-Drupal-Cache-Tags')); diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php index a96b478..616f3fd 100644 --- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php @@ -15,8 +15,8 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; -use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\KernelEvents; +use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -85,8 +85,10 @@ public function onRespond(FilterResponseEvent $event) { // Add headers necessary to specify whether the response should be cached by // proxies and/or the browser. - if ($is_cacheable && $this->config->get('cache.page.max_age') > 0 && !$this->isCacheControlCustomized($response)) { - $this->setResponseCacheable($response, $request); + if ($is_cacheable && $this->config->get('cache.page.max_age') > 0) { + if (!$this->isCacheControlCustomized($response)) { + $this->setResponseCacheable($response, $request); + } } else { $this->setResponseNotCacheable($response, $request); @@ -111,7 +113,7 @@ public function onRespond(FilterResponseEvent $event) { * explicitly. * * When neither Cache-Control nor any of the ETag, Last-Modified, Expires - * headers are set on the response, ::get('cache-control') returns the value + * headers are set on the response, ::get('Cache-Control') returns the value * 'no-cache'. If any of ETag, Last-Modified or Expires are set but not * Cache-Control, then 'private, must-revalidate' (in exactly this order) is * returned. @@ -124,7 +126,7 @@ public function onRespond(FilterResponseEvent $event) { * TRUE when Cache-Control header was set explicitely on the given response. */ protected function isCacheControlCustomized(Response $response) { - $cache_control = $response->headers->get('cache-control'); + $cache_control = $response->headers->get('Cache-Control'); return $cache_control != 'no-cache' && $cache_control != 'private, must-revalidate'; } @@ -203,7 +205,7 @@ protected function setResponseCacheable(Response $response, Request $request) { * A response object. */ protected function setCacheControlNoCache(Response $response) { - $response->headers->set('cache-control', 'no-cache, must-revalidate, post-check=0, pre-check=0'); + $response->headers->set('Cache-Control', 'no-cache, must-revalidate, post-check=0, pre-check=0'); } /** diff --git a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php index 150e1db..fdf16b9 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php @@ -128,40 +128,21 @@ function testConditionalRequests() { $this->drupalGet('', array(), array('If-Modified-Since: ' . $last_modified, 'If-None-Match: ' . $etag)); $this->assertResponse(304, 'Conditional request returned 304 Not Modified.'); - $this->assertTrue(strlen($this->drupalGetContent()) == 0, 'No HTML returned.'); $this->drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DATE_RFC822, strtotime($last_modified)), 'If-None-Match: ' . $etag)); $this->assertResponse(304, 'Conditional request with obsolete If-Modified-Since date returned 304 Not Modified.'); - $this->assertTrue(strlen($this->drupalGetContent()) == 0, 'No HTML returned.'); $this->drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DATE_RFC850, strtotime($last_modified)), 'If-None-Match: ' . $etag)); $this->assertResponse(304, 'Conditional request with obsolete If-Modified-Since date returned 304 Not Modified.'); - $this->assertTrue(strlen($this->drupalGetContent()) == 0, 'No HTML returned.'); $this->drupalGet('', array(), array('If-Modified-Since: ' . $last_modified)); - $this->assertResponse(304, 'Conditional request with If-Modified-Since but without If-None-Match returned 304 Not Modified.'); - $this->assertTrue(strlen($this->drupalGetContent()) == 0, 'No HTML returned.'); - - $this->drupalGet('', array(), array('If-None-Match: ' . $etag)); - $this->assertResponse(304, 'Conditional request with If-None-Match but without If-Modified-Since returned 304 Not Modified.'); - $this->assertTrue(strlen($this->drupalGetContent()) == 0, 'No HTML returned.'); - - $this->drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DATE_RFC1123, strtotime($last_modified) + 1), 'If-None-Match: ' . $etag)); - $this->assertResponse(200, 'Conditional request with an If-Modified-Since date newer than Last-Modified returned 200 OK.'); - // Verify the page is not printed twice when the cache is warm. - $this->assertNoPattern('#assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - - $this->drupalGet('', array(), array('If-Modified-Since: ' . $last_modified, 'If-None-Match: ' . $etag . '-is-invalid')); - $this->assertResponse(200, 'Conditional request with an invalid If-None-Match ETag value returned 200 OK.'); // Verify the page is not printed twice when the cache is warm. $this->assertNoPattern('#assertResponse(200, 'Conditional request without If-None-Match returned 200 OK.'); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); - $this->drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DATE_RFC1123, strtotime($last_modified) + 1), 'If-None-Match: ' . $etag . '-is-invalid')); - $this->assertResponse(200, 'Conditional request with an If-Modified-Since date nwer than Last-Modified and an invalid If-None-Match ETag value returned 200 OK.'); - // Verify the page is not printed twice when the cache is warm. - $this->assertNoPattern('#drupalGet('', array(), array('If-Modified-Since: ' . gmdate(DATE_RFC1123, strtotime($last_modified) + 1), 'If-None-Match: ' . $etag)); + $this->assertResponse(200, 'Conditional request with new a If-Modified-Since date newer than Last-Modified returned 200 OK.'); $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.'); $user = $this->drupalCreateUser();