diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index da3a277..e8dd011 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -951,6 +951,23 @@ function variable_del($name) { } /** + * Gets the page cache cid for this request. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The request for this page. + * + * @return string + * The cid for this request. + */ +function drupal_page_cache_get_cid(Request $request) { + $cid_parts = array( + $request->getUri(), + Drupal::service('content_negotiation')->getContentType($request), + ); + return sha1(implode(':', $cid_parts)); +} + +/** * Retrieves the current page from the cache. * * Note: we do not serve cached pages to authenticated users, or to anonymous @@ -958,27 +975,15 @@ function variable_del($name) { * from a form submission, the contents of a shopping cart, or other user- * specific content that should not be cached and displayed to other users. * - * @param $check_only - * (optional) Set to TRUE to only return whether a previous call found a - * cache entry. + * @param \Symfony\Component\HttpFoundation\Request $request + * The request for this page. * * @return * The cache object, if the page was found in the cache, NULL otherwise. */ -function drupal_page_get_cache($check_only = FALSE) { - global $base_root; - static $cache_hit = FALSE; - - if ($check_only) { - return $cache_hit; - } - +function drupal_page_get_cache(Request $request) { if (drupal_page_is_cacheable()) { - $cache = cache('page')->get($base_root . request_uri()); - if ($cache !== FALSE) { - $cache_hit = TRUE; - } - return $cache; + return Drupal::cache('page')->get(drupal_page_cache_get_cid($request)); } } @@ -2035,7 +2040,6 @@ function _drupal_bootstrap_page_cache() { $cache_enabled = $config->get('cache.page.use_internal'); } - // @todo this is *criminal*. but, necessary, until we fix bootstrap ordering. $request = Request::createFromGlobals(); // If there is no session cookie and cache is enabled (or forced), try // to serve a cached page. @@ -2043,7 +2047,7 @@ function _drupal_bootstrap_page_cache() { // Make sure there is a user object because its timestamp will be checked. $user = drupal_anonymous_user(); // Get the page from the cache. - $cache = drupal_page_get_cache(); + $cache = drupal_page_get_cache($request); // If there is a cached page, display it. if (is_object($cache)) { $response = new Response(); diff --git a/core/includes/common.inc b/core/includes/common.inc index 842136e..26181c0 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -3165,11 +3165,9 @@ function _drupal_bootstrap_full($skip = FALSE) { * @see drupal_page_header() */ function drupal_page_set_cache(Response $response, Request $request) { - global $base_root; - if (drupal_page_is_cacheable()) { $cache = (object) array( - 'cid' => $base_root . $request->getRequestUri(), + 'cid' => drupal_page_cache_get_cid($request), 'data' => array( 'path' => $request->attributes->get('_system_path'), 'body' => $response->getContent(), 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 ca2d7b3..3bbc729 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/PageCacheTest.php @@ -7,6 +7,7 @@ namespace Drupal\system\Tests\Bootstrap; +use Symfony\Component\Routing\RequestContext; use Drupal\simpletest\WebTestBase; /** @@ -41,6 +42,33 @@ function setUp() { } /** + * Tests support for different cache items with different Accept headers. + */ + function testAcceptHeaderRequests() { + $config = config('system.performance'); + $config->set('cache.page.use_internal', 1); + $config->set('cache.page.max_age', 300); + $config->save(); + + $url_generator = \Drupal::urlGenerator(); + $url_generator->setContext(new RequestContext()); + $accept_header_cache_uri = $url_generator->getPathFromRoute('system_test.page_cache_accept_header'); + $json_accept_header = array('Accept: application/json'); + + $this->drupalGet($accept_header_cache_uri); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'HTML page was not yet cached.'); + $this->drupalGet($accept_header_cache_uri); + $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'HTML page was cached.'); + $this->assertRaw('

oh hai this is html.

', 'The correct HTML response was returned.'); + + $this->drupalGet($accept_header_cache_uri, 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->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.'); + } + + /** * Tests support of requests with If-Modified-Since and If-None-Match headers. */ function testConditionalRequests() { diff --git a/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/PageCacheAcceptHeaderController.php b/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/PageCacheAcceptHeaderController.php new file mode 100644 index 0000000..cc3b231 --- /dev/null +++ b/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/PageCacheAcceptHeaderController.php @@ -0,0 +1,35 @@ +headers->get('Accept') == 'application/json') { + return new JsonResponse(array('content' => 'oh hai this is json')); + } + else { + return "

oh hai this is html.

"; + } + } +} + diff --git a/core/modules/system/tests/modules/system_test/system_test.routing.yml b/core/modules/system/tests/modules/system_test/system_test.routing.yml new file mode 100644 index 0000000..1be2566 --- /dev/null +++ b/core/modules/system/tests/modules/system_test/system_test.routing.yml @@ -0,0 +1,7 @@ +system_test.page_cache_accept_header: + pattern: '/system-test/page-cache/accept-header' + defaults: + _controller: '\Drupal\system_test\Controller\PageCacheAcceptHeaderController::content' + requirements: + _access: 'TRUE' + diff --git a/core/modules/toolbar/toolbar.module b/core/modules/toolbar/toolbar.module index dbbca14..f058445 100644 --- a/core/modules/toolbar/toolbar.module +++ b/core/modules/toolbar/toolbar.module @@ -125,10 +125,10 @@ function _toolbar_initialize_page_cache() { // If we have a cache, serve it. // @see _drupal_bootstrap_page_cache() - $cache = drupal_page_get_cache(); + $request = \Drupal::request(); + $cache = drupal_page_get_cache($request); if (is_object($cache)) { $response = new Response(); - $request = \Drupal::request(); $response->headers->set('X-Drupal-Cache', 'HIT'); date_default_timezone_set(drupal_get_user_timezone());