Mais conteúdo relacionado Semelhante a Caching the uncacheable with Varnish - DevDays 2021 (20) Caching the uncacheable with Varnish - DevDays 202127. CONTROLLING THE CACHE WITH HTTP
Expires: Sat, 09 Sep 2017 14:30:00 GMT
Cache-control: public, max-age=3600, s-maxage=86400
Cache-control: stale-while-revalidate=100
Cache-control: private, no-cache, no-store
Surrogate-Control: max-age=3600+600
Surrogate-Control: content="ESI/1.0"
Vary: Accept-Language
33. vcl 4.1
;
sub vcl_recv
{
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,
";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; 1=")
;
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "")
;
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "")
;
if (req.http.cookie ~ "^s*$")
{
unset req.http.Cookie
;
}
}
}
Only
keep certain
cookies
34. sub vcl_recv
{
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, ";(language)=", "; 1=")
;
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "")
;
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "")
;
if (req.http.cookie ~ "^s*$")
{
unset req.http.cookie
;
}
return(hash)
;
}
}
sub vcl_hash
{
hash_data(regsub( req.http.Cookie, "^.*language=([^;]*);*.*$", "1" ))
;
}
Cookie
cache
variation
35. vcl 4.1
;
import cookie
;
sub vcl_recv
{
cookie.parse(req.http.cookie)
;
cookie.keep("language")
;
set req.http.cookie = cookie.get_string()
;
}
sub vcl_hash
{
hash_data(cookie.get("language"))
;
}
VMOD_COOKIE
49. CURRENT STATUS
✓ REMOVE UNWANTED COOKIES
✓ LEVERAGE COOKIES FOR CACHE VARIATIONS
✓ USE PLACEHOLDERS TO LOAD STATEFUL CONTENT
TO
INCREASE HIT
RATE
51. NOT JUST A CACHE
NOT JUST "TAKE IT OR LEAVE IT"
55. <!DOCTYPE html>
<html>
<head>
<title>200 Synthetic output</title>
</head>
<body>
<h1>Error 200 Synthetic output</h1>
<p>Synthetic output</p>
<h3>Guru Meditation:</h3>
<p>XID: 32770</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
SYNTHETIC HTTP
56. <!DOCTYPE html>
<html>
<head>
<title>Error 503 Backend fetch failed</title>
</head>
<body>
<h1>Error 503 Backend fetch failed</h1>
<p>Backend fetch failed</p>
<h3>Guru Meditation:</h3>
<p>XID: 32804</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
SYNTHETIC HTTP
WHEN
ERRORS
OCCUR
59. vcl 4.1;
import redis;
import synthbackend;
import ykey;
import format;
backend default {
.host = "backend.example.com";
}
sub vcl_init {
new redis_client = redis.db(
location="redis:6379",
shared_connections=false,
max_connections=1);
}
sub vcl_recv {
if(req.url == "/api/session") {
set req.http.sessionId = regsub(req.http.Cookie,"^.*;?s*sessionIds*=s*([0-9a-zA-z]+)
s*;?.*","1");
return(hash);
}
}
SYNTHETIC HTTP
60. sub vcl_hash {
hash_data(req.http.sessionId);
}
sub vcl_backend_fetch {
if(bereq.url == "/api/session") {
redis_client.command("HGET");
redis_client.push(bereq.http.sessionId);
redis_client.push("username");
redis_client.execute();
if(redis_client.reply_is_nil() || redis_client.reply_is_error()) {
set bereq.backend = synthbackend.from_string("{}");
} else {
set bereq.backend = synthbackend.from_string(
format.quick({"{ "username":"%s" }"}, redis_client.get_string_reply())
);
}
} else {
set bereq.backend = default;
}
}
sub vcl_backend_response {
if(bereq.url == "/api/session") {
set beresp.http.Content-Type = "application/json";
set beresp.ttl = 3h;
}
}
62. WHAT DO YOU DO WITH IT?
✓ AJAX CALL
✓ LOAD VIA ESI AND PROCESS VIA LOCAL JAVASCRIPT
✓ EDGESTASH
65. vcl 4.1;
import edgestash;
backend default
{
.host = "backend.example.com";
}
sub vcl_backend_response {
if (bereq.url == "/api/session") {
edgestash.index_json();
} else if (bereq.url == "/") {
edgestash.parse_response();
}
}
sub vcl_deliver {
if (req.url == "/" && edgestash.is_edgestash()) {
edgestash.add_json_url("/api/session");
edgestash.execute();
}
}
EDGESTASH
69. vcl 4.1;
import edgestash;
import std;
backend default
{
.host = "backend.example.com";
}
sub vcl_recv
{
set req.http.Surrogate-Capability={"edgestash="EDGESTASH/2.1""};
}
sub vcl_backend_response
{
if(beresp.http.Link) {
std.collect(beresp.http.Link,",");
}
if(beresp.http.Link ~ "<([^>]+)>; rel=edgestash") {
set beresp.http.x-edgestash-json-urls = regsuball(beresp.http.Link,"(?(?=<[^>]+>; rel=edgestash)<([^>]+)>;
rel=edgestash|<([^>]+)>; rel=[a-z]+, )","1");
}
if(beresp.http.Surrogate-Control) {
std.collect(beresp.http.Surrogate-Control);
}
if(beresp.http.Surrogate-Control ~ {".*="EDGESTASH/2.[0-9]+".*"}) {
edgestash.parse_response();
}
}
EDGESTASH
70. sub vcl_deliver
{
if(edgestash.is_edgestash() && resp.http.x-edgestash-json-urls) {
edgestash.add_json_url_csv(resp.http.x-edgestash-json-urls);
edgestash.execute();
}
unset resp.http.Link;
unset resp.http.x-edgestash-json-urls;
unset resp.http.surrogate-control;
}
EDGESTASH
72. vcl 4.1;
import xbody;
import edgestash;
sub vcl_backend_response {
if(bereq.url == "/") {
xbody.regsub({"(<div id="username" [^>]+>)(w*)(</div>)"},
{"1{{username}}3"});
edgestash.parse_response();
}
}
78. import deviceatlas;
sub vcl_recv {
set req.http.MobilePhone = "no";
if (deviceatlas.lookup_int(req.http.User-Agent, "isMobilePhone")) {
set req.http.MobilePhone = "yes";
}
}
Device
detection
79. vcl 4.0;
import mmdb;
backend default { .host = "192.0.2.11"; .port = "8080"; }
# create a database object
sub vcl_init {
new geodb = mmdb.init("/path/to/db");
}
sub vcl_recv {
# retrieve the name of the request's origin
set req.http.Country-Name = geodb.country_name(client.ip);
# if the country doesn't come from Germany or Belgium, deny access
if (req.http.Country-Name != "Germany" ||
req.http.Country-Name != "Belgium") {
return (synth(403, "Sorry, only available in Germany and Belgium"));
}
}
Geo
blocking
80. vcl 4.0;
import http;
backend default {
.host = "origin";
.port = "80";
}
sub vcl_recv {
set req.http.X-prefetch = http.varnish_url("/");
}
sub vcl_backend_response {
if (beresp.http.Link ~ "<.+>.*(prefetch|next)") {
set bereq.http.X-link = regsub(beresp.http.Link, "^.*<([^>]*)>.*$", "1");
set bereq.http.X-prefetch = regsub(bereq.http.X-prefetch, "/$", bereq.http.X-link);
http.init(0);
http.req_copy_headers(0);
http.req_set_url(0, bereq.http.X-prefetch);
http.req_send_and_finish(0);
}
}
Pre-fetching