Last active
September 10, 2018 17:55
-
-
Save vvuksan/ce3f7726b1b994430955368a0b392f7c to your computer and use it in GitHub Desktop.
EZ Publish VCL snippets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Stale object handling | |
if (resp.status >= 500 && resp.status < 600) { | |
/* restart if the stale object is available */ | |
if (stale.exists) { | |
restart; | |
} | |
} | |
// On receiving the hash response, copy the hash header to the original | |
// request and restart. | |
if (req.restarts == 0 | |
&& resp.http.content-type ~ "application/vnd.fos.user-context-hash" | |
) { | |
set req.http.x-user-hash = resp.http.x-user-hash; | |
restart; | |
} | |
// If we get here, this is a real response that gets sent to the client. | |
// Remove the vary on user context hash, this is nothing public. Keep all | |
// other vary headers. | |
if (!req.http.Fastly-FF && resp.http.Vary ~ "X-User-Hash") { | |
set resp.http.Vary = regsub(resp.http.Vary, "(?i),? *X-User-Hash *", ""); | |
set resp.http.Vary = regsub(resp.http.Vary, "^, *", ""); | |
if (resp.http.Vary == "") { | |
unset resp.http.Vary; | |
} | |
// If we vary by user hash, we'll also adjust the cache control headers going out by default to avoid sending | |
// large ttl meant for Varnish to shared proxies and such. We assume only session cookie is left after vcl_recv. | |
if (req.http.cookie) { | |
// When in session where we vary by user hash we by default avoid caching this in shared proxies & browsers | |
// For browser cache with it revalidating against varnish, use for instance "private, no-cache" instead | |
set resp.http.cache-control = "private, no-cache, no-store, must-revalidate"; | |
} else if (resp.http.cache-control ~ "public") { | |
// For non logged in users we allow caching on shared proxies (mobile network accelerators, planes, ...) | |
// But only for a short while, as there is no way to purge them | |
set resp.http.cache-control = "public, s-maxage=600, stale-while-revalidate=300, stale-if-error=300"; | |
} | |
} | |
// Sanity check to prevent ever exposing the hash to a non debug client. | |
if ( !req.http.Fastly-FF ) { | |
unset resp.http.x-user-hash; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* handle 503s */ | |
if (obj.status >= 500 && obj.status < 600) { | |
/* deliver stale object if it is available */ | |
if (stale.exists) { | |
return(deliver_stale); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* handle 5XX (or any other unwanted status code) */ | |
if (beresp.status >= 500 && beresp.status < 600) { | |
/* deliver stale if the object is available */ | |
if (stale.exists) { | |
return(deliver_stale); | |
} | |
if (req.restarts < 1 && (req.request == "GET" || req.request == "HEAD")) { | |
restart; | |
} | |
/* else go to vcl_error to deliver a synthetic */ | |
error beresp.status beresp.response; | |
} | |
/* # VLADIMIR COMMENT OUT | |
# This will never hit unless status code is 600+. It's handled by block above | |
if (bereq.http.accept ~ "application/vnd.fos.user-context-hash" && beresp.status >= 500 ) { | |
error beresp.status "Internal Server Error"; | |
} | |
*/ | |
// Check for ESI acknowledgement and remove Surrogate-Control header | |
if (beresp.http.Surrogate-Control ~ "ESI/1.0") { | |
unset beresp.http.Surrogate-Control; | |
esi; | |
# Since varnish doesn't compress ESIs we need to hint to the HTTP/2 terminators to | |
# compress it | |
set beresp.http.x-compress-hint = "on"; | |
} | |
if (beresp.http.Cache-Control ~ "no-cache") { | |
return(pass); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sub ez_user_context_hash { | |
// Prevent tampering attacks on the hash mechanism | |
if (req.restarts == 0 | |
&& (req.http.accept ~ "application/vnd.fos.user-context-hash" | |
|| req.http.x-user-hash | |
) | |
) { | |
error 400 "Bad request"; | |
} | |
if (req.restarts == 0 && (req.request == "GET" || req.request == "HEAD")) { | |
// Backup accept header, if set | |
if (req.http.accept) { | |
set req.http.x-fos-original-accept = req.http.accept; | |
} | |
set req.http.accept = "application/vnd.fos.user-context-hash"; | |
// Backup original URL | |
set req.http.x-fos-original-url = req.url; | |
set req.url = "/_fos_user_context_hash"; | |
// Force the lookup, the backend must tell not to cache or vary on all | |
// headers that are used to build the hash. | |
// varnish : return(hash); | |
return (lookup); | |
} | |
// Rebuild the original request which now has the hash. | |
if (req.restarts > 0 && req.http.accept == "application/vnd.fos.user-context-hash") { | |
// By default, fastly treats a restart as a failure and wont distribute hits in the PoP cluster | |
// Setting Fastly-Force-Shield fixes that behaviour | |
set req.http.Fastly-Force-Shield = "1"; | |
set req.url = req.http.x-fos-original-url; | |
unset req.http.x-fos-original-url; | |
if (req.http.x-fos-original-accept) { | |
set req.http.accept = req.http.x-fos-original-accept; | |
unset req.http.x-fos-original-accept; | |
} else { | |
// If accept header was not set in original request, remove the header here. | |
unset req.http.accept; | |
} | |
// Force the lookup, the backend must tell not to cache or vary on the | |
// user context hash to properly separate cached data. | |
// varnish : return(hash); | |
//return (lookup); | |
//return (pass); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Advertise Symfony for ESI support | |
set req.http.Surrogate-Capability = "abc=ESI/1.0"; | |
// Varnish, in its default configuration, sends the X-Forwarded-For header but does not filter out Forwarded header | |
if ( req.restarts == 0 ) { | |
unset req.http.Forwarded; | |
} | |
// Preserve X-Forwarded-For in all requests. | |
if (!req.http.Fastly-FF) { | |
if (req.http.X-Forwarded-For) { | |
set req.http.Fastly-Temp-XFF = req.http.X-Forwarded-For ", " client.ip; | |
} else { | |
set req.http.Fastly-Temp-XFF = client.ip; | |
} | |
} else { | |
# We are on Origin Shield | |
set req.http.Fastly-Temp-XFF = req.http.X-Forwarded-For; | |
set req.max_stale_while_revalidate = 0s; | |
# VLADIMIR ADD - disable ESI processing on Origin Shield | |
set req.esi = false; | |
} | |
/* -- VLADIMIR COMMENT OUT -- early returns are discouraged as they may avoid shielding logic | |
if (req.http.Authenticate || req.http.Authorization) { | |
return(lookup); | |
} | |
*/ | |
// Remove all cookies besides Session ID, as JS tracker cookies and so will make the responses effectively un-cached | |
// VLADIMIR -- I would consider removing this altogether | |
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, "^[; ]+|[; ]+$", ""); | |
if (req.http.cookie == "") { | |
// If there are no more cookies, remove the header to get page cached. | |
unset req.http.cookie; | |
} | |
} | |
/* VLADIMIR COMMENT OUT-- this is unnecessary as most these things are already set ie. duplicates X-Forwarded-For logic from above | |
if( req.url.ext ~ "(?i)(css|js|gif|jpe?g|bmp|png|tiff?|ico|img|tga|wmf|svg|swf|ico|mp3|mp4|m4a|ogg|mov|avi|wmv|zip|gz|pdf|ttf|eot|wof)" ) { | |
if (!req.http.Fastly-FF) { | |
if (req.http.X-Forwarded-For) { | |
set req.http.Fastly-Temp-XFF = req.http.X-Forwarded-For ", " client.ip; | |
} else { | |
set req.http.Fastly-Temp-XFF = client.ip; | |
} | |
} else { | |
set req.http.Fastly-Temp-XFF = req.http.X-Forwarded-For; | |
} | |
return(lookup); | |
} | |
*/ | |
// Sort the query string for cache normalization. | |
set req.url = boltsort.sort(req.url); | |
// Retrieve client user context hash and add it to the forwarded request. | |
call ez_user_context_hash; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment