first commit

first commit

# Marker to tell the VCL compiler that this VCL has been adapted to the
# new 4.0 format.
vcl 4.0;

# Import VMod's
import std;
import directors;

# Default backend definition. Set this to point to your content server.
backend default {
  .host = "localhost";
  .port = "81";
  .connect_timeout = 600s;
  .first_byte_timeout = 600s;
  .between_bytes_timeout = 600s;
  .max_connections = 300;
}

# Only allow purging from specific IPs
acl purge {
  "localhost";
  "127.0.0.1";
  "::1";
}

acl internal {
  "127.0.0.0"/24;
  # For remote access, add your IP address here.
  # Ex: 162.xxx.xx.xx
}

# This function is used when a request is send by a HTTP client (Browser)
sub vcl_recv {
  # 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);

  # Check if request is allowed to invoke cache purge, Allow purging.
  if (req.method == "PURGE") {
    if (!client.ip ~ purge) {
      # purge is the ACL defined at the begining
      # Not from an allowed IP? Then die with an error.
      return (synth(405, "Forbidden - Not allowed."));
    }
    # If you got this stage (and didn't error out above), purge the cached result
    return (purge);
  }

  # Verify HTTP request methods
  # 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);
  }

  # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-websockets.html)
  if (req.http.Upgrade ~ "(?i)websocket") {
    return (pipe);
  }

  # Only cache GET or HEAD requests. This makes sure the POST requests are always passed.
  if (req.method != "GET" && req.method != "HEAD") {
    /* We only deal with GET and HEAD by default */
    return (pass);
  }

  #if (req.http.Authorization || req.http.Cookie) {
    /* Not cacheable by default */
    #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)=") {
    set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "");
    set req.url = regsuball(req.url, "\?(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([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, "_gat=[^;]+(; )?", "");
  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*", "");

  # Remove any Piiwik based cookies
  set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_pk_(ses|id)[\.a-z0-9]*)=[^;]*", ""); # removes Piwik cookies

  # Are there cookies left with only spaces or that are empty?
  if (req.http.cookie ~ "^\s*$") {
    unset req.http.cookie;
  }

  #if (req.http.Cache-Control ~ "(?i)no-cache") {
  #if (req.http.Cache-Control ~ "(?i)no-cache" && client.ip ~ editors) { # create the acl editors if you want to restrict the Ctrl-F5
  # http://varnish.projects.linpro.no/wiki/VCLExampleEnableForceRefresh
  # Ignore requests via proxy caches and badly behaved crawlers
  # like msnbot that send no-cache with every request.
  #  if (! (req.http.Via || req.http.User-Agent ~ "(?i)bot" || req.http.X-Purge)) {
      #set req.hash_always_miss = true; # Doesn't seems to refresh the object in the cache
  #    return(purge); # Couple this with restart in vcl_purge and X-Purge header to avoid loops
  #  }
  #}

  # Large static files are delivered directly to the end-user without
  # waiting for Varnish to fully read the file first.
  # Varnish 4 fully supports Streaming, so set do_stream in vcl_backend_response()
  if (req.url ~ "^[^?]*\.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av]|webm)(\?.*)?$") {
    unset req.http.Cookie;
    return (hash);
  }

  # Remove all cookies for static files
  # A valid discussion could be held on this line: do you really need to cache static files that don't cause load? Only if you have memory left.
  # Sure, there's disk I/O, but chances are your OS will already have these files in their buffers (thus memory).
  # Before you blindly enable this, have a read here: https://ma.ttias.be/stop-caching-static-files/
  if (req.url ~ "^[^?]*\.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|svg|js|less|pdf|png|rtf|swf|txt|woff|woff2|xml)(\?.*)?$") {
    unset req.http.Cookie;
    return (hash);
  }

  if (req.url ~ "^/phpmyadmin/.*$" || req.url ~ "^/phppgadmin/.*$" || req.url ~ "^/server-status.*$") {
    return(synth(403, "For security reasons, this URL is only accessible using localhost (127.0.0.1) as the hostname."));
  }

  # Send Surrogate-Capability headers to announce ESI support to backend
  set req.http.Surrogate-Capability = "key=ESI/1.0";

  if (req.http.Authorization) {
    # Not cacheable by default
    return (pass);
  }

  # Modify (remove) progress.js request parameters.
  if (req.url ~ "^/misc/progress\.js\?[0-9]+$") {
    set req.url = "/misc/progress.js";
  }

  # Modify HTTP X-Forwarded-For header.
  # This will replace Varnish's IP with actual client's.
  unset req.http.X-Forwarded-For;
  set   req.http.X-Forwarded-For = client.ip;

  # Do not cache these paths.
  if (req.url ~ "^/status\.php$" ||
      req.url ~ "^/update\.php$" ||
      req.url ~ "^/ooyala/ping$" ||
      req.url ~ "^/admin" ||
      req.url ~ "^/admin/.*$" ||
      req.url ~ "^/user" ||
      req.url ~ "^/user/.*$" ||
      req.url ~ "^/users/.*$" ||
      req.url ~ "^/info/.*$" ||
      req.url ~ "^/flag/.*$" ||
      req.url ~ "^/batch/.*$" ||
      req.url ~ "^.*/ajax/.*$" ||
      req.url ~ "^.*/ahah/.*$") {
    return (pass);
  }

  # Pipe these paths directly to Apache for streaming.
  if (req.url ~ "^/admin/content/backup_migrate/export") {
    return (pipe);
  }

  # Do not allow outside access to cron.php or install.php.
  if (req.url ~ "^/(cron|install)\.php$" && !client.ip ~ internal) {
    # Have Varnish throw the error directly.
    return(synth(404, "Page not found."));
    # Use a custom error page that you've defined in Drupal at the path "404".
    # set req.url = "/404";
  }

  return (hash);
}

sub vcl_pipe {
  # Called upon entering pipe mode.
  # In this mode, the request is passed on to the backend, and any further data from both the client
  # and backend is passed on unaltered until either end closes the connection. Basically, Varnish will
  # degrade into a simple TCP proxy, shuffling bytes back and forth. For a connection in pipe mode,
  # no other VCL subroutine will ever get called after vcl_pipe.

  # Note that only the first request to the backend will have
  # X-Forwarded-For set.  If you use X-Forwarded-For and want to
  # have it set for all requests, make sure to have:
  # set bereq.http.connection = "close";
  # here.  It is not set by default as it might break some broken web
  # applications, like IIS with NTLM authentication.

  # set bereq.http.Connection = "Close";

  # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-websockets.html)
  if (req.http.upgrade) {
    set bereq.http.upgrade = req.http.upgrade;
  }

  return (pipe);
}

sub vcl_pass {
  # Called upon entering pass mode. In this mode, the request is passed on to the backend, and the
  # backend's response is passed on to the client, but is not entered into the cache. Subsequent
  # requests submitted over the same client connection are handled normally.

  return (fetch);
}

# The data on which the hashing will take place
sub vcl_hash {
  # Called after vcl_recv to create a hash value for the request. This is used as a key
  # to look up the object in Varnish.

  hash_data(req.url);

  if (req.http.host) {
    hash_data(req.http.host);
  } else {
    hash_data(server.ip);
  }

  # If the client supports compression, keep that in a different cache
  if (req.http.Accept-Encoding) {
    hash_data(req.http.Accept-Encoding);
  }

  # hash cookies for requests that have them
  if (req.http.Cookie) {
    hash_data(req.http.Cookie);
  }

  return (lookup);
}

sub vcl_hit {
  # Called when a cache lookup is successful.

  if (obj.ttl >= 0s) {
    # A pure unadultered hit, deliver it
    return (deliver);
  }

  # https://www.varnish-cache.org/docs/trunk/users-guide/vcl-grace.html
  # When several clients are requesting the same page Varnish will send one request to the backend and place the others on hold while fetching one copy from the backend. In some products this is called request coalescing and Varnish does this automatically.
  # If you are serving thousands of hits per second the queue of waiting requests can get huge. There are two potential problems - one is a thundering herd problem - suddenly releasing a thousand threads to serve content might send the load sky high. Secondly - nobody likes to wait. To deal with this we can instruct Varnish to keep the objects in cache beyond their TTL and to serve the waiting requests somewhat stale content.

  # if (!std.healthy(req.backend_hint) && (obj.ttl + obj.grace > 0s)) {
  #   return (deliver);
  # } else {
  #   return (fetch);
  # }

  # We have no fresh fish. Lets look at the stale ones.
  if (std.healthy(req.backend_hint)) {
    # Backend is healthy. Limit age to 10s.
    if (obj.ttl + 10s > 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) {
      // Object is in grace, deliver it
      // Automatically triggers a background fetch
      // set req.http.grace = "full";
      return (deliver);
    } else {
      # no graced object.
      return (fetch);
    }
  }

  #if (req.method == "PURGE") {
  #  purge;
  #  return (synth(200, "Purged."));
  #}

  # fetch & deliver once we get the result
  return (fetch); # Dead code, keep as a safeguard
}

sub vcl_miss {
  # Called after a cache lookup if the requested document was not found in the cache. Its purpose
  # is to decide whether or not to attempt to retrieve the document from the backend, and which
  # backend to use.

  #if (req.method == "PURGE") {
  #  purge;
  #  return (synth(200, "Purged."));
  #}

  return (fetch);
}

# This function is used when a request is sent by our backend (Nginx server)
sub vcl_backend_response {
  # Called after the response headers has been successfully retrieved from the backend.

  # Remove some headers we never want to see
  unset beresp.http.Server;
  unset beresp.http.X-Powered-By;

  # Pause ESI request and remove Surrogate-Control header
  if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
    unset beresp.http.Surrogate-Control;
    set beresp.do_esi = true;
  }

  # Enable cache for all static files
  # The same argument as the static caches from above: monitor your cache size, if you get data nuked out of it, consider giving up the static file cache.
  # Before you blindly enable this, have a read here: https://ma.ttias.be/stop-caching-static-files/
  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|xml|zip|webm)(\?.*)?$") {
    unset beresp.http.set-cookie;
  }

  # Large static files are delivered directly to the end-user without
  # waiting for Varnish to fully read the file first.
  # Varnish 4 fully supports Streaming, so use streaming here to avoid locking.
  if (bereq.url ~ "^[^?]*\.(mp[34]|rar|tar|tgz|gz|wav|zip|bz2|xz|7z|avi|mov|ogm|mpe?g|mk[av]|webm)(\?.*)?$") {
    unset beresp.http.set-cookie;
    set beresp.do_stream = true;  # 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_gzip = false;   # Don't try to compress it for storage
  }

  # Sometimes, a 301 or 302 redirect formed via Apache's mod_rewrite can mess with the HTTP port that is being passed along.
  # This often happens with simple rewrite rules in a scenario where Varnish runs on :80 and Apache on :8080 on the same box.
  # A redirect can then often redirect the end-user to a URL on :8080, where it should be :80.
  # This may need finetuning on your setup.
  #
  # To prevent accidental replace, we only filter the 301/302 redirects for now.
  if (beresp.status == 301 || beresp.status == 302) {
    set beresp.http.Location = regsub(beresp.http.Location, ":[0-9]+", "");
  }

  # Set 2min cache if unset for static files
  if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*") {
    /*
    * Mark as "Hit-For-Pass" for the next 2 minutes
    */
    set beresp.ttl = 120s; # Important, you shouldn't rely on this, SET YOUR HEADERS in the backend
    set beresp.uncacheable = true;
    return (deliver);
  }

  # Allow stale content, in case the backend goes down.
  # make Varnish keep all objects for 6 hours beyond their TTL
  set beresp.grace = 6h;

	# Only allow cookies to be set if we're in admin area
#	if (beresp.http.Set-Cookie && bereq.url !~ "^/wp-(login|admin)") {
#        	unset beresp.http.Set-Cookie;
#   	}

	# don't cache response to posted requests or those with basic auth
#	if ( bereq.method == "POST" || bereq.http.Authorization ) {
#        	set beresp.uncacheable = true;
#		set beresp.ttl = 120s;
#		return (deliver);
#    	}

    	# don't cache search results
#	if ( bereq.url ~ "\?s=" ){
#		set beresp.uncacheable = true;
#                set beresp.ttl = 120s;
#                return (deliver);
#	}

	# only cache status ok
#	if ( beresp.status != 200 ) {
#		set beresp.uncacheable = true;
#                set beresp.ttl = 120s;
#                return (deliver);
#	}

	# A TTL of 24h
#	set beresp.ttl = 24h;
	# Define the default grace period to serve cached content
#	set beresp.grace = 30s;

  return (deliver);
}

# The routine when we deliver the HTTP request to the user
# Last chance to modify headers that are sent to the client
sub vcl_deliver {
  # Called before a cached object is delivered to the client.

  if (obj.hits > 0) { # Add debug header to see if it's a HIT/MISS and the number of hits, disable when not needed
    set resp.http.X-Cache = "HIT";
  } else {
    set resp.http.X-Cache = "MISS";
  }

  # Please note that obj.hits behaviour changed in 4.0, now it counts per objecthead, not per object
  # and obj.hits may not be reset in some cases where bans are in use. See bug 1492 for details.
  # So take hits with a grain of salt
  set resp.http.X-Cache-Hits = obj.hits;

  # Remove some headers: PHP version
  unset resp.http.X-Powered-By;

  # Remove some headers: Apache version & OS
  unset resp.http.Server;
  unset resp.http.X-Drupal-Cache;
  unset resp.http.X-Varnish;
  unset resp.http.Via;
  unset resp.http.Link;
  unset resp.http.X-Generator;

  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);
  }

  return (synth(200, "Purged"));
}

sub vcl_synth {
  if (resp.status == 720) {
    # We use this special error status 720 to force redirects with 301 (permanent) redirects
    # To use this, call the following from anywhere in vcl_recv: return (synth(720, "http://host/new.html"));
    set resp.http.Location = resp.reason;
    set resp.status = 301;
    return (deliver);
  } elseif (resp.status == 721) {
    # And we use error status 721 to force redirects with a 302 (temporary) redirect
    # To use this, call the following from anywhere in vcl_recv: return (synth(720, "http://host/new.html"));
    set resp.http.Location = resp.reason;
    set resp.status = 302;
    return (deliver);
  }

  return (deliver);
}

sub vcl_init {
  return (ok);
}

sub vcl_fini {
  # Called when VCL is discarded only after all requests have exited the VCL.
  # Typically used to clean up VMODs.

  return (ok);
}


added more comments to drupal_base.vcl

added more comments to drupal_base.vcl

error: pathspec 'varnish' did not match any file(s) known to git
error: pathspec '3' did not match any file(s) known to git
error: pathspec 'vcls/drupal_base.vcl' did not match any file(s) known to git


Add VCL snippet for force TLS that executes before all the other snippets

# Force SSL immediately to avoid magento module VCL stripping off
# google campaign ids like gclid
  if (!req.http.Fastly-SSL) {
    error 972 "Force SSL";
  }

error: pathspec 'etc/vcl_snippets_force_tls/recv.vcl' did not match any file(s) known to git


Add Varnish VCL test-file

Add Varnish VCL test-file

# This is the VCL configuration Varnish will automatically append to your VCL
# file during compilation/loading. See the vcl(7) man page for details on syntax
# and semantics.
# New users is recommended to use the example.vcl file as a starting point.

vcl 4.0;

backend foo { .host = "192.168.1.1"; }

probe blatti { .url = "foo"; }

sub vcl_recv {
    if (req.method == "PRI") {
	/* We do not support SPDY or HTTP/2.0 */
	return (synth(405));
    }
    if (req.method != "GET" &&
      req.method != "HEAD" &&
      req.method != "PUT" &&
      req.method != "POST" &&
      req.method != "TRACE" &&
      req.method != "OPTIONS" &&
      req.method != "DELETE") {
        /* Non-RFC2616 or CONNECT which is weird. */
        return (pipe);
    }

    if (req.method != "GET" && req.method != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }
    if (req.http.Authorization || req.http.Cookie) {
        /* Not cacheable by default */
        return (pass);
    }
    return (hash);
}

sub vcl_pipe {
    # By default Connection: close is set on all piped requests, to stop
    # connection reuse from sending future requests directly to the
    # (potentially) wrong backend. If you do want this to happen, you can undo
    # it here.
    # unset bereq.http.connection;
    return (pipe);
}

sub vcl_pass {
    return (fetch);
}

sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    return (lookup);
}

sub vcl_purge {
    return (synth(200, "Purged"));
}

sub vcl_hit {
    if (obj.ttl >= 0s) {
        // A pure unadultered hit, deliver it
        return (deliver);
    }
    if (obj.ttl + obj.grace > 0s) {
        // Object is in grace, deliver it
        // Automatically triggers a background fetch
        return (deliver);
    }
    // fetch & deliver once we get the result
    return (miss);
}

sub vcl_miss {
    return (fetch);
}

sub vcl_deliver {
    return (deliver);
}

/*
 * We can come here "invisibly" with the following errors: 413, 417 & 503
 */
