Skip to content

Commit 9de1be9

Browse files
committed
Merge pull request #288 from FriendsOfSymfony/optional-vary-user-hash
Added always_vary_on_context_hash option
2 parents 197a1c9 + 9311b61 commit 9de1be9

File tree

11 files changed

+51
-4
lines changed

11 files changed

+51
-4
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
Changelog
22
=========
33

4+
2.0.0 (unreleased)
5+
------------------
6+
7+
* [User Context] Added an option always_vary_on_context_hash to make it
8+
possible to disable automatically setting the vary headers for the user
9+
hash.
410

511
1.3.7
612
-----

DependencyInjection/Configuration.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,10 @@ private function addUserContextListenerSection(ArrayNodeDefinition $rootNode)
611611
->defaultValue(0)
612612
->info('Cache the response for the hash for the specified number of seconds. Setting this to 0 will not cache those responses at all.')
613613
->end()
614+
->booleanNode('always_vary_on_context_hash')
615+
->defaultTrue()
616+
->info('Whether to always add the user context hash header name in the response Vary header.')
617+
->end()
614618
->arrayNode('user_identifier_headers')
615619
->prototype('scalar')->end()
616620
->defaultValue(array('Cookie', 'Authorization'))

DependencyInjection/FOSHttpCacheExtension.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,8 @@ private function loadUserContext(ContainerBuilder $container, XmlFileLoader $loa
198198
->replaceArgument(0, new Reference($config['match']['matcher_service']))
199199
->replaceArgument(2, $config['user_identifier_headers'])
200200
->replaceArgument(3, $config['user_hash_header'])
201-
->replaceArgument(4, $config['hash_cache_ttl']);
201+
->replaceArgument(4, $config['hash_cache_ttl'])
202+
->replaceArgument(5, $config['always_vary_on_context_hash']);
202203

203204
if ($config['logout_handler']['enabled']) {
204205
$container->getDefinition($this->getAlias().'.user_context.logout_handler')

EventListener/UserContextSubscriber.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,18 @@ class UserContextSubscriber implements EventSubscriberInterface
6161
*/
6262
private $ttl;
6363

64+
/**
65+
* @var bool Whether to automatically add the Vary header for the hash / user identifier if there was no hash.
66+
*/
67+
private $addVaryOnHash;
68+
6469
public function __construct(
6570
RequestMatcherInterface $requestMatcher,
6671
HashGenerator $hashGenerator,
6772
array $userIdentifierHeaders = array('Cookie', 'Authorization'),
6873
$hashHeader = "X-User-Context-Hash",
69-
$ttl = 0
74+
$ttl = 0,
75+
$addVaryOnHash = true
7076
) {
7177
if (!count($userIdentifierHeaders)) {
7278
throw new \InvalidArgumentException('The user context must vary on some request headers');
@@ -76,6 +82,7 @@ public function __construct(
7682
$this->userIdentifierHeaders = $userIdentifierHeaders;
7783
$this->hashHeader = $hashHeader;
7884
$this->ttl = $ttl;
85+
$this->addVaryOnHash = $addVaryOnHash;
7986
}
8087

8188
/**
@@ -146,10 +153,16 @@ public function onKernelResponse(FilterResponseEvent $event)
146153
return;
147154
}
148155

149-
if (!in_array($this->hashHeader, $vary)) {
156+
if ($this->addVaryOnHash && !in_array($this->hashHeader, $vary)) {
150157
$vary[] = $this->hashHeader;
151158
}
152-
} else {
159+
} elseif ($this->addVaryOnHash) {
160+
/*
161+
* Additional precaution: If for some reason we get requests without a user hash, vary
162+
* on user identifier headers to avoid the caching proxy mixing up caches between
163+
* users. For the hash lookup request, those Vary headers are already added in
164+
* onKernelRequest above.
165+
*/
153166
foreach ($this->userIdentifierHeaders as $header) {
154167
if (!in_array($header, $vary)) {
155168
$vary[] = $header;

Resources/config/user_context.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
<argument />
2828
<argument />
2929
<argument />
30+
<argument />
3031
<tag name="kernel.event_subscriber" />
3132
</service>
3233

Resources/doc/reference/configuration/user-context.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ request. However, when you decide to cache hash responses, you must invalidate
120120
them when the user context changes, particularly when the user logs in or out.
121121
This bundle provides a logout handler that takes care of this for you.
122122

123+
``always_vary_on_context_hash``
124+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
125+
126+
**type**: ``boolean`` **default**: ``true``
127+
128+
This bundle automatically adds the Vary header for the user context hash, so
129+
you don't need to do this yourself or :doc:`configure it as header <headers>`.
130+
If the hash header is missing from a request for some reason, the response is
131+
set to vary on the user identifier headers to avoid problems.
132+
133+
If not all your pages depend on the hash, you can set
134+
``always_vary_on_context_hash`` to ``false`` and handle the Vary yourself.
135+
When doing that, you should be careful to set the Vary header whenever needed,
136+
or you will end up with mixed up caches.
137+
123138
``logout_handler``
124139
~~~~~~~~~~~~~~~~~~
125140

Tests/Resources/Fixtures/config/full.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
'method' => 'GET',
100100
),
101101
'hash_cache_ttl' => 300,
102+
'always_vary_on_context_hash' => true,
102103
'user_identifier_headers' => array('Cookie', 'Authorization'),
103104
'user_hash_header' => 'FOS-User-Context-Hash',
104105
'role_provider' => true,

Tests/Resources/Fixtures/config/full.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ fos_http_cache:
9393
match:
9494
method: GET
9595
hash_cache_ttl: 300
96+
always_vary_on_context_hash: true
9697
role_provider: true
9798
user_identifier_headers:
9899
- Cookie

Tests/Unit/DependencyInjection/ConfigurationTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ public function testSupportsAllConfigFormats()
153153
'method' => 'GET',
154154
),
155155
'hash_cache_ttl' => 300,
156+
'always_vary_on_context_hash' => true,
156157
'user_identifier_headers' => array('Cookie', 'Authorization'),
157158
'user_hash_header' => 'FOS-User-Context-Hash',
158159
'role_provider' => true,
@@ -460,6 +461,7 @@ private function getEmptyConfig()
460461
'method' => null,
461462
),
462463
'hash_cache_ttl' => 0,
464+
'always_vary_on_context_hash' => true,
463465
'user_identifier_headers' => array('Cookie', 'Authorization'),
464466
'user_hash_header' => 'X-User-Context-Hash',
465467
'role_provider' => false,

Tests/Unit/DependencyInjection/FOSHttpCacheExtensionTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ public function testConfigUserContext()
286286
'user_identifier_headers' => array('X-Foo'),
287287
'user_hash_header' => 'X-Bar',
288288
'hash_cache_ttl' => 30,
289+
'always_vary_on_context_hash' => true,
289290
'role_provider' => true,
290291
),
291292
);
@@ -315,6 +316,7 @@ public function testConfigWithoutUserContext()
315316
'user_identifier_headers' => array('X-Foo'),
316317
'user_hash_header' => 'X-Bar',
317318
'hash_cache_ttl' => 30,
319+
'always_vary_on_context_hash' => true,
318320
'role_provider' => true,
319321
)),
320322
);

Tests/Unit/EventListener/UserContextSubscriberTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ public function testOnKernelResponse()
130130

131131
$userContextSubscriber->onKernelResponse($event);
132132

133+
$this->assertTrue($event->getResponse()->headers->has('Vary'), 'Vary header must be set');
133134
$this->assertContains('X-Hash', $event->getResponse()->headers->get('Vary'));
134135
}
135136

0 commit comments

Comments
 (0)