diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index e173a95..148a6c7 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -1021,38 +1021,6 @@ function variable_del($name) { } /** - * Retrieves the current page from the cache. - * - * Note: we do not serve cached pages to authenticated users, or to anonymous - * users when $_SESSION is non-empty. $_SESSION may contain status messages - * 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. - * - * @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; - } - - if (drupal_page_is_cacheable()) { - $cache = cache('page')->get($base_root . request_uri()); - if ($cache !== FALSE) { - $cache_hit = TRUE; - } - return $cache; - } -} - -/** * Determines the cacheability of the current page. * * @param $allow_caching @@ -1066,7 +1034,7 @@ function drupal_page_is_cacheable($allow_caching = NULL) { if (isset($allow_caching)) { $allow_caching_static = $allow_caching; } - + return $allow_caching_static && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD') && !drupal_is_cli(); } @@ -1275,111 +1243,6 @@ function drupal_page_header() { } /** - * Sets HTTP headers in preparation for a cached page response. - * - * The headers allow as much as possible in proxies and browsers without any - * particular knowledge about the pages. Modules can override these headers - * using drupal_add_http_header(). - * - * If the request is conditional (using If-Modified-Since and If-None-Match), - * and the conditions match those currently in the cache, a 304 Not Modified - * response is sent. - */ -function drupal_serve_page_from_cache(stdClass $cache) { - $config = config('system.performance'); - - // Negotiate whether to use compression. - $page_compression = $config->get('page_compression') && extension_loaded('zlib'); - $return_compressed = $page_compression && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE; - - // Get headers set in hook_boot(). Keys are lower-case. - $hook_boot_headers = drupal_get_http_header(); - - // Headers generated in this function, that may be replaced or unset using - // drupal_add_http_headers(). Keys are mixed-case. - $default_headers = array(); - - foreach ($cache->data['headers'] as $name => $value) { - // In the case of a 304 response, certain headers must be sent, and the - // remaining may not (see RFC 2616, section 10.3.5). Do not override - // headers set in hook_boot(). - $name_lower = strtolower($name); - if (in_array($name_lower, array('content-location', 'expires', 'cache-control', 'vary')) && !isset($hook_boot_headers[$name_lower])) { - drupal_add_http_header($name, $value); - unset($cache->data['headers'][$name]); - } - } - - // If the client sent a session cookie, a cached copy will only be served - // to that one particular client due to Vary: Cookie. Thus, do not set - // max-age > 0, allowing the page to be cached by external proxies, when a - // session cookie is present unless the Vary header has been replaced or - // unset in hook_boot(). - $max_age = !isset($_COOKIE[session_name()]) || isset($hook_boot_headers['vary']) ? $config->get('page_cache_maximum_age') : 0; - $default_headers['Cache-Control'] = 'public, max-age=' . $max_age; - - // Entity tag should change if the output changes. - $etag = '"' . $cache->created . '-' . intval($return_compressed) . '"'; - header('Etag: ' . $etag); - - // See if the client has provided the required HTTP headers. - $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE; - $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE; - - if ($if_modified_since && $if_none_match - && $if_none_match == $etag // etag must match - && $if_modified_since == $cache->created) { // if-modified-since must match - header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified'); - drupal_send_headers($default_headers); - return; - } - - // Send the remaining headers. - foreach ($cache->data['headers'] as $name => $value) { - drupal_add_http_header($name, $value); - } - - $default_headers['Last-Modified'] = gmdate(DATE_RFC1123, $cache->created); - - // HTTP/1.0 proxies does not support the Vary header, so prevent any caching - // by sending an Expires date in the past. HTTP/1.1 clients ignores the - // Expires header if a Cache-Control: max-age= directive is specified (see RFC - // 2616, section 14.9.3). - $default_headers['Expires'] = 'Sun, 19 Nov 1978 05:00:00 GMT'; - - drupal_send_headers($default_headers); - - // Allow HTTP proxies to cache pages for anonymous users without a session - // cookie. The Vary header is used to indicates the set of request-header - // fields that fully determines whether a cache is permitted to use the - // response to reply to a subsequent request for a given URL without - // revalidation. If a Vary header has been set in hook_boot(), it is assumed - // that the module knows how to cache the page. - if (!isset($hook_boot_headers['vary']) && !variable_get('omit_vary_cookie')) { - header('Vary: Cookie'); - } - - if ($page_compression) { - header('Vary: Accept-Encoding', FALSE); - // If page_compression is enabled, the cache contains gzipped data. - if ($return_compressed) { - // $cache->data['body'] is already gzip'ed, so make sure - // zlib.output_compression does not compress it once more. - ini_set('zlib.output_compression', '0'); - header('Content-Encoding: gzip'); - } - else { - // The client does not support compression, so unzip the data in the - // cache. Strip the gzip header and run uncompress. - $cache->data['body'] = gzinflate(substr(substr($cache->data['body'], 10), 0, -8)); - } - } - - // Print the page. - print $cache->data['body']; -} - -/** * Defines the critical hooks that force modules to always be loaded. */ function bootstrap_hooks() { @@ -2274,35 +2137,8 @@ function _drupal_bootstrap_page_cache() { // If there is no session cookie and cache is enabled (or forced), try // to serve a cached page. if (!isset($_COOKIE[session_name()]) && $cache_enabled) { - // Make sure there is a user object because its timestamp will be - // checked, hook_boot might check for anonymous user etc. - $user = drupal_anonymous_user(); - // Get the page from the cache. - $cache = drupal_page_get_cache(); - // If there is a cached page, display it. - if (is_object($cache)) { - header('X-Drupal-Cache: HIT'); - // Restore the metadata cached with the page. - _current_path($cache->data['path']); - drupal_set_title($cache->data['title'], PASS_THROUGH); - date_default_timezone_set(drupal_get_user_timezone()); - // If the skipping of the bootstrap hooks is not enforced, call - // hook_boot. - if (variable_get('page_cache_invoke_hooks', TRUE)) { - bootstrap_invoke_all('boot'); - } - drupal_serve_page_from_cache($cache); - // If the skipping of the bootstrap hooks is not enforced, call - // hook_exit. - if (variable_get('page_cache_invoke_hooks', TRUE)) { - bootstrap_invoke_all('exit'); - } - // We are done. - exit; - } - else { - header('X-Drupal-Cache: MISS'); - } + // The cache was first served here. This is now handled by the + // kernel after the bootstrap has finished. } } diff --git a/core/includes/common.inc b/core/includes/common.inc index 17e1363..d9a48da 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -4952,62 +4952,6 @@ function _drupal_bootstrap_full($skip = FALSE) { } /** - * Stores the current page in the cache. - * - * If page_compression is enabled, a gzipped version of the page is stored in - * the cache to avoid compressing the output on each request. The cache entry - * is unzipped in the relatively rare event that the page is requested by a - * client without gzip support. - * - * Page compression requires the PHP zlib extension - * (http://php.net/manual/ref.zlib.php). - * - * @param $body - * The response body. - * @return - * The cached object or NULL if the page cache was not set. - * - * @see drupal_page_header() - */ -function drupal_page_set_cache($body) { - global $base_root; - - if (drupal_page_is_cacheable()) { - $cache = (object) array( - 'cid' => $base_root . request_uri(), - 'data' => array( - 'path' => current_path(), - 'body' => $body, - 'title' => drupal_get_title(), - 'headers' => array(), - ), - 'tags' => array('content' => TRUE), - 'expire' => CACHE_PERMANENT, - 'created' => REQUEST_TIME, - ); - - // Restore preferred header names based on the lower-case names returned - // by drupal_get_http_header(). - $header_names = _drupal_set_preferred_header_name(); - foreach (drupal_get_http_header() as $name_lower => $value) { - $cache->data['headers'][$header_names[$name_lower]] = $value; - if ($name_lower == 'expires') { - // Use the actual timestamp from an Expires header if available. - $cache->expire = strtotime($value); - } - } - - if ($cache->data['body']) { - if (config('system.performance')->get('page_compression') && extension_loaded('zlib')) { - $cache->data['body'] = gzencode($cache->data['body'], 9, FORCE_GZIP); - } - cache('page')->set($cache->cid, $cache->data, $cache->expire, $cache->tags); - } - return $cache; - } -} - -/** * Executes a cron run when called. * * Do not call this function from a test. Use $this->cronRun() instead. diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php index 8044a5c..61ed5d0 100644 --- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php @@ -71,15 +71,30 @@ class FinishResponseSubscriber implements EventSubscriberInterface { // use partial page caching more extensively. // Commit the user session, if needed. drupal_session_commit(); - if (config('system.performance')->get('cache') && ($cache = drupal_page_set_cache($response->getContent()))) { - drupal_serve_page_from_cache($cache); - // drupal_serve_page_from_cache() already printed the response. - $response->setContent(''); - $response->headers->remove('cache-control'); + + // @todo, is this the proper location to add these headers? + if (config('system.performance')->get('cache') && drupal_page_is_cacheable()) { + $vary = array('Accept-Encoding'); + if (!variable_get('omit_vary_cookie')) { + $vary[] = 'Cookie'; + } + $response->setVary($vary); + + $response->setPublic(); + $max_age = config('system.performance')->get('page_cache_maximum_age'); + if (!$max_age) { + // @todo, Define a Max Age to use for HttpCache which it expects + // to see whether or not TTL has expired. + $max_age = 3600; + } + $response->setMaxAge($max_age); } else { $response->headers->set('Expires', 'Sun, 19 Nov 1978 05:00:00 GMT'); - $response->headers->set('Cache-Control', 'no-cache, must-revalidate, post-check=0, pre-check=0'); + $response->headers->addCacheControlDirective('no-cache'); + $response->headers->addCacheControlDirective('must-revalidate'); + $response->headers->addCacheControlDirective('post-check', 0); + $response->headers->addCacheControlDirective('pre-check', 0); } } diff --git a/index.php b/index.php index 38177ab..1dff479 100644 --- a/index.php +++ b/index.php @@ -13,7 +13,9 @@ use Drupal\Core\DrupalKernel; use Symfony\Component\HttpFoundation\Request; - +use Drupal\Core\HttpCache; +use Symfony\Component\HttpKernel\HttpCache\Store; + /** * Root directory of Drupal installation. */ @@ -30,6 +32,11 @@ drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE); // @todo Figure out how best to handle the Kernel constructor parameters. $kernel = new DrupalKernel('prod', FALSE); +// Are we using page caching, if so override the Kernel. +if (config('system.performance')->get('cache') && drupal_page_is_cacheable()) { + $kernel = new HttpCache($kernel, new Store("/tmp/meuk")); +} + // Create a request object from the HTTPFoundation. $request = Request::createFromGlobals(); $response = $kernel->handle($request)->prepare($request)->send();