sub vcl_synth {
    set resp.http.Content-Type = "text/html; charset=utf-8";
    set resp.http.Retry-After = "5";
    synthetic( {"<!DOCTYPE html>

    <title>"} + resp.status + " " + resp.reason + {"</title>

Error "} + resp.status + " " + resp.reason + {"

"} + resp.reason + {"

Guru Meditation:

XID: "} + req.xid + {"

Varnish cache server

"} );
    return (deliver);
}

#######################################################################
# Backend Fetch

sub vcl_backend_fetch {
    return (fetch);
}

sub vcl_backend_response {
    if (beresp.ttl <= 0s ||
      beresp.http.Set-Cookie ||
      beresp.http.Surrogate-control ~ "no-store" ||
      (!beresp.http.Surrogate-Control &&
        beresp.http.Cache-Control ~ "no-cache|no-store|private") ||
      beresp.http.Vary == "*") {
        /*
        * Mark as "Hit-For-Pass" for the next 2 minutes
        */
        set beresp.ttl = 120s;
        set beresp.uncacheable = true;
    }
    return (deliver);
}

sub vcl_backend_error {
    set beresp.http.Content-Type = "text/html; charset=utf-8";
    set beresp.http.Retry-After = "5";
    synthetic( {"<!DOCTYPE html>

    <title>"} + beresp.status + " " + beresp.reason + {"</title>

Error "} + beresp.status + " " + beresp.reason + {"

"} + beresp.reason + {"

Guru Meditation:

XID: "} + bereq.xid + {"

Varnish cache server

"} );
    return (deliver);
}

#######################################################################
# Housekeeping

sub vcl_init {
}

sub vcl_fini {
    return (ok);
}

error: pathspec 'tests/examplefiles/varnish.vcl' did not match any file(s) known to git


Add a trivial example showing off the vmod API.

#
# A trivial example to demonstrate how to use this vmod
#

import redis;

backend be1 {
  .host = "192.168.0.1";
  .port = "80";
}

sub vcl_recv {
  #
  # redis.call is a procedure, it will send the command to redis and ignore
  # the response. If the command errors out, it will be logged but the VCL
  # will not know.
  #
  redis.send("LPUSH client " + client.ip);

  #
  # redis.call is a function that sends the command to redis and return the
  # return value.
  #
  set req.http.x-redis = redis.call("LTRIM client 0 99");
}

error: pathspec 'examples/example.vcl' did not match any file(s) known to git


add default varnish config

add default varnish config

fatal: unable to access 'https://github.com/majestrate/nntpchan.git/': The requested URL returned error: 403


Update varnish vcl

Update varnish vcl

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/a25kk/lra.git/'


Create default.vcl

Create default.vcl

fatal: unable to access 'https://github.com/babim/docker-varnish.git/': The requested URL returned error: 403


Check in varnish config

Check in varnish config

sub vcl_recv {
#FASTLY recv

  if (req.request != "HEAD" && req.request != "GET" && req.request != "FASTLYPURGE") {
      return(pass);
  }

  if (req.http.cookie ~ "logged_in" && req.url !~ "^/assets/") {
      set req.hash_always_miss = true;
      return(pass);
  }

  if (req.url !~ "^/(ahoy)/") {
      unset req.http.Cookie;
  }

  return(lookup);
}

sub vcl_fetch {
  if (req.http.cookie !~ "logged_in" && req.url !~ "^/(login)|(confirmation/new)|(unlock/new)|(password/new)|(ahoy/)") {
      unset beresp.http.Set-Cookie;
  }

#FASTLY fetch

  if ((beresp.status == 500 || beresp.status == 503) && req.restarts < 1 && (req.request == "GET" || req.request == "HEAD")) {
      restart;
  }

  if (req.restarts > 0) {
      set beresp.http.Fastly-Restarts = req.restarts;
  }

  if (beresp.http.Set-Cookie) {
      set req.http.Fastly-Cachetype = "SETCOOKIE";
      return(pass);
  }

  if (beresp.http.Cache-Control ~ "private") {
      set req.http.Fastly-Cachetype = "PRIVATE";
      return(pass);
  }

  if (beresp.status == 500 || beresp.status == 503) {
      set req.http.Fastly-Cachetype = "ERROR";
      set beresp.ttl = 1s;
      set beresp.grace = 5s;
      return(deliver);
  }

  if (beresp.http.Expires || beresp.http.Surrogate-Control ~ "max-age" || beresp.http.Cache-Control ~ "(s-maxage|max-age)") {
      # keep the ttl here
  } else {
      # apply the default ttl
      set beresp.ttl = 3600s;
  }

  return(deliver);
}

sub vcl_hit {
#FASTLY hit

  if (!obj.cacheable) {
      return(pass);
  }
  return(deliver);
}

sub vcl_miss {
#FASTLY miss
  return(fetch);
}

sub vcl_deliver {
#FASTLY deliver
  return(deliver);
}

sub vcl_error {
#FASTLY error
}

sub vcl_pass {
#FASTLY pass
}

sub vcl_log {
#FASTLY log
}

error: pathspec 'varnish.vcl' did not match any file(s) known to git


Added example vcl to use in front of zope+plone (this could perhaps go in a contrib/ directory instead)

git-svn-id: 2c9807fa3ff65b17195bd55dc8a6c4261e10127b@1427 d4fa192b-c00b-0410-8231-f00ffab90ce4

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/alarky/varnish-cache-doc-ja.git/'


We have to turn off Accept-Encoding in pass as well since response may contain ESIs

    # Deactivate gzip on origin
    unset bereq.http.Accept-Encoding;

error: pathspec 'etc/vcl_snippets/pass.vcl' did not match any file(s) known to git


Regex set for doing device detection

Regex set for doing device detection


Add Snippet for Basic Auth

Add Snippet for Basic Auth

if (obj.status == 971) {
        set obj.http.Content-Type = "text/html; charset=utf-8";
        set obj.http.WWW-Authenticate = "Basic realm=Secured";
        set obj.status = 401;
        synthetic {"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">

        <TITLE>Error</TITLE>
        <META HTTP-EQUIV='Content-Type' CONTENT='text/html;'>

401 Unauthorized

        "};
        return (deliver);
    }

error: pathspec 'etc/vcl_snippets_basic_auth/error.vcl' did not match any file(s) known to git


Documentation for vcl_pipe and connection: close

Note in the default VCL that connection: close might be wanted.

git-svn-id: 2c9807fa3ff65b17195bd55dc8a6c4261e10127b@3852 d4fa192b-c00b-0410-8231-f00ffab90ce4


Added "default.vcl" for varnish.

Added "default.vcl" for varnish.

## /etc/varnish/default.vcl / 20150504
## Marianne Spiller <github@spiller.me>
## v 3.0.5-2

backend default {
  .host = "127.0.0.1";
  .port = "8080";
  .connect_timeout = 600s;
  .first_byte_timeout = 600s;
  .between_bytes_timeout = 600s;
  .max_connections = 800;
 }

# Import Varnish Standard Module so I can serve custom error pages
import std;

# Set who is allowed to purge
acl purge {
  "localhost";
  "127.0.0.1";
  "92.222.22.102";
}

#----------------------------------------------------------------------
# vcl_recv
#
sub vcl_recv {
  # Ignore all "POST" requests - nothing cacheable there
   if (req.request == "POST") {
      return (pass);
  }

  # In the event of a backend overload (HA!), serve stale objects for up to two minutes
  set req.grace = 2m;

  #--------------------------------------------------------------------
  # Ignore these hosts
  # Great when I'm working on the blog
  ##
  ##	 if (req.http.host ~ "spiller.me") {
  ##	    return(pass);
  ##	  }
  ##
  ##	  if (req.http.host ~ "www.spiller.me") {
  ##	    return(pass);
  ##	  }

  # No caching of the Wordpress "preview" sites
  if (req.url ~ "preview=true") {
	return(pass);
  }

  # Use the "purge" ACL we set earlier to allow purging from the LAN
  if (req.request == "PURGE") {
	if (!client.ip ~ purge) {
		error 405 "Not allowed.";
	}
	return (lookup);
  }

  # Static Elements should always go to the cache...
  if (req.url ~ "(?i)\.(png|gif|jpeg|jpg|ico|swf|css|js|html|htm|woff|ttf|eot|svg)(\?[a-zA-Z0-9\=\.\-]+)?$") {
	remove req.http.Cookie;
  }

  # I throw away *all* cookies from *both* Wordpress installations - except wp-admin
  if (req.http.host ~ "www.spiller.me|www.urban-exploring.eu") {
	if (req.url ~ "wp-(login|admin)") {
            return (pass);
	}

	  # Tell Varnish to use X-Forwarded-For, to set "real" IP addresses on all requests
	remove req.http.X-Forwarded-For;
	set req.http.X-Forwarded-For = req.http.rlnclientipaddr;
    }
}

#----------------------------------------------------------------------
# vcl_pass
#
sub vcl_pass {
  set bereq.http.connection = "close";
  if (req.http.X-Forwarded-For) {
	set bereq.http.X-Forwarded-For = req.http.X-Forwarded-For;
  }
  else {
	set bereq.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
  }
}

#----------------------------------------------------------------------
# vcl_pipe
#
sub vcl_pipe {
  set bereq.http.connection = "close";
  if (req.http.X-Forwarded-For) {
	set bereq.http.X-Forwarded-For = req.http.X-Forwarded-For;
  }
  else {
	set bereq.http.X-Forwarded-For = regsub(client.ip, ":.*", "");
  }
}

#----------------------------------------------------------------------
# vcl_pipe
#
sub vcl_fetch {
  set beresp.grace = 2m;
  if (req.http.host ~ "www.spiller.me") {
	if (!(req.url ~ "wp-(login|admin)")) {
	  remove beresp.http.set-cookie;
        }
  }

  # Strip cookies before static items are inserted into cache.
  if (req.url ~ "\.(png|gif|jpg|swf|css|js|ico|html|htm|woff|eof|ttf|svg)$") {
	remove beresp.http.set-cookie;
  }

  # Adjusting caching:
  # - cacheable objects stay for 24 hours
  # - objects declared as uncacheable stay for 60 seconds
  # - exception for the photo blog: its content stays for 5 days
  if (req.http.host ~ "www.urban-exploring.eu") {
	set beresp.ttl = 5d;
  }
  else {
	if (beresp.ttl < 24h) {
	  if (beresp.http.Cache-Control ~ "(private|no-cache|no-store)") {
	    set beresp.ttl = 60s;
	  }
	  else {
	    set beresp.ttl = 24h;
	  }
	}
  }
}

#----------------------------------------------------------------------
# vcl_hit
#
sub vcl_hit {
  if (req.request == "PURGE") {
	purge;
	error 200 "Purged.";
  }
}

#----------------------------------------------------------------------
# vcl_miss
#
sub vcl_miss {
  if (req.request == "PURGE") {
	purge;
	error 200 "Purged.";
  }
}

#----------------------------------------------------------------------
# vcl_error
#
sub vcl_error {
  set obj.http.Content-Type = "text/html; charset=utf-8";
  set obj.http.MyError = std.fileread("/var/www/spillerme/varnisherr.html");
  synthetic obj.http.MyError;
  return(deliver);
}

#----------------------------------------------------------------------
# vcl_deliver
#
sub vcl_deliver {
  # Display hit/miss info
  if (obj.hits > 0) {
	set resp.http.X-Cache = "HIT";
  }
  else {
	set resp.http.X-Cache = "MISS";
  }

  # Remove the Varnish header
  remove resp.http.X-Varnish;

  # Display my header
  set resp.http.X-sysadmama-is-awesome = "YAY";

  # Remove custom error header
  remove resp.http.MyError;
  return (deliver);
}

error: pathspec 'varnish/default.vcl' did not match any file(s) known to git


add vcl example

add vcl example

# This is a the VCL configuration file for 3scale's varnish plugin.
#
# Default backend definition.  Set this to point to the 3scale's
# backend.
#
# set the beresp.ttl in vcl_fetch to have a default global TTL
# you can define custom TTL via regular expresions
#

backend default {
	.host = "su1.3scale.net";
    	.port = "80";
}

import std;
import threescale;

sub vcl_recv {

	unset req.http.cookie;
	set req.http.host = "su1.3scale.net";
	set req.grace = 1s;

	if (req.request != "GET" && req.request != "HEAD") {
      		return(pass);
    	}
    	else {
      		## GET or HEAD requests
      		return(lookup);
    	}

}

# the hash of the request needs to be customized to remove all fields that are not
# associated to the user

sub vcl_hash {

	## remove no_body
	set req.http.X-url-tmp = regsub(req.url,"[&?]no_body.[^&]*","");
	## remove object_id
	set req.http.X-url-tmp = regsub(req.http.X-url-tmp,"[&?]object.[^&]*","");
	## remove object
	set req.http.X-url-tmp = regsub(req.http.X-url-tmp,"[&?]object_id.[^&]*","");

	hash_data(req.http.X-url-tmp);
	unset req.http.X-url-tmp;
     	return (hash);

}

#A HIT means that the request to your local cache of 3scale is still fresh and the
#response will not have to fetch the data from the remote 3scale backend.
#vmod_3scale plugin will send a replica of the call asynchronously to 3scale's remote
#backend on its own

sub vcl_hit {
	if (threescale.request_no_response("su1.3scale.net","80",req.url)==0) {}
}

sub vcl_fetch {
	set beresp.ttl = 30s;
}

error: pathspec 'vcl/default_3scale_simple.vcl' did not match any file(s) known to git


note added for the convenience of restarting POST request on backend failures


moving vlc_error subroutine outside

moving vlc_error subroutine outside

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/kkwoker/ansible-varnish.git/'


Boilerplate

Boilerplate

sub vcl_recv {
#FASTLY recv

	if (req.request != "HEAD" && req.request != "GET" && req.request != "FASTLYPURGE") {
		return(pass);
	}

	return(lookup);
}

sub vcl_fetch {
#FASTLY fetch

	if ((beresp.status == 500 || beresp.status == 503) && req.restarts < 1 && (req.request == "GET" || req.request == "HEAD")) {
		restart;
	}

	if(req.restarts > 0 ) {
		set beresp.http.Fastly-Restarts = req.restarts;
	}

	if (beresp.http.Set-Cookie) {
		set req.http.Fastly-Cachetype = "SETCOOKIE";
		return (pass);
	}

	if (beresp.http.Cache-Control ~ "private") {
		set req.http.Fastly-Cachetype = "PRIVATE";
		return (pass);
	}

	if (beresp.status == 500 || beresp.status == 503) {
		set req.http.Fastly-Cachetype = "ERROR";
		set beresp.ttl = 1s;
		set beresp.grace = 5s;
		return (deliver);
	}

	if (beresp.http.Expires || beresp.http.Surrogate-Control ~ "max-age" || beresp.http.Cache-Control ~"(s-maxage|max-age)") {
# keep the ttl here
	} else {
# apply the default ttl
		set beresp.ttl = 3600s;
	}

	return(deliver);
}

sub vcl_hit {
#FASTLY hit

	if (!obj.cacheable) {
		return(pass);
	}
	return(deliver);
}

sub vcl_miss {
#FASTLY miss
	return(fetch);
}

sub vcl_deliver {
#FASTLY deliver
	return(deliver);
}

sub vcl_error {
#FASTLY error
}

sub vcl_pass {
#FASTLY pass
}

error: pathspec 'oauth_sig_check.vcl' did not match any file(s) known to git


Regression testcase for #433

Regression testcase for #433

git-svn-id: 7d4b18ab7d176792635d6a7a77dd8cbbea8e8daa@3576 d4fa192b-c00b-0410-8231-f00ffab90ce4

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/wikimedia/operations-debs-varnish.git/'


add varnish configuration

add varnish configuration

fatal: unable to access 'https://github.com/KhanovaSkola/khanovaskola-v3.git/': The requested URL returned error: 403


Add vcl sample from previous commit.

Add vcl sample from previous commit.

/*
  This is the minimal VCL configuration required for passing the Apache
  mod_pagespeed system tests. To install varnish and start the varnish
  server at the right port, do the following:
  1) sudo apt-get install varnish
  2) sudo vim /etc/default/varnish and put in the following lines at the
     bottom of the file:
  DAEMON_OPTS="-a :8020 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s file,/var/lib/varnish/$INSTANCE/varnish_storage.bin,1G"
  3) sudo cp /path/to/install/sample_conf.vcl /etc/varnish/default.vcl
  4) sudo service varnish restart
*/

backend default {
  # Location of Apache mod_pagespeed server.
  .host = "127.0.0.1";
  .port = "8080";
}

acl purge {
  # Purge requests are only allowed from localhost.
  "localhost";
  "127.0.0.1";
}

sub vcl_recv {
  if (req.request == "PURGE") {
    if (!client.ip ~ purge) {
      error 405 "Not allowed.";
    }
    return (lookup);
  }
}

sub vcl_hit {
  if (req.request == "PURGE") {
    purge;
    error 200 "Purged.";
  }
}

sub vcl_miss {
  if (req.request == "PURGE") {
     purge;
     error 200 "Purged.";
  }
}

sub vcl_fetch {
   # Cache everything for 30s.
   set beresp.ttl   = 30s;
   set beresp.grace = 30s;
   set beresp.http.X-Cacheable = "YES";
   return (deliver);
}

error: pathspec 'src/install/sample_conf.vcl' did not match any file(s) known to git


Minor updates to VCL.

Minor updates to VCL.

vcl 4.0;

import directors;
import std;

###
# Varnish Documentation
#   https://www.varnish-cache.org/docs/trunk/users-guide/vcl-built-in-subs.html
#   https://www.varnish-cache.org/docs/trunk/reference/vcl.html
##

{% for backend in varnish_backend_hosts %}
backend application_{{ loop.index }} {
  .host = "{{ backend }}";
  .port = "{{ varnish_backend_port }}";
{% if varnish_health_checks_enabled %}
  .probe = {
    .url = "{{ varnish_health_check_url }}";
    .interval = {{ varnish_health_check_interval }};
    .timeout  = {{ varnish_health_check_timeout }};
    .window = {{ varnish_health_check_window }};
    .threshold = {{ varnish_health_check_threshold }};
  }
{% endif %}
}
{% endfor %}

###
# vcl_init
#   Called when VCL is loaded, before any requests pass through it. Typically used to initialize VMODs.
###
# The vcl_init subroutine may terminate with calling return() with one of the following keywords:
#
# ok
#   Normal return, VCL continues loading.
##

sub vcl_init {
  new application = directors.round_robin();
{% for backend in varnish_backend_hosts %}
  application.add_backend(application_{{ loop.index }});
{% endfor %}
}

###
# vcl_recv
#   Called at the beginning of a request, after the complete request has been received and parsed.
#   Its purpose is to decide whether or not to serve the request, how to do it, and, if applicable, which backend to use.
#   It is also used to modify the request
###
# The vcl_recv subroutine may terminate with calling return() on one of the following keywords:
#
# synth(status code, reason)
#   Return a synthetic object with the specified status code to the client and abandon the request.
# pass
#   Switch to pass mode. Control will eventually pass to vcl_pass.
# pipe
#   Switch to pipe mode. Control will eventually pass to vcl_pipe.
# hash
#   Continue processing the object as a potential candidate for caching. Passes the control over to vcl_hash.
# purge
#   Purge the object and it's variants. Control passes through vcl_hash to vcl_purge.
#

sub vcl_recv {
  set req.backend_hint = application.backend();

  ###
  # Avoid processing uncacheable requests
  ###

  if (req.http.Authorization) {
    set req.http.X-Passthrough-Reason = "No Caching Authenticated Content";
    return (pass);
  }

{% if varnish_uri_blacklist_enabled %}
  if ((req.url ~ "{{ varnish_uri_blacklist_regexp }}")) {
    set req.http.X-Passthrough-Reason = "Path in Blacklist";
    return(pass);
  }
{% endif %}

{% if varnish_diagnostic_headers_forwarded_for %}
  ###
  # Inject X-Forwarded-For headers, but only once.
  ###

  if (req.restarts == 0) {
    if (req.http.X-Forwarded-For) {
      set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
    } else {
      set req.http.X-Forwarded-For = client.ip;
    }
  }
{% endif %}

{% if varnish_header_sanitization_enabled %}
  ###
  # Header Sanitization
  ###

{% if varnish_header_sanitization_discard_host_port %}
  set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
{% endif %}

{% if varnish_header_sanitization_normalize_accept_encoding %}
  if (req.http.Accept-Encoding) {
    if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
      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 {
      unset req.http.Accept-Encoding;
    }
  }
{% endif %}

{% endif %}

{% if varnish_cookie_sanitization_enabled %}
  ###
  # Cookie Sanitization
  ###

{% for cookie in varnish_cookie_sanitization_blacklist %}
  set req.http.Cookie = regsuball(req.http.Cookie, "{{ cookie }}=[^;]+(; )?", "");
{% endfor %}

  ### General Cleanup
  set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
  if (req.http.cookie ~ "^\s*$") {
      unset req.http.cookie;
  }
{% endif %}

{% if varnish_uri_sanitization_enabled %}
  ###
  # URI Sanitization
  ###

  if (req.url ~ "(\?|&){{ varnish_uri_sanitization_regexp }}=") {
    set req.url = regsuball(req.url, "&{{ varnish_uri_sanitization_regexp }}=([A-z0-9_\-\.%25]+)", "");
    set req.url = regsuball(req.url, "\?{{ varnish_uri_sanitization_regexp }}=([A-z0-9_\-\.%25]+)", "?");
    set req.url = regsub(req.url, "\?&", "?");
    set req.url = regsub(req.url, "\?$", "");
  }
  if (req.url ~ "\#") {
    set req.url = regsub(req.url, "\#.*$", "");
  }
{% endif %}

{% if varnish_workaround_telusdotcom_browser_profile %}
  ###
  # Workaround and Diagnostics for BrowserProfile and Language/Region Detection on TELUS.com
  ###

  if (req.http.Cookie ~ "BrowserProfile") {
    set req.http.X-BrowserProfile = regsuball(req.http.Cookie, "(.*)BrowserProfile=([^;]*)(.*)", "\2");
    if (req.http.X-BrowserProfile ~ "language") {
      set req.http.X-Language = std.tolower(regsuball(req.http.X-BrowserProfile, "(.*)language\\.:\\.([^\\]*)(.*)", "\2"));
      set req.http.X-Language-Found = "YES:BrowserProfile";
    }
    if (req.http.X-BrowserProfile ~ "region") {
      set req.http.X-Region = std.tolower(regsuball(regsuball(req.http.X-BrowserProfile, "geo\\.\:{(.*)\}", ""), "(.*)region\\.:\\.([^\\]*)(.*)", "\2"));
      set req.http.X-Region-Found = "YES:BrowserProfile";
    }
    if (req.http.X-BrowserProfile ~ "geo") {
      set req.http.X-BrowserProfile-Geolocation = regsuball(req.http.X-BrowserProfile, "(.*)geo..:\\.([^\\]*)(.*)", "\2");
      set req.http.X-BrowserProfile-Geolocation-Found = "YES";

      if (req.http.X-BrowserProfile-Geolocation ~ "country") {
        set req.http.X-BrowserProfile-Geolocation-Country = regsuball(req.http.X-BrowserProfile-Geolocation, "(.*)country\\.:\\.([^\\]*)(.*)", "\2");
      }
      if (req.http.X-BrowserProfile-Geolocation ~ "region") {
        set req.http.X-BrowserProfile-Geolocation-Region = regsuball(req.http.X-BrowserProfile-Geolocation, "(.*)region\\.:\\.([^\\]*)(.*)", "\2");
      }
      if (req.http.X-BrowserProfile-Geolocation ~ "city") {
        set req.http.X-BrowserProfile-Geolocation-City = regsuball(req.http.X-BrowserProfile-Geolocation, "(.*)city\\.:\\.([^\\]*)(.*)", "\2");
      }
      if (req.http.X-BrowserProfile-Geolocation ~ "isp") {
        set req.http.X-BrowserProfile-Geolocation-ISP = regsuball(req.http.X-BrowserProfile-Geolocation, "(.*)isp\\.:\\.([^\\]*)(.*)", "\2");
      }
    } else {
      set req.http.X-BrowserProfile-Geolocation-Found = "NO";
    }
  }

  if (!req.http.X-Language) {
    if (req.http.Cookie ~ "lang=") {
      set req.http.X-Language = std.tolower(regsuball(req.http.Cookie, "(.*)lang=([^;]*)(.*)", "\2"));
      set req.http.X-Language-Found = "YES:lang";
    } else {
      set req.http.X-Language = "en";
      set req.http.X-Language-Found = "NO";
    }
  }

  if (!req.http.X-Region) {
    if (req.http.Cookie ~ "prov=") {
      set req.http.X-Region = std.tolower(regsuball(req.http.Cookie, "(.*)prov=([^;]*)(.*)", "\2"));
      set req.http.X-Region-Found = "YES:prov";
    } else {
      set req.http.X-Region = "bc";
      set req.http.X-Region-Found = "NO";
    }
  }

  if (req.url ~ "/(en|fr)/") {
    if (req.url ~ "/en/" && req.http.X-Language != "en") {
      set req.http.X-Passthrough-Reason = "Unaligned Language (Path: /en/) vs (Cookie: " + req.http.X-Language + ")";
      return(pass);
    }
    if (req.url ~ "/fr/" && req.http.X-Language != "fr") {
      set req.http.X-Passthrough-Reason = "Unaligned Language (Path: /fr/) vs (Cookie: " + req.http.X-Language + ")";
      return(pass);
    }
  } else {
      set req.http.X-Passthrough-Reason = "Not Set in Path (Language)";
    return(pass);
  }

  if (req.url ~ "/(ab|bc|mb|nb|nl|ns|nt|nu|on|pe|qc|sk|yt)/") {
    {% for province in ['ab', 'bc', 'mb', 'nb', 'nl', 'ns', 'nt', 'nu', 'on', 'pe', 'qc', 'sk', 'yt'] %}
    if (req.url ~ "/{{ province }}/" && req.http.X-Region != "{{ province }}") {
      set req.http.X-Passthrough-Reason = "Unaligned Region (Path: /{{ province }}/) vs (Cookie: " + req.http.X-Region + ")";
      return(pass);
    }
    {% endfor %}
  } else {
      set req.http.X-Passthrough-Reason = "Not Set in Path (Province)";
    return(pass);
  }
{% endif %}

{% if varnish_cookie_sanitization_discard_from_client %}
    unset req.http.Cookie;
{% endif %}
}

###
# vcl_hit
#   Called when a cache lookup is successful.
###
# The vcl_hit subroutine may terminate with calling return() with one of the following keywords:
#
# restart
#   Restart the transaction. Increases the restart counter. If the number of restarts is higher than max_restarts Varnish emits a guru meditation error.
# deliver
#   Deliver the object. Control passes to vcl_deliver.
# synth(status code, reason)
#   Return the specified status code to the client and abandon the request.
###

sub vcl_hit {
  if (obj.ttl > 0s) {
    return (deliver);
  }
{% if varnish_health_checks_enabled %}
  if (!std.healthy(req.backend_hint) && (obj.ttl + obj.grace > 0s)) {
    return (deliver);
  } else {
    return (fetch);
  }
{% else %}
  if (obj.ttl + obj.grace > 0s) {
     return (deliver);
  }

  return (fetch);
{% endif %}
}

###
# vcl_backend_response
#   Called after the response headers has been successfully retrieved from the backend.
###
# The vcl_backend_response subroutine may terminate with calling return() with one of the following keywords:
#
# deliver
#   Possibly insert the object into the cache, then deliver it to the Control will eventually pass to vcl_deliver.
# abandon
#   Abandon the backend request and generates an error.
# retry
#   Retry the backend transaction. Increases the retries counter. If the number of retries is higher than max_retries Varnish emits a guru meditation error.
###

sub vcl_backend_response {
{% if varnish_workaround_telusdotcom_browser_profile %}
  if (bereq.http.X-Language) {
    set beresp.http.X-Language = bereq.http.X-Language;
#    if (bereq.http.X-Language-Found) {
#      set beresp.http.X-Language-Found = bereq.http.X-Language-Found;
#    }
  }
  if (bereq.http.X-Region) {
    set beresp.http.X-Region = bereq.http.X-Region;
#    if (bereq.http.X-Region-Found) {
#      set beresp.http.X-Region-Found = bereq.http.X-Region-Found;
#    }
  }
{% endif %}

{% if varnish_uri_blacklist_enabled %}
  if (bereq.url ~ "{{ varnish_uri_blacklist_regexp }}") {
    set beresp.http.X-Cacheable = "NO:Path in Blacklist";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } else {
    if (bereq.http.X-Passthrough-Reason) {
{% if varnish_diagnostic_headers_passthrough_reason %}
      set beresp.http.X-Passthrough-Reason = bereq.http.X-Passthrough-Reason;
{% endif %}
      return(deliver);
    }
  }
{% else %}
{% if varnish_cookie_sanitization_discard_from_server %}
  unset beresp.http.Set-Cookie;
{% endif %}
{% endif %}

{% if varnish_diagnostic_headers_enabled %}
  if (bereq.http.Cookie) {
    set beresp.http.X-Cacheable = "NO:Cookie in Request";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } elsif (beresp.http.Set-Cookie) {
    set beresp.http.X-Cacheable = "NO:Set-Cookie in Response";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } elsif (beresp.http.Cache-Control ~ "private") {
    set beresp.http.X-Cacheable = "NO:Cache-Control=private";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } elsif (beresp.http.X-No-Cache) {
    set beresp.http.X-Cacheable = "NO:X-No-Cache";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } elsif (beresp.ttl <= 0s) {
    set beresp.http.X-Cacheable = "NO:Not Cacheable";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } else {
    set beresp.http.X-Cacheable = "YES";
  }
{% endif %}

  set beresp.grace = {{ varnish_grace_period }};
}

###
# vcl_deliver
#   Called before a cached object is delivered to the client.
###
# The vcl_deliver subroutine may terminate with calling return() with one of the following keywords:
#
# deliver
#   Deliver the object to the client.
# restart
#   Restart the transaction. Increases the restart counter. If the number of restarts is higher than max_restarts Varnish emits a guru meditation error.
###

sub vcl_deliver {
  if (obj.hits > 0) {
    set resp.http.X-Cache = "HIT";
  } else {
    set resp.http.X-Cache = "MISS";
  }
}

vcl 4.0;

import directors;
import std;

###
# Varnish Documentation
#   https://www.varnish-cache.org/docs/trunk/users-guide/vcl-built-in-subs.html
#   https://www.varnish-cache.org/docs/trunk/reference/vcl.html
##

{% for backend in varnish_backend_hosts %}
backend application_{{ loop.index }} {
  .host = "{{ backend }}";
  .port = "{{ varnish_backend_port }}";
{% if varnish_health_checks_enabled %}
  .probe = {
    .url = "{{ varnish_health_check_url }}";
    .interval = {{ varnish_health_check_interval }};
    .timeout  = {{ varnish_health_check_timeout }};
    .window = {{ varnish_health_check_window }};
    .threshold = {{ varnish_health_check_threshold }};
  }
{% endif %}
}
{% endfor %}

###
# vcl_init
#   Called when VCL is loaded, before any requests pass through it. Typically used to initialize VMODs.
###
# The vcl_init subroutine may terminate with calling return() with one of the following keywords:
#
# ok
#   Normal return, VCL continues loading.
##

sub vcl_init {
  new application = directors.round_robin();
{% for backend in varnish_backend_hosts %}
  application.add_backend(application_{{ loop.index }});
{% endfor %}
}

###
# vcl_recv
#   Called at the beginning of a request, after the complete request has been received and parsed.
#   Its purpose is to decide whether or not to serve the request, how to do it, and, if applicable, which backend to use.
#   It is also used to modify the request
###
# The vcl_recv subroutine may terminate with calling return() on one of the following keywords:
#
# synth(status code, reason)
#   Return a synthetic object with the specified status code to the client and abandon the request.
# pass
#   Switch to pass mode. Control will eventually pass to vcl_pass.
# pipe
#   Switch to pipe mode. Control will eventually pass to vcl_pipe.
# hash
#   Continue processing the object as a potential candidate for caching. Passes the control over to vcl_hash.
# purge
#   Purge the object and it's variants. Control passes through vcl_hash to vcl_purge.
#

sub vcl_recv {
  set req.backend_hint = application.backend();

  ###
  # Avoid processing uncacheable requests
  ###

  if (req.http.Authorization) {
    return (pass);
  }

{% if varnish_uri_blacklist_enabled %}
  if ((req.url ~ "{{ varnish_uri_blacklist_regexp }}")) {
    set req.http.X-Passthrough-Reason = "Path in Blacklist";
    return(pass);
  }
{% endif %}

  ###
  # Inject X-Forwarded-For headers, but only once.
  ###

  if (req.restarts == 0) {
    if (req.http.X-Forwarded-For) {
      set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
    } else {
      set req.http.X-Forwarded-For = client.ip;
    }
  }

{% if varnish_header_sanitization_enabled %}
  ###
  # Header Sanitization
  ###

{% if varnish_header_sanitization_discard_host_port %}
  set req.http.Host = regsub(req.http.Host, ":[0-9]+", "");
{% endif %}

  if (req.http.Accept-Encoding) {
    if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
      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 {
      unset req.http.Accept-Encoding;
    }
  }
{% endif %}

{% if varnish_cookie_sanitization_enabled %}
  ###
  # Cookie Sanitization
  ###
{% for cookie in varnish_cookie_sanitization_blacklist %}
  set req.http.Cookie = regsuball(req.http.Cookie, "{{ cookie }}=[^;]+(; )?", "");
{% endfor %}

  ### General Cleanup
  set req.http.Cookie = regsuball(req.http.Cookie, "^;\s*", "");
  if (req.http.cookie ~ "^\s*$") {
      unset req.http.cookie;
  }
{% endif %}

{% if varnish_uri_sanitization_enabled %}
  ###
  # URI Sanitization
  ###

  if (req.url ~ "(\?|&){{ varnish_uri_sanitization_regexp }}=") {
    set req.url = regsuball(req.url, "&{{ varnish_uri_sanitization_regexp }}=([A-z0-9_\-\.%25]+)", "");
    set req.url = regsuball(req.url, "\?{{ varnish_uri_sanitization_regexp }}=([A-z0-9_\-\.%25]+)", "?");
    set req.url = regsub(req.url, "\?&", "?");
    set req.url = regsub(req.url, "\?$", "");
  }
  if (req.url ~ "\#") {
    set req.url = regsub(req.url, "\#.*$", "");
  }
{% endif %}

{% if varnish_workaround_telusdotcom_browser_profile %}
  ###
  # Workaround for BrowserProfile and Language/Region Detection on TELUS.com
  ###

  if (req.http.Cookie ~ "BrowserProfile") {
    set req.http.X-BrowserProfile = regsuball(req.http.Cookie, "(.*)BrowserProfile=([^;]*)(.*)", "\2");
    if (req.http.X-BrowserProfile ~ "language") {
      set req.http.X-Language = std.tolower(regsuball(req.http.X-BrowserProfile, "(.*)language\\.:\\.([^\\]*)(.*)", "\2"));
      set req.http.X-Language-Found = "YES:BrowserProfile";
    }
    if (req.http.X-BrowserProfile ~ "region") {
      set req.http.X-Region = std.tolower(regsuball(regsuball(req.http.X-BrowserProfile, "geo\\.\:{(.*)\}", ""), "(.*)region\\.:\\.([^\\]*)(.*)", "\2"));
      set req.http.X-Region-Found = "YES:BrowserProfile";
    }
    if (req.http.X-BrowserProfile ~ "geo") {
      set req.http.X-BrowserProfile-Geolocation = regsuball(req.http.X-BrowserProfile, "(.*)geo..:\\.([^\\]*)(.*)", "\2");
      set req.http.X-BrowserProfile-Geolocation-Found = "YES";

      if (req.http.X-BrowserProfile-Geolocation ~ "country") {
        set req.http.X-BrowserProfile-Geolocation-Country = regsuball(req.http.X-BrowserProfile-Geolocation, "(.*)country\\.:\\.([^\\]*)(.*)", "\2");
      }
      if (req.http.X-BrowserProfile-Geolocation ~ "region") {
        set req.http.X-BrowserProfile-Geolocation-Region = regsuball(req.http.X-BrowserProfile-Geolocation, "(.*)region\\.:\\.([^\\]*)(.*)", "\2");
      }
      if (req.http.X-BrowserProfile-Geolocation ~ "city") {
        set req.http.X-BrowserProfile-Geolocation-City = regsuball(req.http.X-BrowserProfile-Geolocation, "(.*)city\\.:\\.([^\\]*)(.*)", "\2");
      }
      if (req.http.X-BrowserProfile-Geolocation ~ "isp") {
        set req.http.X-BrowserProfile-Geolocation-ISP = regsuball(req.http.X-BrowserProfile-Geolocation, "(.*)isp\\.:\\.([^\\]*)(.*)", "\2");
      }
    } else {
      set req.http.X-BrowserProfile-Geolocation-Found = "NO";
    }
  }

  if (!req.http.X-Language) {
    if (req.http.Cookie ~ "lang=") {
      set req.http.X-Language = std.tolower(regsuball(req.http.Cookie, "(.*)lang=([^;]*)(.*)", "\2"));
      set req.http.X-Language-Found = "YES:lang";
    } else {
      set req.http.X-Language = "en";
      set req.http.X-Language-Found = "NO";
    }
  }

  if (!req.http.X-Region) {
    if (req.http.Cookie ~ "prov=") {
      set req.http.X-Region = std.tolower(regsuball(req.http.Cookie, "(.*)prov=([^;]*)(.*)", "\2"));
      set req.http.X-Region-Found = "YES:prov";
    } else {
      set req.http.X-Region = "bc";
      set req.http.X-Region-Found = "NO";
    }
  }

  if (req.url ~ "/(en|fr)/") {
    if (req.url ~ "/en/" && req.http.X-Language != "en") {
      set req.http.X-Passthrough-Reason = "Unaligned Language (Path: /en/) vs (Cookie: " + req.http.X-Language + ")";
      return(pass);
    }
    if (req.url ~ "/fr/" && req.http.X-Language != "fr") {
      set req.http.X-Passthrough-Reason = "Unaligned Language (Path: /fr/) vs (Cookie: " + req.http.X-Language + ")";
      return(pass);
    }
  } else {
      set req.http.X-Passthrough-Reason = "Not Set in Path (Language)";
    return(pass);
  }

  if (req.url ~ "/(ab|bc|mb|nb|nl|ns|nt|nu|on|pe|qc|sk|yt)/") {
    {% for province in ['ab', 'bc', 'mb', 'nb', 'nl', 'ns', 'nt', 'nu', 'on', 'pe', 'qc', 'sk', 'yt'] %}
    if (req.url ~ "/{{ province }}/" && req.http.X-Region != "{{ province }}") {
      set req.http.X-Passthrough-Reason = "Unaligned Region (Path: /{{ province }}/) vs (Cookie: " + req.http.X-Region + ")";
      return(pass);
    }
    {% endfor %}
  } else {
      set req.http.X-Passthrough-Reason = "Not Set in Path (Province)";
    return(pass);
  }
{% endif %}

{% if varnish_cookie_sanitization_discard_from_client %}
    unset req.http.Cookie;
{% endif %}
}

###
# vcl_hit
#   Called when a cache lookup is successful.
###
# The vcl_hit subroutine may terminate with calling return() with one of the following keywords:
#
# restart
#   Restart the transaction. Increases the restart counter. If the number of restarts is higher than max_restarts Varnish emits a guru meditation error.
# deliver
#   Deliver the object. Control passes to vcl_deliver.
# synth(status code, reason)
#   Return the specified status code to the client and abandon the request.
###

sub vcl_hit {
  if (obj.ttl > 0s) {
    return (deliver);
  }
{% if varnish_health_checks_enabled %}
  if (!std.healthy(req.backend_hint) && (obj.ttl + obj.grace > 0s)) {
    return (deliver);
  } else {
    return (fetch);
  }
{% else %}
  if (obj.ttl + obj.grace > 0s) {
     return (deliver);
  }

  return (fetch);
{% endif %}
}

###
# vcl_backend_response
#   Called after the response headers has been successfully retrieved from the backend.
###
# The vcl_backend_response subroutine may terminate with calling return() with one of the following keywords:
#
# deliver
#   Possibly insert the object into the cache, then deliver it to the Control will eventually pass to vcl_deliver.
# abandon
#   Abandon the backend request and generates an error.
# retry
#   Retry the backend transaction. Increases the retries counter. If the number of retries is higher than max_retries Varnish emits a guru meditation error.
###

sub vcl_backend_response {
{% if varnish_workaround_telusdotcom_browser_profile %}
  if (bereq.http.X-Language) {
    set beresp.http.X-Language = bereq.http.X-Language;
#    if (bereq.http.X-Language-Found) {
#      set beresp.http.X-Language-Found = bereq.http.X-Language-Found;
#    }
  }
  if (bereq.http.X-Region) {
    set beresp.http.X-Region = bereq.http.X-Region;
#    if (bereq.http.X-Region-Found) {
#      set beresp.http.X-Region-Found = bereq.http.X-Region-Found;
#    }
  }
{% endif %}

{% if varnish_uri_blacklist_enabled %}
  if (bereq.url ~ "{{ varnish_uri_blacklist_regexp }}") {
    set beresp.http.X-Cacheable = "NO:Path in Blacklist";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } else {
    if (bereq.http.X-Passthrough-Reason) {
      set beresp.http.X-Passthrough-Reason = bereq.http.X-Passthrough-Reason;
      return(deliver);
    }
  }
{% else %}
{% if varnish_cookie_sanitization_discard_from_server %}
  unset beresp.http.Set-Cookie;
{% endif %}
{% endif %}

{% if varnish_diagnostic_headers_enabled %}
  if (bereq.http.Cookie) {
    set beresp.http.X-Cacheable = "NO:Cookie in Request";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } elsif (beresp.http.Set-Cookie) {
    set beresp.http.X-Cacheable = "NO:Set-Cookie in Response";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } elsif (beresp.http.Cache-Control ~ "private") {
    set beresp.http.X-Cacheable = "NO:Cache-Control=private";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } elsif (beresp.http.X-No-Cache) {
    set beresp.http.X-Cacheable = "NO:X-No-Cache";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } elsif (beresp.ttl <= 0s) {
    set beresp.http.X-Cacheable = "NO:Not Cacheable";
    set beresp.uncacheable = true;
    set beresp.ttl = {{ varnish_backend_response_ttl }}s;
    return(deliver);
  } else {
    set beresp.http.X-Cacheable = "YES";
  }
{% endif %}

  set beresp.grace = {{ varnish_grace_period }};
}

###
# vcl_deliver
#   Called before a cached object is delivered to the client.
###
# The vcl_deliver subroutine may terminate with calling return() with one of the following keywords:
#
# deliver
#   Deliver the object to the client.
# restart
#   Restart the transaction. Increases the restart counter. If the number of restarts is higher than max_restarts Varnish emits a guru meditation error.
###

sub vcl_deliver {
  if (obj.hits > 0) {
    set resp.http.X-Cache = "HIT";
  } else {
    set resp.http.X-Cache = "MISS";
  }
}


added varnish v3.0 default.vcl

added varnish v3.0 default.vcl

#
# This is an example VCL file for Varnish.
#
# It does not do anything by default, delegating control to the
# builtin VCL. The builtin VCL is called when there is no explicit
# return statement.
#
# See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/
# and http://varnish-cache.org/trac/wiki/VCLExamples for more examples.
#
# This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition. Set this to point to your content server.
backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .connect_timeout = 600s;
    .first_byte_timeout = 600s;
    .between_bytes_timeout = 600s;
    .max_connections = 800;
}

# Only allow purging from specific IPs
acl purge {
    "localhost";
    "127.0.0.1";
}

error: pathspec 'files/default/default3.0.vcl' did not match any file(s) known to git


removing expire controls from varnish

removing expire controls from varnish

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/cristianocasella/cristianocasella.com.git/'


first draft at varnish

first draft at varnish

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/erezny/twitter-import.git/'


* Move PURGE to a place where it does some good

* Make http auth work

git-svn-id: 7d4b18ab7d176792635d6a7a77dd8cbbea8e8daa@1499 d4fa192b-c00b-0410-8231-f00ffab90ce4


tuning varnish

tuning varnish


added twitter page when down

added twitter page when down

# This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition.  Set this to point to your content
# server.
#
backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

sub vcl_error {
  if (obj.status >= 500 && obj.status <= 505) {
      set obj.http.Content-Type = "text/html; charset=utf-8";
      synthetic {"

                 <title>taproot is down</title>

             #taprootapp Tweets

     "};
  }
    return (deliver);
}
#
# Below is a commented-out copy of the default VCL logic.  If you
# redefine any of these subroutines, the built-in logic will be
# appended to your code.
# sub vcl_recv {
#     if (req.restarts == 0) {
# 	if (req.http.x-forwarded-for) {
# 	    set req.http.X-Forwarded-For =
# 		req.http.X-Forwarded-For + ", " + client.ip;
# 	} else {
# 	    set req.http.X-Forwarded-For = client.ip;
# 	}
#     }
#     if (req.request != "GET" &&
#       req.request != "HEAD" &&
#       req.request != "PUT" &&
#       req.request != "POST" &&
#       req.request != "TRACE" &&
#       req.request != "OPTIONS" &&
#       req.request != "DELETE") {
#         /* Non-RFC2616 or CONNECT which is weird. */
#         return (pipe);
#     }
#     if (req.request != "GET" && req.request != "HEAD") {
#         /* We only deal with GET and HEAD by default */
#         return (pass);
#     }
#     if (req.http.Authorization || req.http.Cookie) {
#         /* Not cacheable by default */
#         return (pass);
#     }
#     return (lookup);
# }
#
# sub vcl_pipe {
#     # Note that only the first request to the backend will have
#     # X-Forwarded-For set.  If you use X-Forwarded-For and want to
#     # have it set for all requests, make sure to have:
#     # set bereq.http.connection = "close";
#     # here.  It is not set by default as it might break some broken web
#     # applications, like IIS with NTLM authentication.
#     return (pipe);
# }
#
# sub vcl_pass {
#     return (pass);
# }
#
# sub vcl_hash {
#     hash_data(req.url);
#     if (req.http.host) {
#         hash_data(req.http.host);
#     } else {
#         hash_data(server.ip);
#     }
#     return (hash);
# }
#
# sub vcl_hit {
#     return (deliver);
# }
#
# sub vcl_miss {
#     return (fetch);
# }
#
# sub vcl_fetch {
#     if (beresp.ttl <= 0s ||
#         beresp.http.Set-Cookie ||
#         beresp.http.Vary == "*") {
# 		/*
# 		 * Mark as "Hit-For-Pass" for the next 2 minutes
# 		 */
# 		set beresp.ttl = 120 s;
# 		return (hit_for_pass);
#     }
#     return (deliver);
# }
#
# sub vcl_deliver {
#     return (deliver);
# }
#
# sub vcl_error {
#     set obj.http.Content-Type = "text/html; charset=utf-8";
#     set obj.http.Retry-After = "5";
#     synthetic {"
# <?xml version="1.0" encoding="utf-8"?>
# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
#  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
#
#
#     <title>"} + obj.status + " " + obj.response + {"</title>
#
#
#
Error "} + obj.status + " " + obj.response + {"

#
"} + obj.response + {"

#
Guru Meditation:

#
XID: "} + req.xid + {"

#

#
Varnish cache server

#
#
# "};
#     return (deliver);
# }
#
# sub vcl_init {
# 	return (ok);
# }
#
# sub vcl_fini {
# 	return (ok);
# }

error: pathspec 'config/default.vcl' did not match any file(s) known to git


added debugging headers in vcl_fetch

added debugging headers in vcl_fetch

error: pathspec 'varnish' did not match any file(s) known to git
error: pathspec '3' did not match any file(s) known to git
error: pathspec 'vcls/drupal_base.vcl' did not match any file(s) known to git


fixed typo

fixed typo


Avoid DOS by CVE-2013-4484. See https://www.varnish-cache.org/lists/pipermail/varnish-announce/2013-October/000686.html


New example of configuration file: varnish to proxy your API request with 3scale backend not proxied

# This is a the VCL configuration file for 3scale's varnish plugin.
#
# Default backend definition.  Set this to point to the 3scale's
# backend.
#
# set the beresp.ttl in vcl_fetch to have a default global TTL
# you can define custom TTL via regular expressions
#

## the backend of your API
backend origin_server {
  .host = "YOU_ORIGIN_API_HOSTNAME";
  .port = "80";
}

import std;
import threescale;

sub vcl_recv {

  unset req.http.cookie;

  ## this request was send by the end-user
  set req.backend = origin_server;

  set req.http.X-3scale-authrep = "/transactions/authrep.xml?provider_key=YOUR_PROVIDER_KEY";

  ## ------------------
  ## MAPPING OF METHODS
  ## ------------------

  if (req.url ~ "^/deals/") {
    set req.http.X-3scale-authrep = req.http.X-3scale-authrep + "&usage[deals]=1";
  }

  if (req.url ~ "^/sales/local") {
    set req.http.X-3scale-authrep = req.http.X-3scale-authrep + "&usage[sales]=1&usage[local]=1";
  }

  ## ----------------------
  ## END MAPPING OF METHODS
  ## ----------------------

  ## extract the parameters sent by the user
  set req.http.X-3scale-app_id = regsub(req.url,".*[&?](app_id.[^&]*).*","\1");
  set req.http.X-3scale-app_key = regsub(req.url,".*[&?](app_key.[^&]*).*","\1");
  set req.http.X-3scale-user_key = regsub(req.url,".*[&?](user_key.[^&]*).*","\1");
  set req.http.X-3scale-user_id = regsub(req.url,".*[&?](user_id.[^&]*).*","\1");

  if (req.http.X-3scale-app_id != req.url) {
    set req.http.X-3scale-authrep = req.http.X-3scale-authrep + "&" + req.http.X-3scale-app_id;
  }

  if (req.http.X-3scale-app_key != req.url ) {
    set req.http.X-3scale-authrep = req.http.X-3scale-authrep + "&" + req.http.X-3scale-app_key;
  }

  if (req.http.X-3scale-user_id != req.url) {
    set req.http.X-3scale-authrep = req.http.X-3scale-authrep + "&" + req.http.X-3scale-user_id;
  }

  if (req.http.X-3scale-user_key != req.url) {
    set req.http.X-3scale-authrep = req.http.X-3scale-authrep + "&" + req.http.X-3scale-user_key;
  }

  unset req.http.X-3scale-app_id;
  unset req.http.X-3scale-app_key;
  unset req.http.X-3scale-user_id;
  unset req.http.X-3scale-user_key;

  set req.http.X-3scale-authrep-result = threescale.send_get_request("su1.3scale.net","80",req.http.X-3scale-authrep,"");

  if (req.http.X-3scale-authrep-result == "200") {
    ## the request from the user has been authorized, proceed as normal

    if (req.request != "GET" && req.request != "HEAD") {
      return(pass);
    }
    else {
      return(lookup);
    }

  }
  else {
    ## the request from the users has not been authorized!! Returning an error
    ## FIXME: convert req.http.X-3scale-authrep-result; to int
    error 401;
  }

  unset req.http.X-3scale-authrep;
  unset req.http.X-3scale-authrep-result;

}

# the hash of the request needs to be customized to remove all fields that are not
# associated to the user

sub vcl_hash {

  set req.http.X-url-tmp = regsub(req.url,"[&?]user_key.[^&]*","");
  set req.http.X-url-tmp = regsub(req.url,"[&?]user_id.[^&]*","");
  set req.http.X-url-tmp = regsub(req.url,"[&?]app_key.[^&]*","");
  set req.http.X-url-tmp = regsub(req.url,"[&?]app_id.[^&]*","");

  hash_data(req.http.X-url-tmp);

  if (req.http.host) {
    hash_data(req.http.host);
  }
  else {
    hash_data(server.ip);
  }

  unset req.http.X-url-tmp;

  return (hash);

}

#A HIT means that the request to your local cache of 3scale is still fresh and the
#response will not have to fetch the data from the remote 3scale backend.
#vmod_3scale plugin will send a replica of the call asynchronously to 3scale's remote
#backend on its own

sub vcl_fetch {
  ## 5 minutes caching for everything
  set beresp.ttl = 5m;
}

sub vcl_deliver {
  ## remove control headers
  unset req.http.X-3scale-authrep;
}

sub vcl_error {
  set obj.http.Content-Type = "text/html; charset=utf-8";
  synthetic {"
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

    <title>"} + obj.status + " " + obj.response + {"</title>

Authorization error trying to access this API

Did you forget to send your credentials?

Are you over the limits of your account?

Please go to your account at http://your3scaledomain.com to find out

"};
  return (deliver);
}

error: pathspec 'vcl/default_3scale_only_proxy.vcl' did not match any file(s) known to git


VCL request

VCL request

Added custom Deliver Custom Header

sub vcl_recv {
  #FASTLY recv
    if (req.request != "HEAD" && req.request != "GET" && req.request != "FASTLYPURGE") {
      return(pass);
    }
    return(lookup);

}
sub vcl_fetch {
	#FASTLY fetch

    if (beresp.http.Vary) {
        set beresp.http.Vary = beresp.http.Vary ", MyLang";
      } else {
        set beresp.http.Vary = "MyLang";
    }
      if ((beresp.status == 500 || beresp.status == 503) && req.restarts < 1 && (req.request == "GET" || req.request == "HEAD")) {
    restart;
  }

  if(req.restarts > 0 ) {
    set beresp.http.Fastly-Restarts = req.restarts;
  }

  if (beresp.http.Set-Cookie) {
    set req.http.Fastly-Cachetype = "SETCOOKIE";
    return (pass);
  }

  if (beresp.http.Cache-Control ~ "private") {
    set req.http.Fastly-Cachetype = "PRIVATE";
    return (pass);
  }

  if (beresp.status == 500 || beresp.status == 503) {
    set req.http.Fastly-Cachetype = "ERROR";
    set beresp.ttl = 1s;
    set beresp.grace = 5s;
    return (deliver);
  }

  if (beresp.http.Expires || beresp.http.Surrogate-Control ~ "max-age" || beresp.http.Cache-Control ~"(s-maxage|max-age)") {
    # keep the ttl here
  } else {
    # apply the default ttl
    set beresp.ttl = 3600s;
  }
  return(deliver);

}
sub vcl_deliver {
	#FASTLY deliver
   if (resp.http.Vary) {
    set resp.http.Vary = regsub(resp.http.Vary, "MyLang", "WebSiteLang");
  }
  if (req.url ~ "ja" && req.http.Cookie !~ "WebSiteLang=ja") {
    add resp.http.Set-Cookie = "WebSiteLang=ja; expires=" now + 180d "; path=/;";
  }
  if (req.url ~ "es" && req.http.Cookie !~ "WebSiteLang=es") {
    add resp.http.Set-Cookie = "WebSiteLang=es; expires=" now + 180d "; path=/;";
  }
  if (req.url ~ "pt" && req.http.Cookie !~ "WebSiteLang=pt") {
    add resp.http.Set-Cookie = "WebSiteLang=pt; expires=" now + 180d "; path=/;";
  }
  if (req.url ~ "it" && req.http.Cookie !~ "WebSiteLang=it") {
    add resp.http.Set-Cookie = "WebSiteLang=it; expires=" now + 180d "; path=/;";
  }
  if (req.url ~ "fr" && req.http.Cookie !~ "WebSiteLang=fr") {
    add resp.http.Set-Cookie = "WebSiteLang=fr; expires=" now + 180d "; path=/;";
  }
  if (req.url ~ "de" && req.http.Cookie !~ "WebSiteLang=de") {
    add resp.http.Set-Cookie = "WebSiteLang=de; expires=" now + 180d "; path=/;";
  }
  if (req.url ~ "en" && req.http.Cookie !~ "WebSiteLang=en") {
    add resp.http.Set-Cookie = "WebSiteLang=en; expires=" now + 180d "; path=/;";
  }

}
sub vcl_hit {
#FASTLY hit

  if (!obj.cacheable) {
    return(pass);
  }
  return(deliver);
}

sub vcl_miss {
#FASTLY miss
  return(fetch);
}
sub vcl_error {
#FASTLY error
}

sub vcl_pass {
#FASTLY pass
}

error: pathspec 'custom52.vcl' did not match any file(s) known to git


fixing ip address for backend

fixing ip address for backend


Comment cleanup

Comment cleanup

As noted by @kbemelmans on https://github.com/NITEMAN/Varnish_VCL_samps-hacks/commit/4ad1aa9fa2f7b0597419508e54f147c97b08fa97#commitcomment-4548026


drupal_base.vcl Mix & Fun of X-Forwarded-Proto thanks to penyaskito


Started developing/learning a varnish.vcl file for D3Up. Dont judge!

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/D3Up/D3Up.com.git/'


added placeholders TO-DOs to give a better debugging info


re #444 : Add nooku.vcl for varnish 4.0

re #444 : Add nooku.vcl for varnish 4.0

vcl 4.0;

# Based on: https://github.com/mattiasgeniar/varnish-4.0-configuration-templates/blob/master/default.vcl
# Corrected & improved for 4.0.2 by jnerin@gmail.com

import std;
import directors;

# Backend definitions
backend default
{
    .host = "127.0.0.1";        # IP or Hostname of backend
    .port = "8080";             # Port Apache or whatever is listening
    .max_connections = 300;     # That's it
    .probe = {
        #.url = "/varnish-enabled";
        # We prefer to only do a HEAD /
        .request =
            "HEAD /varnish-enabled HTTP/1.1"
            "Host: localhost"
            "Connection: close";
      .interval = 5s;   # check the health of each backend every 5 seconds
      .timeout = 1s;    # timing out after 1 second.
       # If 3 out of the last 5 polls succeeded the backend is considered healthy, otherwise it will be marked as sick
      .window = 5;
      .threshold = 3;
    }

    .connect_timeout = 600s;        # How long to wait before we receive a first byte from our backend?
    .first_byte_timeout = 600s;     # How long to wait for a backend connection?
    .between_bytes_timeout = 600s;  # How long to wait between bytes received from our backend?
}

# Acl definitions
acl localhost
{
    "localhost";
    "33.33.33.63";
    "::1";
}

# Called when VCL is loaded, before any requests pass through it. Typically used to initialize VMODs.
sub vcl_init
{
    new vdir = directors.round_robin();
    vdir.add_backend(default);
    # vdir.add_backend(server...);
    # vdir.add_backend(servern);
}

# Called at the beginning of a request, after the complete request has been received and parsed. Its purpose is to
# decide whether or not to serve the request, how to do it, and, if applicable, which backend to use also used to
# modify the request
sub vcl_recv
{
    # Add a Surrogate-Capability header to announce ESI support.
    set req.http.Surrogate-Capability = "varnish=ESI/1.0";

    # Send all traffic to the vdir director
    set req.backend_hint = vdir.backend(); # send all traffic to the vdir director

    if (req.restarts == 0)
    {
        # Set or append the client.ip to X-Forwarded-For header
        if (req.http.X-Forwarded-For) {
          set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
        } else {
          set req.http.X-Forwarded-For = client.ip;
        }

        set req.http.X-Forwarded-By = server.ip;
        set req.http.X-Forwarded-Port = std.port(client.ip);
    }

    # 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")
    {
        # purge is the ACL defined at the begining
        if (!client.ip ~ localhost) {
          return (synth(405, "This IP is not allowed to send PURGE requests."));
        }

        return (purge);
    }

    # 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);
    }

    # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-websockets.html)
    if (req.http.Upgrade ~ "(?i)websocket") {
        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);
    }

    # Send Surrogate-Capability headers to announce ESI support to backend
    set req.http.Surrogate-Capability = "key=ESI/1.0";
    if (req.http.Authorization)
    {
        # Not cacheable by default
        return (pass);
    }

    # Check if we've still enabled Varnish, if not, passthrough every request
    if (! std.healthy(req.backend_hint))
    {
        set req.backend_hint = default;
        return (pass);
    }

    # Specific Nooku Platform rules

        # Do not cache /administrator
        if(req.url ~ "^/administrator") {
            return (pass);
        }

    # Specific Nooku Server rules

        # Do not cache webgrind.nooku.dev
        if (req.http.host == "webgrind.nooku.dev") {
            return (pass);
        }

        # Do not cache phpmyadmin.nooku.dev
        if (req.http.host == "phpmyadmin.nooku.dev") {
            return (pass);
        }

        # Do not cache /apc and /phpinfo
        if (req.url == "/apc" || req.url == "/phpinfo") {
            return (pass);
        }

    # Generic URL manipulation, useful for all templates that follow

        # 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)=") {
            set req.url = regsuball(req.url, "&(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([A-z0-9_\-\.%25]+)", "");
            set req.url = regsuball(req.url, "\?(utm_source|utm_medium|utm_campaign|utm_content|gclid|cx|ie|cof|siteurl)=([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, "\?$", "");
        }

    # Cookie manipulation

        # 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*", "");

        # Remove the csrf_token cookie
        set req.http.Cookie = regsuball(req.http.Cookie, "csrf_token=[^;]+(; )?", "");

        # Are there cookies left with only spaces or that are empty?
        if (req.http.cookie ~ "^\s*$") {
            unset req.http.cookie;
        }

    # We do not support SPDY or HTTP/2.0
    if (req.method == "PRI") {
        return (synth(405));
    }

    # Normalize Accept-Encoding header
    # straight from the manual: https://www.varnish-cache.org/docs/3.0/tutorial/vary.html
    # 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;
        }
    }

    if (req.http.Cache-Control ~ "(?i)no-cache" && client.ip ~ localhost)
    {
        # http://varnish.projects.linpro.no/wiki/VCLExampleEnableForceRefresh
        # Ignore requests via proxy caches and badly behaved crawlers
        # like msnbot that send no-cache with every request.
        if (! (req.http.Via || req.http.User-Agent ~ "(?i)bot" || req.http.X-Purge))
        {
             # Doesn't seems to refresh the object in the cache
             set req.hash_always_miss = true;

             # Couple this with restart in vcl_purge and X-Purge header to avoid loops
             return(purge);
        }
    }

    # Large static files are delivered directly to the end-user without waiting for Varnish to fully read the file first.
    # Varnish 4 fully supports Streaming, so set do_stream in vcl_backend_response()
    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);
    }

    # Remove all cookies for static files
    # Before you blindly enable this, have a read here: https://ma.ttias.be/stop-caching-static-files/
    if (req.method == "GET")
    {
        # Cache files with these extensions and remove cookie
        if (req.url ~ "^[^?]*\.(bmp|bz2|css|doc|eot|flv|gif|gz|ico|jpeg|jpg|js|less|pdf|png|rtf|swf|txt|woff|xml)(\?.*)?$") {
            unset req.http.Cookie;
            return (hash);
        }
    }

    return (hash);
}

# Called upon entering pipe mode. In this mode, the request is passed on to the backend, and any further data from both
# the client and backend is passed on unaltered until either end closes the connection. Basically, Varnish will degrade
# into a simple TCP proxy, shuffling bytes back and forth. For a connection in pipe mode, no other VCL subroutine will
# ever get called after vcl_pipe.
sub vcl_pipe
{
    # Note that only the first request to the backend will have X-Forwarded-For set.
    # If you use X-Forwarded-For and want to have it set for all requests, make sure to have:
    # set bereq.http.connection = "close";
    # It is not set by default as it might break some broken web applications, like IIS with NTLM authentication.
    # set bereq.http.Connection = "Close";

    # Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-websockets.html)
    if (req.http.upgrade) {
        set bereq.http.upgrade = req.http.upgrade;
    }

    return (pipe);
}

# Called upon entering pass mode. In this mode, the request is passed on to the backend, and the backend's response
# is passed on to the client, but is not entered into the cache. Subsequent requests submitted over the same client
# connection are handled normally.
sub vcl_pass
{
    return (fetch);
}

# Called after vcl_recv to create a hash value for the request. This is used as a key to look up the object in Varnish.
sub vcl_hash
{
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }

    # hash cookies for requests that have them
    if (req.http.Cookie) {
        hash_data(req.http.Cookie);
    }
}

