Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ Next, use nslookup to find the IP:
### Fetching user context hash

As explained in [User Context Hash caching](context_aware_cache.md#user-context-hash-caching), the HTTP cache indexes the cache based on the user-context-hash.
Users with the same user-context-hash here the same cache (as long as [[= product_name =]] responds with `Vary: X-Context-User-Hash`).
Users with the same user-context-hash here the same cache (as long as [[= product_name =]] responds with `Vary: X-User-Context-Hash`).

To simulate the requests the HTTP cache sends to [[= product_name =]], you need this user-context-hash.
To obtain it, use `curl`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
It means that HTTP cache is unique per set of user permissions (roles and limitations), and there are variations of cache shared only among users that have the exact same permissions.
So if a user browses a list of children locations, they only see children locations they have access to, even if their rendering is served from HTTP cache.

This is accomplished by varying on a header called `X-Context-User-Hash`, which the system populates on the request.
This is accomplished by varying on a header called `X-User-Context-Hash`, which the system populates on the request.

Check warning on line 13 in docs/infrastructure_and_maintenance/cache/http_cache/context_aware_cache.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/cache/http_cache/context_aware_cache.md#L13

[Ibexa.UnclearAntecedent] Instead of 'This is', try starting this sentence with a specific subject and verb.
Raw output
{"message": "[Ibexa.UnclearAntecedent] Instead of 'This is', try starting this sentence with a specific subject and verb.", "location": {"path": "docs/infrastructure_and_maintenance/cache/http_cache/context_aware_cache.md", "range": {"start": {"line": 13, "column": 1}}}, "severity": "WARNING"}

Check notice on line 13 in docs/infrastructure_and_maintenance/cache/http_cache/context_aware_cache.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/infrastructure_and_maintenance/cache/http_cache/context_aware_cache.md#L13

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/infrastructure_and_maintenance/cache/http_cache/context_aware_cache.md", "range": {"start": {"line": 13, "column": 6}}}, "severity": "INFO"}
The [logic for this](#request-lifecycle) is accomplished in the provided VCL for Varnish and Fastly.
A similar but internal logic is done in the provided enhanced Symfony Proxy (AppCache).

Expand All @@ -21,9 +21,9 @@
1. A client (browser) requests URI `/foo`.
1. The caching proxy receives the request and holds it. It first sends a hash request to the application's context hash route: `/_fos_user_context_hash`.
1. The application receives the hash request. An event subscriber (`UserContextSubscriber`) aborts the request immediately after the Symfony firewall is applied.
The application calculates the hash (`HashGenerator`) and then sends a response with the hash in a custom header (`X-Context-User-Hash`).
The application calculates the hash (`HashGenerator`) and then sends a response with the hash in a custom header (`X-User-Context-Hash`).
1. The caching proxy receives the hash response, copies the hash header to the client's original request for `/foo` and restarts the modified original request.
1. If the response to `/foo` should differ per user context, the application sets a `Vary: X-Context-User-Hash` header, which makes Proxy store the variations of this cache varying on the hash value.
1. If the response to `/foo` should differ per user context, the application sets a `Vary: X-User-Context-Hash` header, which makes Proxy store the variations of this cache varying on the hash value.

The next time a request comes in from the same user, application lookup for the hash (step 3) doesn't take place, as the hash lookup itself is cached by the cache proxy as described below.

Expand All @@ -33,7 +33,7 @@

```
HTTP/1.1 200 OK
X-Context-User-Hash: <hash>
X-User-Context-Hash: <hash>
Content-Type: application/vnd.fos.user-context-hash
Cache-Control: public, max-age=600
Vary: Cookie, Authorization
Expand Down Expand Up @@ -104,7 +104,7 @@

This solution requires more effort depending on project requirements (for example, traffic load).

3\. Custom vary by logic, for example, `X-User-Preference-Hash` inspired by `X-Context-User-Hash`:
3\. Custom vary by logic, for example, `X-User-Preference-Hash` inspired by `X-User-Context-Hash`:

This method allows for fine-grained caching as you can explicitly vary on this in only the places that need it.

Expand Down Expand Up @@ -157,15 +157,15 @@
@@ -174,6 +174,7 @@ sub ez_user_context_hash {
if (req.restarts == 0
&& (req.http.accept ~ "application/vnd.fos.user-context-hash"
|| req.http.X-Context-User-Hash
|| req.http.x-user-context-hash
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I've adjusted it to be in line with https://github.com/ibexa/http-cache/blob/4.6/docs/varnish/vcl/varnish7.vcl (which uses lowercase here)

+ || req.http.x-user-preference-hash
)
) {
return (synth(400, "Bad Request"));
@@ -263,12 +264,19 @@ sub vcl_deliver {
&& resp.http.content-type ~ "application/vnd.fos.user-context-hash"
) {
set req.http.X-Context-User-Hash = resp.http.X-Context-User-Hash;
set req.http.x-user-context-hash = resp.http.x-user-context-hash;
+ set req.http.x-user-preference-hash = resp.http.x-user-preference-hash;

return (restart);
Expand All @@ -181,7 +181,7 @@
+
// Remove the vary on user context hash, this is nothing public. Keep all
// other vary headers.
if (resp.http.Vary ~ "X-Context-User-Hash") {
if (resp.http.Vary ~ "X-User-Context-Hash") {
```

3\. Add `Vary` in your custom controller or content view controller:
Expand All @@ -190,5 +190,5 @@
$response->setVary('X-User-Preference-Hash');

// If you _also_ need to vary on [[= product_name =]] permissions, instead use:
//$response->setVary(['X-Context-User-Hash', 'X-User-Preference-Hash']);
//$response->setVary(['X-User-Context-Hash', 'X-User-Preference-Hash']);
```