diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f1f9bd7..d8246cd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,8 @@ See also the [GitHub releases page](https://github.com/FriendsOfSymfony/FOSHttpC options array for customization. * Provide a trait for the event dispatching kernel, instead of a base class. The trait offers both the addSubscriber and the addListener methods. +* By default, no hash header is sent for anonymous users anymore, to sync + behaviour with Varnish behaviour. ### Testing diff --git a/doc/symfony-cache-configuration.rst b/doc/symfony-cache-configuration.rst index 160c2eae..8b3ffe25 100644 --- a/doc/symfony-cache-configuration.rst +++ b/doc/symfony-cache-configuration.rst @@ -182,6 +182,8 @@ options through the constructor: * **anonymous_hash**: Hash used for anonymous user. This is a performance optimization to not do a backend request for users that are not logged in. + By default, the header is skipped. If you specify a header, that header is + used. * **user_hash_accept_header**: Accept header value to be used to request the user hash to the backend application. Must match the setup of the backend diff --git a/doc/user-context.rst b/doc/user-context.rst index d7dcc919..4acf9ba0 100644 --- a/doc/user-context.rst +++ b/doc/user-context.rst @@ -62,6 +62,19 @@ client, moving step 2-4 into the cache. After the page is in cache, subsequent requests from clients that got the same hash can be served from the cache as well. +.. note:: + + If your application starts sessions for anonymous users, you will get one + hash lookup request for each of those users. Your application can return + the same hash for authenticated users with no special privileges as for + anonymous users with a session cookie. + + If there is no cookie and no authentication information, the hash lookup is + skipped and no hash header added to the request. However, we can not avoid + the initial hash lookup request per different cookie, as the caching proxy + can not know which session cookies indicate a logged in user and which an + anonymous session. + Proxy Client Configuration -------------------------- diff --git a/doc/varnish-configuration.rst b/doc/varnish-configuration.rst index 21126089..f56cda3f 100644 --- a/doc/varnish-configuration.rst +++ b/doc/varnish-configuration.rst @@ -55,7 +55,7 @@ Purge removes a specific URL (including query strings) in all its variants (as specified by the ``Vary`` header). Subroutines are provided in ``resources/config/varnish-[version]/fos_purge.vcl``. -To enable support add the following to ``your_varnish.vcl``: +To enable this feature, add the following to ``your_varnish.vcl``: .. configuration-block:: @@ -96,7 +96,7 @@ Refreshing applies only to a specific URL including the query string, but *not* its variants. Subroutines are provided in ``resources/config/varnish-[version]/fos_refresh.vcl``. -To enable support, add the following to ``your_varnish.vcl``: +To enable this feature, add the following to ``your_varnish.vcl``: .. configuration-block:: @@ -125,7 +125,7 @@ Ban Banning invalidates whole groups of cached entries with regular expressions. Subroutines are provided in ``resources/config/varnish-[version]/fos_ban.vcl`` -To enable support add the following to ``your_varnish.vcl``: +To enable this feature, add the following to ``your_varnish.vcl``: .. configuration-block:: @@ -202,11 +202,14 @@ User Context Feature: :doc:`user context hashing ` -The ``fos_user_context.vcl`` needs the ``user_context_hash_url`` subroutine that sets a URL to the request lookup URL. The default URL is ``/_fos_user_context_hash`` and you can simply include ``resources/config/varnish-[version]/fos_user_context_url.vcl`` in your configuration to provide this. If you need a different URL, include a custom file implementing the ``user_context_hash_url`` subroutine. - - -To enable support add the following to ``your_varnish.vcl``: +The ``fos_user_context.vcl`` needs the ``user_context_hash_url`` subroutine +that sets a URL to the request lookup URL. The default URL is +``/_fos_user_context_hash`` and you can simply include +``resources/config/varnish-[version]/fos_user_context_url.vcl`` in your +configuration to provide this. If you need a different URL, include a custom +file implementing the ``user_context_hash_url`` subroutine. +To enable this feature, add the following to ``your_varnish.vcl``: .. configuration-block:: @@ -358,7 +361,7 @@ sends an ``X-Cache-Debug`` header: Subroutines are provided in ``fos_debug.vcl``. -To enable support add the following to ``your_varnish.vcl``: +To enable this feature, add the following to ``your_varnish.vcl``: .. configuration-block:: diff --git a/src/SymfonyCache/UserContextListener.php b/src/SymfonyCache/UserContextListener.php index 6d38ca16..3c86b992 100644 --- a/src/SymfonyCache/UserContextListener.php +++ b/src/SymfonyCache/UserContextListener.php @@ -60,7 +60,7 @@ public function __construct(array $options = []) { $resolver = new OptionsResolver(); $resolver->setDefaults([ - 'anonymous_hash' => '38015b703d82206ebc01d17a39c727e5', + 'anonymous_hash' => null, 'user_hash_accept_header' => 'application/vnd.fos.user-context-hash', 'user_hash_header' => 'X-User-Context-Hash', 'user_hash_uri' => '/_fos_user_context_hash', @@ -104,8 +104,8 @@ public function preHandle(CacheEvent $event) return; } - if ($request->isMethodSafe()) { - $request->headers->set($this->options['user_hash_header'], $this->getUserHash($event->getKernel(), $request)); + if ($request->isMethodSafe() && $hash = $this->getUserHash($event->getKernel(), $request)) { + $request->headers->set($this->options['user_hash_header'], $hash); } } diff --git a/tests/Unit/SymfonyCache/UserContextListenerTest.php b/tests/Unit/SymfonyCache/UserContextListenerTest.php index 6e4fb91d..07fa85a2 100644 --- a/tests/Unit/SymfonyCache/UserContextListenerTest.php +++ b/tests/Unit/SymfonyCache/UserContextListenerTest.php @@ -107,8 +107,12 @@ public function testUserHashAnonymous($arg, $options) $response = $event->getResponse(); $this->assertNull($response); - $this->assertTrue($request->headers->has($options['user_hash_header'])); - $this->assertSame($options['anonymous_hash'], $request->headers->get($options['user_hash_header'])); + if ($options['anonymous_hash']) { + $this->assertTrue($request->headers->has($options['user_hash_header'])); + $this->assertSame($options['anonymous_hash'], $request->headers->get($options['user_hash_header'])); + } else { + $this->assertFalse($request->headers->has($options['user_hash_header'])); + } } /**