Skip to content

Commit d9979f9

Browse files
committed
Merge branch 'sprain-master'
2 parents d5e382f + 437e05c commit d9979f9

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

doc/symfony-cache-configuration.rst

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,10 @@ User Context
118118
~~~~~~~~~~~~
119119

120120
To support :doc:`user context hashing <user-context>` you need to register the
121-
``UserContextSubscriber``. If the default settings are right for you, you don't
122-
need to do anything more. You can customize a number of options through the
123-
constructor:
121+
``UserContextSubscriber``. The user context is then automatically recognized
122+
based on session cookies or authorization headers. If the default settings are
123+
right for you, you don't need to do anything more. You can customize a number of
124+
options through the constructor:
124125

125126
* **anonymous_hash**: Hash used for anonymous user. This is a performance
126127
optimization to not do a backend request for users that are not logged in.
@@ -160,6 +161,16 @@ constructor:
160161
user context hash for every users, or not having it cached at all, which
161162
hurts performance.
162163

164+
.. note::
165+
166+
To use authorization headers for user context, you might have to add some server
167+
configuration to make these headers available to PHP.
168+
169+
With Apache, you can do this for example in a ``.htaccess`` file:
170+
171+
RewriteEngine On
172+
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
173+
163174
Cleaning the Cookie Header
164175
^^^^^^^^^^^^^^^^^^^^^^^^^^
165176

src/SymfonyCache/UserContextSubscriber.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@ protected function cleanupHashLookupRequest(Request $hashLookupRequest, Request
130130
$hashLookupRequest->cookies->set($name, $value);
131131
}
132132
}
133-
$hashLookupRequest->headers->set('Cookie', http_build_query($sessionIds, '', '; '));
133+
134+
if (count($sessionIds) > 0) {
135+
$hashLookupRequest->headers->set('Cookie', http_build_query($sessionIds, '', '; '));
136+
}
134137
}
135138

136139
/**
@@ -180,6 +183,16 @@ private function getUserHash(HttpKernelInterface $kernel, Request $request)
180183
*/
181184
private function isAnonymous(Request $request)
182185
{
186+
// You might have to enable rewriting of the Authorization header in your server config or .htaccess:
187+
// RewriteEngine On
188+
// RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
189+
if ($request->server->has('AUTHORIZATION') ||
190+
$request->server->has('HTTP_AUTHORIZATION') ||
191+
$request->server->has('PHP_AUTH_USER')
192+
) {
193+
return false;
194+
}
195+
183196
foreach ($request->cookies as $name => $value) {
184197
if ($this->isSessionName($name)) {
185198
return false;

tests/Unit/SymfonyCache/UserContextSubscriberTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ public function testUserHashUserWithSession($arg, $options)
160160
$request->getMethod();
161161
$request->getPathInfo();
162162
$that->assertEquals($hashRequest, $request);
163+
$that->assertCount(2, $request->cookies->all());
163164

164165
return true;
165166
}),
@@ -177,6 +178,54 @@ public function testUserHashUserWithSession($arg, $options)
177178
$this->assertSame($expectedContextHash, $request->headers->get($options['user_hash_header']));
178179
}
179180

181+
/**
182+
* @dataProvider provideConfigOptions
183+
*/
184+
public function testUserHashUserWithAuthorizationHeader($arg, $options)
185+
{
186+
$userContextSubscriber = new UserContextSubscriber($arg);
187+
188+
// The foo cookie should not be available in the eventual hash request anymore
189+
$request = Request::create('/foo', 'GET', array(), array('foo' => 'bar'), array(), array('HTTP_AUTHORIZATION' => 'foo'));
190+
191+
$hashRequest = Request::create($options['user_hash_uri'], $options['user_hash_method'], array(), array(), array(), $request->server->all());
192+
$hashRequest->attributes->set('internalRequest', true);
193+
$hashRequest->headers->set('Accept', $options['user_hash_accept_header']);
194+
195+
// Ensure request properties have been filled up.
196+
$hashRequest->getPathInfo();
197+
$hashRequest->getMethod();
198+
199+
$expectedContextHash = 'my_generated_hash';
200+
$hashResponse = new Response();
201+
$hashResponse->headers->set($options['user_hash_header'], $expectedContextHash );
202+
203+
$that = $this;
204+
$this->kernel
205+
->expects($this->once())
206+
->method('handle')
207+
->with(
208+
$this->callback(function (Request $request) use ($that, $hashRequest) {
209+
// we need to call some methods to get the internal fields initialized
210+
$request->getMethod();
211+
$request->getPathInfo();
212+
$that->assertEquals($hashRequest, $request);
213+
$that->assertCount(0, $request->cookies->all());
214+
215+
return true;
216+
})
217+
)
218+
->will($this->returnValue($hashResponse));
219+
220+
$event = new CacheEvent($this->kernel, $request);
221+
222+
$userContextSubscriber->preHandle($event);
223+
$response = $event->getResponse();
224+
225+
$this->assertNull($response);
226+
$this->assertTrue($request->headers->has($options['user_hash_header']));
227+
$this->assertSame($expectedContextHash, $request->headers->get($options['user_hash_header']));
228+
}
180229

181230
/**
182231
* @expectedException \InvalidArgumentException

0 commit comments

Comments
 (0)