# Called when a cache lookup is successful.
sub vcl_hit
{
    # A pure unadultered hit, deliver it
    if (obj.ttl >= 0s) {
        return (deliver);
    }

    # https://www.varnish-cache.org/docs/trunk/users-guide/vcl-grace.html
    # When several clients are requesting the same page Varnish will send one request to the backend and place the
    # others on hold while fetching one copy from the backend. In some products this is called request coalescing and
    # Varnish does this automatically.

    # If you are serving thousands of hits per second the queue of waiting requests can get huge. There are two
    # potential problems - one is a thundering herd problem - suddenly releasing a thousand threads to serve content
    # might send the load sky high. Secondly - nobody likes to wait. To deal with this we can instruct Varnish to keep
    # the objects in cache beyond their TTL and to serve the waiting requests somewhat stale content.

    # if (!std.healthy(req.backend_hint) && (obj.ttl + obj.grace > 0s)) {
    #   return (deliver);
    # } else {
    #   return (fetch);
    # }

    # We have no fresh fish. Lets look at the stale ones.
    if (std.healthy(req.backend_hint))
    {
        # Backend is healthy. Limit age to 10s.
        if (obj.ttl + 10s > 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
    return (fetch); # Dead code, keep as a safeguard
}

# Called after a cache lookup if the requested document was not found in the cache. Its purpose is to decide whether
# or not to attempt to retrieve the document from the backend, and which backend to use.
sub vcl_miss
{
    return (fetch);
}

 # Called after the response headers has been successfully retrieved from the backend.
sub vcl_backend_response
{
    # Enable ESI handling
    if (beresp.http.Surrogate-Control ~ "ESI/1.0" ) {
        set beresp.do_esi = true;
    }

    # Store the csrf_token cookie temporarily if the response is cacheabale
    if (beresp.http.Set-Cookie && beresp.uncacheable )
    {
        set beresp.http.X-Varnish-Cookie = beresp.http.Set-Cookie;
        unset beresp.http.Set-Cookie;
    }

    # Enable cache for all static files
    # Before you blindly enable this, have a read here: https://ma.ttias.be/stop-caching-static-files/
    if (bereq.method == "GET")
    {
        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|xml|zip)(\?.*)?$") {
            unset beresp.http.Set-Cookie;
        }
    }

    # Large static files are delivered directly to the end-user without waiting for Varnish to fully read the file first.
    # Varnish 4 fully supports Streaming, so use streaming here to avoid locking.
    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;
        set beresp.do_stream = true;
        # 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_gzip = false; # Don't try to compress it for storage
    }

    # Sometimes, a 301 or 302 redirect formed via Apache's mod_rewrite can mess with the HTTP port that is being passed along.
    # This often happens with simple rewrite rules in a scenario where Varnish runs on :80 and Apache on :8080 on the same box.
    # A redirect can then often redirect the end-user to a URL on :8080, where it should be :80.
    # This may need finetuning on your setup.
    #
    # To prevent accidental replace, we only filter the 301/302 redirects for now.
    if (beresp.status == 301 || beresp.status == 302) {
        set beresp.http.Location = regsub(beresp.http.Location, ":[0-9]+", "");
    }

    # Set 2min cache if unset for static files
    if (beresp.ttl <= 0s || beresp.http.Set-Cookie || beresp.http.Vary == "*")
    {
        set beresp.ttl = 120s; # Important, you shouldn't rely on this, SET YOUR HEADERS in the backend
        set beresp.uncacheable = true;

        return (deliver);
    }

    # Do not cache errors from the backend
    if (beresp.status >= 400)
    {
        set beresp.uncacheable = true;
        set beresp.ttl = 0s;

        return (deliver);
    }

    # Allow stale content, in case the backend goes down. Make Varnish keep all objects for 6 hours beyond their TTL
    set beresp.grace = 6h;

    # Set ban-lurker friendly custom headers
    set beresp.http.X-Varnish-Url  = bereq.url;
    set beresp.http.X-Varnish-Host = bereq.http.host;

    return (deliver);
}

