Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // General module loading
- vcl 4.0;
- import std;
- import directors;
- // Configuration for local system settings
- include "/etc/varnish/fuf-local.vcl";
- // Extended cache control (v-max-age)
- include "/etc/varnish/fuf-extended_cache_control.vcl";
- sub vcl_recv {
- // See local.vcl for handling
- call set_director_and_forwardedfor;
- // If needed include local ACL to deny or allow access
- include "/etc/varnish/fuf-acl.vcl";
- if (req.http.x-forwarded-for) {
- std.collect(req.http.x-forwarded-for);
- set req.http.x-forwarded-for = regsub(req.http.x-forwarded-for, "^(.*),.*", "\1");
- }
- // Set default grace header
- set req.http.grace = "none";
- // Normalize the header, remove the port (in case you're testing this on various TCP ports)
- set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
- // Normalize the query arguments
- set req.url = std.querysort(req.url);
- // Allow purging
- if (req.method == "PURGE") {
- if (!client.ip ~ purge) { # purge is the ACL defined at the begining
- return (synth(405, "This IP is not allowed to send PURGE requests."));
- }
- // score purging logic
- if (req.http.X-Purge-Host) {
- ban("req.url ~ " + regsuball(req.http.X-Purge-Url, "\\\\", "\\") + " && req.http.host ~ " + regsuball(req.http.X-Purge-Host, "\\\\", "\\"));
- } else {
- ban("req.url ~ " + regsuball(req.http.X-Purge-Url, "\\\\", "\\"));
- }
- return (synth(200, "Purged."));
- }
- // Only deal with "normal" types
- if (req.method != "GET" &&
- req.method != "HEAD" &&
- req.method != "PUT" &&
- req.method != "POST" &&
- req.method != "TRACE" &&
- req.method != "OPTIONS" &&
- req.method != "PATCH" &&
- req.method != "DELETE") {
- /* Non-RFC2616 or CONNECT which is weird. */
- return (pipe);
- }
- // Only cache GET or HEAD requests. This makes sure the POST requests
- // are always passed.
- if (req.method != "GET" && req.method != "HEAD") {
- return (pass);
- }
- // Some generic URL manipulation, useful for all templates that follow
- // First remove the Google Analytics added parameters, useless for
- // our backend
- if (req.url ~ "(\?|&)(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl|id|view|layout|format|type|start|limitstart)=") {
- set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl|id|view|layout|format|type|start|limitstart)=([A-z0-9_\-\.%25]+)", "");
- set req.url = regsuball(req.url, "\?(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl|id|view|layout|format|type|start|limitstart)=([A-z0-9_\-\.%25]+)", "?");
- set req.url = regsub(req.url, "\?&", "?");
- set req.url = regsub(req.url, "\?$", "");
- }
- // Strip hash, server doesn't need it.
- if (req.url ~ "\#") {
- set req.url = regsub(req.url, "\#.*$", "");
- }
- // Strip a trailing ? if it exists
- if (req.url ~ "\?$") {
- set req.url = regsub(req.url, "\?$", "");
- }
- // Some generic cookie manipulation, useful for all templates that follow
- // Remove the "has_js" cookie
- set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
- // Remove any Google Analytics based cookies
- set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
- set req.http.Cookie = regsuball(req.http.Cookie, "_ga=[^;]+(; )?", "");
- set req.http.Cookie = regsuball(req.http.Cookie, "utmctr=[^;]+(; )?", "");
- set req.http.Cookie = regsuball(req.http.Cookie, "utmcmd.=[^;]+(; )?", "");
- set req.http.Cookie = regsuball(req.http.Cookie, "utmccn.=[^;]+(; )?", "");
- // Remove DoubleClick offensive cookies
- set req.http.Cookie = regsuball(req.http.Cookie, "__gads=[^;]+(; )?", "");
- // Remove the Quant Capital cookies (added by some plugin, all __qca)
- set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
- // Remove the AddThis cookies
- set req.http.Cookie = regsuball(req.http.Cookie, "__atuv.=[^;]+(; )?", "");
- // Remove a ";" prefix in the cookie if present
- set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
- // Are there cookies left with only spaces or that are empty?
- if (req.http.cookie ~ "^\s*$") {
- unset req.http.cookie;
- }
- // Normalize Accept-Encoding header
- // TODO: Test if it's still needed, Varnish 4 now does this by itself
- // if http_gzip_support = on
- // https://www.varnish-cache.org/docs/trunk/users-guide/compression.html
- // https://www.varnish-cache.org/docs/trunk/phk/gzip.html
- if (req.http.Accept-Encoding) {
- if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
- // No point in compressing these
- unset req.http.Accept-Encoding;
- } elsif (req.http.Accept-Encoding ~ "gzip") {
- set req.http.Accept-Encoding = "gzip";
- } elsif (req.http.Accept-Encoding ~ "deflate") {
- set req.http.Accept-Encoding = "deflate";
- } else {
- // unkown algorithm
- unset req.http.Accept-Encoding;
- }
- }
- // Don't send cookie for static files
- if (req.url ~ "^[^?]*\.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|mp[34]|pdf|png|rar|rtf|swf|tar|tgz|txt|wav|woff|woff2|xml|zip)(\?.*)?$") {
- unset req.http.Cookie;
- return (hash);
- }
- if (req.url ~ "^[^?]*\.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av])(\?.*)?$") {
- unset req.http.Cookie;
- return (hash);
- }
- // Not cacheable by default
- if (req.http.Authorization) {
- return (pass);
- }
- return (hash);
- }
- sub vcl_pipe {
- return (pipe);
- }
- sub vcl_pass {
- #return (pass);
- }
- // Needed for our various cookie settings
- include "/etc/varnish/fuf-hash.vcl";
- sub vcl_hit {
- // If the object is in cache and is not expired - deliver it :)
- if (obj.ttl >= 0s) {
- return (deliver);
- }
- // Asynchronous fetching of an object and serve stale object defined
- // by grace time. See https://www.varnish-software.com/blog/ \
- // grace-varnish-4-stale-while-revalidate-semantics-varnish
- // How it works:
- // 6h past expiration time of the object a stale object (24h kept back,
- // see vcl_backend_response). After that time the object is fetched by
- // the user and she has to wait until the object is served by the backend
- if (std.healthy(req.backend_hint)) {
- // Backend is healthy. Limit age to 6h.
- if (obj.ttl + 6h > 0s) {
- set req.http.grace = "normal(limited)";
- return (deliver);
- } else {
- // No candidate for grace. Fetch a fresh object.
- return(fetch);
- }
- } else {
- // backend is sick - use full grace
- if (obj.ttl + obj.grace > 0s) {
- set req.http.grace = "full";
- return (deliver);
- } else {
- // no graced object.
- return (fetch);
- }
- }
- // fetch & deliver once we get the result (dead code, keep as a safeguard
- return (fetch);
- }
- sub vcl_miss {
- return (fetch);
- }
- // Handle the HTTP request coming from our backend
- sub vcl_backend_response {
- set beresp.do_gzip = true;
- // If our backend fails, try to get it again (retry)
- if (beresp.status >= 500 && bereq.retries <= 1) {
- return(retry);
- }
- if (bereq.url ~ "^[^?]*\.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|mp[34]|pdf|png|rar|rtf|swf|tar|tgz|txt|wav|woff|woff2|xml|zip)(\?.*)?$") {
- unset beresp.http.set-cookie;
- }
- if (bereq.url ~ "^[^?]*\.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av])(\?.*)?$") {
- unset beresp.http.set-cookie;
- // Check memory usage it'll grow in fetch_chunksize blocks
- // (128k by default) if the backend doesn't send a Content-Length
- // header, so only enable it for big objects
- set beresp.do_stream = true;
- set beresp.do_gzip = false;
- }
- if (beresp.status == 301 || beresp.status == 302) {
- set beresp.http.Location = regsub(beresp.http.Location, ":[0-9]+", "");
- }
- // Allow stale content, in case the backend goes down.
- // make Varnish keep all objects for 6 hours beyond their TTL
- set beresp.grace = 24h;
- // Do not cache anything by default, handle everything else below
- // This is standard score setting
- set beresp.ttl = 0s;
- // Don't set the cache ttl to 0s and put in cache - instead use pass to
- // directly deliver the object without storing it
- if (beresp.http.Set-Cookie || beresp.status == 301 || beresp.status == 302 || beresp.status == 400 || beresp.status == 401 || beresp.status == 403 || beresp.status == 301) {
- set beresp.uncacheable = true;
- } else if (beresp.status == 410) {
- set beresp.ttl = 360d;
- } else {
- // Call the function to set beresp.ttl from score http-headers
- call extended_cache_control;
- }
- // Activate ESI processing if our backend has ESI activated
- // Do not activate ESI for binary objects and CSS/JS and SVG
- if (!bereq.url ~ "^[^?]*\.(css|js|svg|bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|mp[34]|pdf|png|rar|rtf|swf|tar|tgz|txt|wav|woff|woff2||xml|zip)(\?.*)?$") {
- set beresp.do_esi = true;
- }
- return (deliver);
- }
- sub vcl_deliver {
- set resp.http.X-Varnish-Host = server.hostname;
- if (obj.hits > 0) {
- set resp.http.X-Cache = "HIT";
- set resp.http.X-Cache-Hits = obj.hits;
- } else {
- set resp.http.X-Cache = "MISS";
- }
- // Report our grace status
- set resp.http.grace = req.http.grace;
- // Remove some headers: PHP version
- unset resp.http.X-Powered-By;
- // Remove some headers
- unset resp.http.Server;
- unset resp.http.Link;
- unset resp.http.X-Generator;
- unset resp.http.P3P;
- return (deliver);
- }
- sub vcl_purge {
- // Only handle actual PURGE HTTP methods, everything else is discarded
- if (req.method != "PURGE") {
- // restart request
- set req.http.X-Purge = "Yes";
- return(restart);
- }
- }
- sub vcl_synth {
- // Redirect handling
- if (resp.status == 720) {
- set resp.http.Location = resp.reason;
- set resp.status = 301;
- return (deliver);
- } elseif (resp.status == 721) {
- set resp.http.Location = resp.reason;
- set resp.status = 302;
- return (deliver);
- } elseif (resp.status == 722) {
- set resp.status = 404;
- } elseif (resp.status == 723) {
- set resp.status = 410;
- set resp.reason = "Gone";
- include "/etc/varnish/fuf-error.vcl";
- return(deliver);
- }
- // Deliver the error page if we cannot do anythiny else
- include "/etc/varnish/fuf-error.vcl";
- return (deliver);
- }
- sub vcl_fini {
- return (ok);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement