Update Composer, update everything

This commit is contained in:
Oliver Davies 2018-11-23 12:29:20 +00:00
parent ea3e94409f
commit dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions

View file

@ -23,7 +23,7 @@ function page_cache_help($route_name, RouteMatchInterface $route_match) {
$output .= '<dd>' . t('Pages are usually identical for all anonymous users, while they can be personalized for each authenticated user. This is why entire pages can be cached for anonymous users, whereas they will have to be rebuilt for every authenticated user.') . '</dd>';
$output .= '<dd>' . t('To speed up your site for authenticated users, see the <a href=":dynamic_page_cache-help">Dynamic Page Cache module</a>.', [':dynamic_page_cache-help' => (\Drupal::moduleHandler()->moduleExists('dynamic_page_cache')) ? Url::fromRoute('help.page', ['name' => 'dynamic_page_cache'])->toString() : '#']) . '</p>';
$output .= '<dt>' . t('Configuring the internal page cache') . '</dt>';
$output .= '<dd>' . t('On the <a href=":cache-settings">Performance page</a>, you can configure how long browsers and proxies may cache pages; that setting is also respected by the Internal Page Cache module. There is no other configuration.', [':cache-settings' => \Drupal::url('system.performance_settings')]) . '</dd>';
$output .= '<dd>' . t('On the <a href=":cache-settings">Performance page</a>, you can configure how long browsers and proxies may cache pages based on the Cache-Control header; this setting is ignored by the Internal Page Cache module, which caches pages permanently until invalidation, unless they carry an Expires header. There is no other configuration.', [':cache-settings' => \Drupal::url('system.performance_settings')]) . '</dd>';
$output .= '</dl>';
return $output;

View file

@ -1,6 +1,13 @@
services:
http_middleware.page_cache:
class: Drupal\page_cache\StackMiddleware\PageCache
arguments: ['@cache.render', '@page_cache_request_policy', '@page_cache_response_policy']
arguments: ['@cache.page', '@page_cache_request_policy', '@page_cache_response_policy']
tags:
- { name: http_middleware, priority: 200, responder: true }
cache.page:
class: Drupal\Core\Cache\CacheBackendInterface
tags:
- { name: cache.bin }
factory: cache_factory:get
arguments: [page]

View file

@ -29,7 +29,7 @@ class PageCache implements HttpKernelInterface {
/**
* The cache bin.
*
* @var \Drupal\Core\Cache\CacheBackendInterface.
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
@ -133,23 +133,6 @@ class PageCache implements HttpKernelInterface {
$response->setPrivate();
}
// Negotiate whether to use compression.
if (extension_loaded('zlib') && $response->headers->get('Content-Encoding') === 'gzip') {
if (strpos($request->headers->get('Accept-Encoding'), 'gzip') !== FALSE) {
// The response content is already gzip'ed, so make sure
// zlib.output_compression does not compress it once more.
ini_set('zlib.output_compression', '0');
}
else {
// The client does not support compression. Decompress the content and
// remove the Content-Encoding header.
$content = $response->getContent();
$content = gzinflate(substr(substr($content, 10), 0, -8));
$response->setContent($content);
$response->headers->remove('Content-Encoding');
}
}
// Perform HTTP revalidation.
// @todo Use Response::isNotModified() as
// per https://www.drupal.org/node/2259489.
@ -160,8 +143,10 @@ class PageCache implements HttpKernelInterface {
$if_none_match = $request->server->has('HTTP_IF_NONE_MATCH') ? stripslashes($request->server->get('HTTP_IF_NONE_MATCH')) : FALSE;
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
// etag must match.
&& $if_none_match == $response->getEtag()
// if-modified-since must match.
&& $if_modified_since == $last_modified->getTimestamp()) {
$response->setStatusCode(304);
$response->setContent(NULL);
@ -181,14 +166,6 @@ class PageCache implements HttpKernelInterface {
/**
* Fetches a response from the backend and stores it 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).
*
* @see drupal_page_header()
*
* @param \Symfony\Component\HttpFoundation\Request $request
@ -283,10 +260,15 @@ class PageCache implements HttpKernelInterface {
$expire = $request_time + $cache_ttl_4xx;
}
}
else {
$date = $response->getExpires()->getTimestamp();
// The getExpires method could return NULL if Expires header is not set, so
// the returned value needs to be checked before calling getTimestamp.
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();

View file

@ -5,6 +5,11 @@ namespace Drupal\page_cache_form_test\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* A form to test page cache.
*
* @internal
*/
class TestForm extends FormBase {
/**
@ -25,6 +30,6 @@ class TestForm extends FormBase {
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) { }
public function submitForm(array &$form, FormStateInterface $form_state) {}
}

View file

@ -1,22 +1,22 @@
<?php
namespace Drupal\page_cache\Tests;
namespace Drupal\Tests\page_cache\Functional;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\Core\Language\LanguageInterface;
use Drupal\simpletest\WebTestBase;
use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
use Drupal\node\NodeInterface;
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
use Drupal\Tests\BrowserTestBase;
/**
* Enables the page cache and tests its cache tags in various scenarios.
*
* @group Cache
* @see \Drupal\page_cache\Tests\PageCacheTest
* @see \Drupal\Tests\page_cache\Functional\PageCacheTest
* @see \Drupal\node\Tests\NodePageCacheTest
* @see \Drupal\menu_ui\Tests\MenuTest::testMenuBlockPageCacheTags()
*/
class PageCacheTagsIntegrationTest extends WebTestBase {
class PageCacheTagsIntegrationTest extends BrowserTestBase {
use AssertPageCacheContextsAndTagsTrait;
@ -76,6 +76,9 @@ class PageCacheTagsIntegrationTest extends WebTestBase {
// condition.
'url.path',
'url.query_args:' . MainContentViewSubscriber::WRAPPER_FORMAT,
// These two cache contexts are added by BigPipe.
'cookies:big_pipe_nojs',
'session.exists',
];
// Full node page 1.
@ -83,6 +86,7 @@ class PageCacheTagsIntegrationTest extends WebTestBase {
'http_response',
'rendered',
'block_view',
'local_task',
'config:block_list',
'config:block.block.bartik_branding',
'config:block.block.bartik_breadcrumbs',
@ -124,6 +128,7 @@ class PageCacheTagsIntegrationTest extends WebTestBase {
'http_response',
'rendered',
'block_view',
'local_task',
'config:block_list',
'config:block.block.bartik_branding',
'config:block.block.bartik_breadcrumbs',

View file

@ -1,13 +1,14 @@
<?php
namespace Drupal\page_cache\Tests;
namespace Drupal\Tests\page_cache\Functional;
use Drupal\Component\Datetime\DateTimePlus;
use Drupal\Core\Site\Settings;
use Drupal\Core\Url;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\simpletest\WebTestBase;
use Drupal\Core\Cache\Cache;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\system\Functional\Cache\AssertPageCacheContextsAndTagsTrait;
use Drupal\user\RoleInterface;
/**
@ -15,7 +16,9 @@ use Drupal\user\RoleInterface;
*
* @group page_cache
*/
class PageCacheTest extends WebTestBase {
class PageCacheTest extends BrowserTestBase {
use AssertPageCacheContextsAndTagsTrait;
protected $dumpHeaders = TRUE;
@ -59,7 +62,7 @@ class PageCacheTest extends WebTestBase {
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
$cid_parts = [\Drupal::url('system_test.cache_tags_page', [], ['absolute' => TRUE]), 'html'];
$cid = implode(':', $cid_parts);
$cache_entry = \Drupal::cache('render')->get($cid);
$cache_entry = \Drupal::cache('page')->get($cid);
sort($cache_entry->tags);
$expected_tags = [
'config:user.role.anonymous',
@ -79,7 +82,10 @@ class PageCacheTest extends WebTestBase {
* Test that the page cache doesn't depend on cacheability headers.
*/
public function testPageCacheTagsIndependentFromCacheabilityHeaders() {
$this->setHttpResponseDebugCacheabilityHeaders(FALSE);
// Disable the cacheability headers.
$this->setContainerParameter('http.response.debug_cacheability_headers', FALSE);
$this->rebuildContainer();
$this->resetAll();
$path = 'system-test/cache_tags_page';
$tags = ['system_test_cache_tags_page'];
@ -91,7 +97,7 @@ class PageCacheTest extends WebTestBase {
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
$cid_parts = [\Drupal::url('system_test.cache_tags_page', [], ['absolute' => TRUE]), 'html'];
$cid = implode(':', $cid_parts);
$cache_entry = \Drupal::cache('render')->get($cid);
$cache_entry = \Drupal::cache('page')->get($cid);
sort($cache_entry->tags);
$expected_tags = [
'config:user.role.anonymous',
@ -156,7 +162,7 @@ class PageCacheTest extends WebTestBase {
// Clear the page cache. After that request a HAL request, followed by an
// ordinary HTML one.
\Drupal::cache('render')->deleteAll();
\Drupal::cache('page')->deleteAll();
$this->drupalGet($node_url_with_hal_json_format);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
$this->assertEqual($this->drupalGetHeader('Content-Type'), 'application/hal+json');
@ -185,33 +191,42 @@ class PageCacheTest extends WebTestBase {
// Verify the page is not printed twice when the cache is cold.
$this->assertNoPattern('#<html.*<html#');
$this->drupalHead('');
$this->drupalGet('');
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.');
$etag = $this->drupalGetHeader('ETag');
$last_modified = $this->drupalGetHeader('Last-Modified');
$this->drupalGet('', [], ['If-Modified-Since: ' . $last_modified, 'If-None-Match: ' . $etag]);
$this->drupalGet('', [], ['If-Modified-Since' => $last_modified, 'If-None-Match' => $etag]);
$this->assertResponse(304, 'Conditional request returned 304 Not Modified.');
$this->drupalGet('', [], ['If-Modified-Since: ' . gmdate(DATE_RFC822, strtotime($last_modified)), 'If-None-Match: ' . $etag]);
$this->drupalGet('', [], [
'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->drupalGet('', [], ['If-Modified-Since: ' . gmdate(DATE_RFC850, strtotime($last_modified)), 'If-None-Match: ' . $etag]);
$this->drupalGet('', [], [
'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->drupalGet('', [], ['If-Modified-Since: ' . $last_modified]);
$this->drupalGet('', [], ['If-Modified-Since' => $last_modified, 'If-None-Match' => NULL]);
// Verify the page is not printed twice when the cache is warm.
$this->assertNoPattern('#<html.*<html#');
$this->assertResponse(200, 'Conditional request without If-None-Match returned 200 OK.');
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.');
$this->drupalGet('', [], ['If-Modified-Since: ' . gmdate(DateTimePlus::RFC7231, strtotime($last_modified) + 1), 'If-None-Match: ' . $etag]);
$this->drupalGet('', [], [
'If-Modified-Since' => gmdate(DateTimePlus::RFC7231, 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();
$this->drupalLogin($user);
$this->drupalGet('', [], ['If-Modified-Since: ' . $last_modified, 'If-None-Match: ' . $etag]);
$this->drupalGet('', [], ['If-Modified-Since' => $last_modified, 'If-None-Match' => $etag]);
$this->assertResponse(200, 'Conditional request returned 200 OK for authenticated user.');
$this->assertFalse($this->drupalGetHeader('X-Drupal-Cache'), 'Absence of Page was not cached.');
}
@ -222,7 +237,6 @@ class PageCacheTest extends WebTestBase {
public function testPageCache() {
$config = $this->config('system.performance');
$config->set('cache.page.max_age', 300);
$config->set('response.gzip', 1);
$config->save();
// Fill the cache.
@ -313,20 +327,20 @@ class PageCacheTest extends WebTestBase {
$this->drupalGet($content_url);
$this->assertText('Permission to pet llamas: no!');
$this->assertCacheContext('user.permissions');
$this->assertNoCacheTag('config:user.role.authenticated');
$this->assertSession()->responseHeaderNotContains('X-Drupal-Cache-Tags', 'config:user.role.authenticated');
$this->drupalGet($route_access_url);
$this->assertCacheContext('user.permissions');
$this->assertNoCacheTag('config:user.role.authenticated');
$this->assertSession()->responseHeaderNotContains('X-Drupal-Cache-Tags', 'config:user.role.authenticated');
// 4. authenticated user, with permission.
user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, ['pet llamas']);
$this->drupalGet($content_url);
$this->assertText('Permission to pet llamas: yes!');
$this->assertCacheContext('user.permissions');
$this->assertNoCacheTag('config:user.role.authenticated');
$this->assertSession()->responseHeaderNotContains('X-Drupal-Cache-Tags', 'config:user.role.authenticated');
$this->drupalGet($route_access_url);
$this->assertCacheContext('user.permissions');
$this->assertNoCacheTag('config:user.role.authenticated');
$this->assertSession()->responseHeaderNotContains('X-Drupal-Cache-Tags', 'config:user.role.authenticated');
}
/**
@ -356,7 +370,7 @@ class PageCacheTest extends WebTestBase {
0 => [
'value' => $this->randomString(),
'format' => 'plain_text',
]
],
],
];
$entity = EntityTest::create($entity_values);
@ -375,7 +389,7 @@ class PageCacheTest extends WebTestBase {
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
// Ensure the 'expire' field on the cache entry uses cache_ttl_4xx.
$cache_item = \Drupal::service('cache.render')->get($this->getUrl() . ':html');
$cache_item = \Drupal::service('cache.page')->get($this->getUrl() . ':html');
$difference = $cache_item->expire - (int) $cache_item->created;
// Given that a second might have passed we cannot be sure that
// $difference will exactly equal the default cache_ttl_4xx setting.
@ -394,7 +408,7 @@ class PageCacheTest extends WebTestBase {
'required' => TRUE,
];
$this->writeSettings($settings);
\Drupal::service('cache.render')->deleteAll();
\Drupal::service('cache.page')->deleteAll();
foreach ($tests as $code => $content_url) {
// Getting the 404 page twice should still result in a cache miss.
@ -516,29 +530,45 @@ class PageCacheTest extends WebTestBase {
* Tests that HEAD requests are treated the same as GET requests.
*/
public function testHead() {
/** @var \GuzzleHttp\ClientInterface $client */
$client = $this->getSession()->getDriver()->getClient()->getClient();
// GET, then HEAD.
$url_a = $this->buildUrl('system-test/set-header', ['query' => ['name' => 'Foo', 'value' => 'bar']]);
$response_body = $this->curlExec([CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $url_a, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_NOBODY => FALSE]);
$response_body = $this->drupalGet($url_a);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.');
$this->assertEqual($this->drupalGetHeader('Foo'), 'bar', 'Custom header was sent.');
$this->assertEqual('The following header was set: <em class="placeholder">Foo</em>: <em class="placeholder">bar</em>', $response_body);
$response_body = $this->curlExec([CURLOPT_HTTPGET => FALSE, CURLOPT_URL => $url_a, CURLOPT_CUSTOMREQUEST => 'HEAD', CURLOPT_NOBODY => FALSE]);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.');
$this->assertEqual($this->drupalGetHeader('Foo'), 'bar', 'Custom header was sent.');
$this->assertEqual('', $response_body);
$response = $client->request('HEAD', $url_a);
$this->assertEqual($response->getHeaderLine('X-Drupal-Cache'), 'HIT', 'Page was cached.');
$this->assertEqual($response->getHeaderLine('Foo'), 'bar', 'Custom header was sent.');
$this->assertEqual('', $response->getBody()->getContents());
// HEAD, then GET.
$url_b = $this->buildUrl('system-test/set-header', ['query' => ['name' => 'Foo', 'value' => 'baz']]);
$response_body = $this->curlExec([CURLOPT_HTTPGET => FALSE, CURLOPT_URL => $url_b, CURLOPT_CUSTOMREQUEST => 'HEAD', CURLOPT_NOBODY => FALSE]);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.');
$this->assertEqual($this->drupalGetHeader('Foo'), 'baz', 'Custom header was sent.');
$this->assertEqual('', $response_body);
$response_body = $this->curlExec([CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $url_b, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_NOBODY => FALSE]);
$response = $client->request('HEAD', $url_b);
$this->assertEqual($response->getHeaderLine('X-Drupal-Cache'), 'MISS', 'Page was not cached.');
$this->assertEqual($response->getHeaderLine('Foo'), 'baz', 'Custom header was sent.');
$this->assertEqual('', $response->getBody()->getContents());
$response_body = $this->drupalGet($url_b);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.');
$this->assertEqual($this->drupalGetHeader('Foo'), 'baz', 'Custom header was sent.');
$this->assertEqual('The following header was set: <em class="placeholder">Foo</em>: <em class="placeholder">baz</em>', $response_body);
}
/**
* Test a cacheable response with custom cache control.
*/
public function testCacheableWithCustomCacheControl() {
$config = $this->config('system.performance');
$config->set('cache.page.max_age', 300);
$config->save();
$this->drupalGet('/system-test/custom-cache-control');
$this->assertResponse(200);
$this->assertHeader('Cache-Control', 'bar, private');
}
/**
* Test that URLs are cached in a not normalized form.
*/
@ -565,18 +595,52 @@ class PageCacheTest extends WebTestBase {
];
foreach ($tests as list($url_raw, $url_normalized)) {
// Initialize cache on raw URL.
$this->drupalGet($url_raw);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
$headers = $this->getHeaders($url_raw);
$this->assertEquals('MISS', $headers['X-Drupal-Cache']);
// Ensure cache was set.
$this->drupalGet($url_raw);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', "Cache was set for {$url_raw} URL.");
$headers = $this->getHeaders($url_raw);
$this->assertEquals('HIT', $headers['X-Drupal-Cache'], "Cache was set for {$url_raw} URL.");
// Check if the normalized URL is not cached.
$this->drupalGet($url_normalized);
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', "Cache is missing for {$url_normalized} URL.");
$headers = $this->getHeaders($url_normalized);
$this->assertEquals('MISS', $headers['X-Drupal-Cache'], "Cache is missing for {$url_normalized} URL.");
}
}
/**
* Retrieves only the headers for an absolute path.
*
* Executes a cURL request without any modifications to the given URL.
* Note that Guzzle always normalizes URLs which prevents testing all
* possible edge cases.
*
* @param string $url
* URL to request.
*
* @return array
* Array of headers.
*/
protected function getHeaders($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_NOBODY, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_USERAGENT, drupal_generate_test_ua($this->databasePrefix));
$output = curl_exec($ch);
curl_close($ch);
$headers = [];
foreach (explode("\n", $output) as $header) {
if (strpos($header, ':')) {
list($key, $value) = explode(':', $header, 2);
$headers[trim($key)] = trim($value);
}
}
return $headers;
}
}