# Called when the backend returns an error
sub vcl_backend_error
{
    if (beresp.status == 503 && bereq.retries < 5)
    {
        set beresp.http.X-Varnish-Retries = bereq.retries;
        return(retry);
    }

    return(deliver);
}

# Called before a cached object is delivered to the client.
sub vcl_deliver
{
    # Send the Cookie header again if a temporay header was stored
    if (req.http.X-Varnish-Cookie) {
        set resp.http.Set-Cookie = req.http.X-Varnish-Cookie;
    }

    # Add extra headers if debugging is enabled
    if (resp.http.x-varnish-debug && server.ip ~ localhost)
    {
        set resp.http.X-Served-By = server.hostname;

        if (resp.http.x-varnish ~ " ") {
            set resp.http.X-Varnish-Status = "HIT";
        } else {
            set resp.http.X-Varnish-Status = "MISS";
        }

        # Please note that obj.hits behaviour changed in 4.0, now it counts per objecthead, not per object
        # and obj.hits may not be reset in some cases where bans are in use. See bug 1492 for details.
        # So take hits with a grain of salt
        set resp.http.X-Varnish-Hits = obj.hits;
    }
    else
    {
        # Remove ban-lurker friendly custom headers when delivering to client
        unset resp.http.X-Url;
        unset resp.http.X-Host;

        # Remove some headers: PHP version
        unset resp.http.X-Powered-By;

        # Remove some headers: Apache version & OS
        unset resp.http.Server;
        unset resp.http.Via;
        unset resp.http.Link;
        unset resp.http.X-Varnish;
        unset resp.http.X-Varnish-Tag;
        unset resp.http.X-Varnish-Debug;
        unset resp.http.X-Varnish-Host;
        unset resp.http.X-Varnish-Url;
        unset resp.http.X-Varnish-Retries;
        unset resp.http.X-Varnish-Cookie;
        unset resp.http.Surrogate-Control;
    }

    return (deliver);
}

sub vcl_purge
{
    # Only handle actual PURGE HTTP methods, everything else is discarded
    if (req.method != "PURGE" && server.ip ~ localhost)
    {
        set req.http.X-Varnish-Purge = "Yes";
        return(restart);
    }
}

sub vcl_synth
{
    if (resp.status == 720)
    {
        # We use this special error status 720 to force redirects with 301 (permanent) redirects
        # To use this, call the following from anywhere in vcl_recv: return (synth(720, "http://host/new.html"));
        set resp.status = 301;
        set resp.http.Location = resp.reason;

        return (deliver);
    }
    elseif (resp.status == 721)
    {
        # And we use error status 721 to force redirects with a 302 (temporary) redirect
        # To use this, call the following from anywhere in vcl_recv: return (synth(720, "http://host/new.html"));

        set resp.status = 302;
        set resp.http.Location = resp.reason;

        return (deliver);
    }

    return (deliver);
}

# Called when VCL is discarded only after all requests have exited the VCL. Typically used to clean up VMODs.
sub vcl_fini
{
  return (ok);
}

error: pathspec 'component/varnish/resources/varnish/nooku.vcl' did not match any file(s) known to git


Added example VCL, set rule from curl.

Added example VCL, set rule from curl.

/*-
 * Copyright (c) 2006 Verdens Gang AS
 * Copyright (c) 2006-2011 Varnish Software AS
 * All rights reserved.
 *
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The default VCL code.
 *
 * NB! You do NOT need to copy & paste all of these functions into your
 * own vcl code, if you do not provide a definition of one of these
 * functions, the compiler will automatically fall back to the default
 * code from this file.
 *
 * This code will be prefixed with a backend declaration built from the
 * -b argument.
 */

 import std;
 import abtest;

 C{
    #include <syslog.h>
 }C

 backend default {
    .host = "127.0.0.1";
    .port = "3000";
 }

