Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements to Varnish configuration #180

Open
wants to merge 7 commits into
base: 2.3
Choose a base branch
from
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
6 changes: 3 additions & 3 deletions docs/varnish/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ eZ Platform Varnish configuration

Prerequisites
-------------
* A working Varnish 5.1 and higher _(6.0LTS recommended)_
* A working Varnish 6.0 or higher _(6.0LTS recommended)_
* With 'xkey' VMOD, correct version is provided with `varnish-modules` 0.10.2 or higher
* Varnish Plus comes with xkey out of the box and can also be used.
* Varnish Enterprise comes with xkey out of the box and can also be used.

Recommended VCL base files
--------------------------
For Varnish to work properly with eZ, you'll need to use the provided configuration:

* [eZ Platform 2.5LTs optimized Varnish 5.1+ VCL](vcl/varnish5.vcl)
* [eZ Platform 2.5LTs optimized Varnish 6.0+ VCL](vcl/varnish6.vcl)

For tuning the VCL further to you needs, see the following relevant examples:
- [FOSHttpCache documentation](https://foshttpcache.readthedocs.io/en/latest/varnish-configuration.html)
Expand Down
62 changes: 33 additions & 29 deletions docs/varnish/vcl/varnish5.vcl → docs/varnish/vcl/varnish6.vcl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ include "parameters.vcl";

// Called at the beginning of a request, after the complete request has been received
sub vcl_recv {
// debug header, unset to make sure it's empty:
unset req.http.x-cache;

// Set the backend
set req.backend_hint = ezplatform;
Expand Down Expand Up @@ -71,34 +73,33 @@ sub vcl_recv {
// Retrieve client user context hash and add it to the forwarded request.
call ez_user_context_hash;

if (std.healthy(req.backend_hint)) {
// change the behavior for healthy backends: Cap grace to 10s
set req.grace = 10s;
}
// If it passes all these tests, do a lookup anyway.
return (hash);
}

// Called when a cache lookup is successful. The object being hit may be stale: It can have a zero or negative ttl with only grace or keep time left.
// Set debug header to the appropriate value:
sub vcl_hit {
if (obj.ttl >= 0s) {
// A pure unadulterated hit, deliver it
return (deliver);
}

if (obj.ttl + obj.grace > 0s) {
// Object is in grace, logic below in this block is what differs from default:
// https://varnish-cache.org/docs/5.2/users-guide/vcl-grace.html#grace-mode
if (!std.healthy(req.backend_hint)) {
// Service is unhealthy, deliver from cache
return (deliver);
} else if (req.http.cookie) {
// Request it by a user with session, refresh the cache to avoid issues for editors and forum users
return (miss);
}

// By default deliver cache, automatically triggers a background fetch
return (deliver);
}

// fetch & deliver once we get the result
return (miss);
set req.http.x-cache = "hit";
}

sub vcl_miss {
set req.http.x-cache = "miss";
}

sub vcl_pass {
set req.http.x-cache = "pass";
}

sub vcl_pipe {
set req.http.x-cache = "pipe uncacheable";
}

sub vcl_synth {
set resp.http.x-cache = "synth synth";
}

// Called when the requested object has been retrieved from the backend
Expand All @@ -116,7 +117,7 @@ sub vcl_backend_response {
set beresp.do_esi = true;
}

// Make Varnish keep all objects for up to 1 hour beyond their TTL, see vcl_hit for Request logic on this
// Make Varnish keep all objects for up to 1 hour beyond their TTL, to serve in case the backend is down
set beresp.grace = 1h;

// Compressing the content
Expand Down Expand Up @@ -316,15 +317,18 @@ sub vcl_deliver {
}
}

if (obj.uncacheable) {
set req.http.x-cache = req.http.x-cache + " uncacheable" ;
} else {
set req.http.x-cache = req.http.x-cache + " cached" ;
}
if (client.ip ~ debuggers) {
// Add X-Cache header if debugging is enabled
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
// Add X-Cache (and other) debug header(s) if debugging is enabled
if (req.http.x-cache ~ "^hit") {
set resp.http.X-Cache-Hits = obj.hits;
set resp.http.X-Cache-TTL = obj.ttl;
} else {
set resp.http.X-Cache = "MISS";
}
set resp.http.x-cache = req.http.x-cache;
} else {
// Remove tag headers when delivering to non debug client
unset resp.http.xkey;
Expand Down
47 changes: 36 additions & 11 deletions docs/varnish/vcl/varnish7.vcl
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@
vcl 4.1;
import std;
import xkey;
import cookie;

// For customizing your backend and acl rules see parameters.vcl
include "/etc/varnish/parameters.vcl";
include "parameters.vcl";

// Called at the beginning of a request, after the complete request has been received
sub vcl_recv {
// debug header, unset to make sure it's empty:
unset req.http.x-cache;

// Set the backend
set req.backend_hint = ezplatform;
Expand Down Expand Up @@ -47,11 +50,9 @@ sub vcl_recv {

// Remove all cookies besides Session ID, as JS tracker cookies and so will make the responses effectively un-cached
if (req.http.cookie) {
set req.http.cookie = ";" + req.http.cookie;
set req.http.cookie = regsuball(req.http.cookie, "; +", ";");
set req.http.cookie = regsuball(req.http.cookie, ";(eZSESSID[^=]*)=", "; \1=");
set req.http.cookie = regsuball(req.http.cookie, ";[^ ][^;]*", "");
set req.http.cookie = regsuball(req.http.cookie, "^[; ]+|[; ]+$", "");
cookie.parse(req.http.cookie);
cookie.keep("eZSESSID");
set req.http.cookie = cookie.get_string();

if (req.http.cookie == "") {
// If there are no more cookies, remove the header to get page cached.
Expand All @@ -75,6 +76,27 @@ sub vcl_recv {
return (hash);
}

// Set debug header to the appropriate value:
sub vcl_hit {
set req.http.x-cache = "hit";
}

sub vcl_miss {
set req.http.x-cache = "miss";
}

sub vcl_pass {
set req.http.x-cache = "pass";
}

sub vcl_pipe {
set req.http.x-cache = "pipe uncacheable";
}

sub vcl_synth {
set resp.http.x-cache = "synth synth";
}

// Called when the requested object has been retrieved from the backend
sub vcl_backend_response {

Expand Down Expand Up @@ -293,15 +315,18 @@ sub vcl_deliver {
}
}

if (obj.uncacheable) {
set req.http.x-cache = req.http.x-cache + " uncacheable" ;
} else {
set req.http.x-cache = req.http.x-cache + " cached" ;
}
if (client.ip ~ debuggers) {
// Add X-Cache header if debugging is enabled
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
// Add X-Cache (and other) debug header(s) if debugging is enabled
if (req.http.x-cache ~ "^hit") {
set resp.http.X-Cache-Hits = obj.hits;
set resp.http.X-Cache-TTL = obj.ttl;
} else {
set resp.http.X-Cache = "MISS";
}
set resp.http.x-cache = req.http.x-cache;
} else {
// Remove tag headers when delivering to non debug client
unset resp.http.xkey;
Expand Down
21 changes: 21 additions & 0 deletions tests/varnishtests/001-simple-request.vtc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
varnishtest "Simple request"


server s1 {
rxreq
txresp
} -start


shell {
sed "s/.host =.*/.host = \"${s1_addr}\";/;s/.port = .*/.port = \"${s1_port}\";/" ${pwd}/docs/varnish/vcl/parameters.vcl > ${tmpdir}/parameters.vcl
echo "${s1_addr} ${s1_port}"
} -run

varnish v1 -arg "-p vcl_path=${tmpdir} -f $PWD/docs/varnish/vcl/${vclfile}" -start

client c1 {
txreq
rxresp

Choose a reason for hiding this comment

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

can we get an expect here, for the status, or maybe for the x-cache header?

expect resp.status == 200
} -run
22 changes: 22 additions & 0 deletions tests/varnishtests/002-cookie-handling.vtc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
varnishtest "Simple request"


server s1 {
rxreq
expect req.http.cookie == "eZSESSID=session"
txresp
} -start


shell {
sed "s/.host =.*/.host = \"${s1_addr}\";/;s/.port = .*/.port = \"${s1_port}\";/" ${pwd}/docs/varnish/vcl/parameters.vcl > ${tmpdir}/parameters.vcl
echo "${s1_addr} ${s1_port}"
} -run

varnish v1 -arg "-p vcl_path=${tmpdir} -f $PWD/docs/varnish/vcl/${vclfile}" -start

client c1 {
txreq -hdr "Cookie: unrelated_cookie=something; eZSESSID=session; another_cooke=something_else;"
rxresp
} -run

9 changes: 9 additions & 0 deletions tests/varnishtests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Varnishtest files

Varnishtests can be ran using the official docker images:

Varnish6:
docker run --rm --entrypoint varnishtest --volume $PWD:/etc/varnish varnish:stable -t 5 -D vclfile=varnish6.vcl tests/varnishtests/001-simple-request.vtc

Varnish7:
docker run --rm --entrypoint varnishtest --volume $PWD:/etc/varnish varnish:fresh -t 5 -D vclfile=varnish7.vcl tests/varnishtests/001-simple-request.vtc
Loading