/* Only permit localhost to manipulate abtest configuration */
acl abconfig {
    "localhost";
}

sub vcl_init {
    if (abtest.load_config("/tmp/abtest.cfg") != 0) {
        C{ syslog(LOG_ALERT, "Unable to load AB config from /tmp/abtest.cfg"); }C
    }
    return (ok);
}

sub vcl_fini {
}

sub vcl_recv {
    if (req.http.AB-Cfg) {
        if (!client.ip ~ abconfig) {
            std.log("AB Config request not allowed from " + client.ip);
            error 405 "Not allowed.";
        } else {
            // curl localhost:8080 -X PUT -H "AB-Cfg:base" -H "AB-Cfg-Val:a:25;b:75;"
            if (req.request == "PUT") {
                std.log("AB Config PUT request: " + req.http.AB-Cfg + "|" + req.http.AB-Cfg-Val);
                abtest.set_rule(req.http.AB-Cfg, req.http.AB-Cfg-Val);
                abtest.save_config("/tmp/abtest.cfg");
            }

            if (req.request == "DELETE") {
                std.log("AB Config DELETE request: " + req.http.AB-Cfg);
            }

            if (req.request == "GET") {
                std.log("AB Config GET request: " + req.http.AB-Cfg);
            }
        }
    }

/*
    if(req.http.Cookie ~ "abtesting") {
    }
*/
}

sub vcl_pipe {
}

sub vcl_pass {
}

sub vcl_hash {
}

sub vcl_hit {
}

sub vcl_miss {
}

sub vcl_fetch {
}

sub vcl_deliver {
}

sub vcl_error {
}

error: pathspec 'vcl/default.vcl' did not match any file(s) known to git


Add varnish configuration

Add varnish configuration

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/nextchan/infinity-next.git/'