Search code examples
varnishvarnish-vclvarnish-4

Convert Varnish VCL from 3 to 5.1.2 version


I've this Varnish default VCL that is working fine with version 3.x. However, now it's time to upgrade. How can we upgrade below varnish vcl to latest version 5.1.2, could anyone assist and it might help many others too.

backend default {
 .host = "00.00.0.0";
 .port = "8080"; 
}

acl purgers {
    "00.00.0.1";
    "00.00.0.2";
    "00.00.0.3";
    "00.00.0.4";
    "00.00.0.5";
    "192.168.0.0."/16;
    "192.168.1.0."/16;
    "00.00.0.0";
    "127.0.0.1";
}

# Routine to identify and classify a device based on User-Agent
sub detect_device {

# Default to classification as a PC
set req.http.X-Device = "pc";

if (req.http.User-Agent ~ "iPad" ) {
# The User-Agent indicates it's a iPad - so classify as a tablet
set req.http.X-Device = "mobile-tablet";
}

elsif (req.http.User-Agent ~ "iP(hone|od)" || req.http.User-Agent ~ "Android") {
# The User-Agent indicates it's a iPhone, iPod or Android - so let's 
classify as a touch/smart phone
    set req.http.X-Device = "mobile-smart";
}

  elsif (req.http.User-Agent ~ "SymbianOS" || req.http.User-Agent ~ "^BlackBerry" || req.http.User-Agent ~ "^SonyEricsson" || req.http.User-Agent ~ "^Nokia" || req.http.User-Agent ~ "^SAMSUNG" || req.http.User-Agent ~ "^LG")               {
# The User-Agent indicates that it is some other mobile devices, so let's classify it as such.
set req.http.X-Device = "mobile-other";
  }
}

  sub vcl_hash {
  # If the device has been classified as any sort of mobile device, include the User-Agent in the hash
  # However, do not do this for any static assets as our web application returns                                                                                         the same ones for every device.
  if (!(req.url ~ "\.(gif|jpg|jpeg|swf|flv|mp3|mp4|pdf|ico|png|gz|tgz|bz2)(\?.*| )$")) {
hash_data(req.http.X-Device);
  }
}

sub vcl_recv {

# Everything to HTTPS

if ( req.http.X-Forwarded-Proto !~ "(?i)https") {
    set req.http.X-Redir-Url = "https://" + req.http.Host + req.url;
    error 750 req.http.x-Redir-Url;
}

    call detect_device;
    set client.identity = req.http.cookie;

    if (req.request == "PURGE") {
             if (!client.ip ~ purgers) {
                    error 405 "Method not allowed";
             }
             return(lookup);
    }

# SSL 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.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
    set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");

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

// Remove has_js and Google Analytics __* cookies.
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
// Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");


    if (req.url ~ "spliting.php" || req.url ~ "featured") {
            return (pass);
    }

    if (req.http.Accept-Encoding) {
            if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
                    remove req.http.Accept-Encoding;
            }
            elsif (req.http.Accept-Encoding ~ "gzip") {
                    set req.http.Accept-Encoding = "gzip";
            }
            else {
                    remove req.http.Accept-Encoding;
            }
    }

    if (req.url ~ "\.(ico|png|jpeg|jpg|gif|xpm|css|swf|flv|txt)$") {
            remove req.http.cookie;
            return (lookup);
    }

    return (lookup);
}
sub vcl_error {

   if (obj.status == 750) {
      set obj.http.Location = obj.response;
      set obj.status = 301;
      return (deliver);
   }

   if (obj.status == 204) {
      unset obj.http.Server;
      unset obj.http.Content-Length;
      unset obj.http.Date;
      unset obj.http.X-Varnish;
      unset obj.http.Age;
      unset obj.http.Via;
      synthetic {""};
   }

   if (obj.status == 500 || obj.status == 502 || obj.status == 503 || obj.status == 504) {
   #if (obj.status >= 500) {
      unset obj.http.X-Varnish;
      unset obj.http.Server;
      unset obj.http.Via;
      set obj.ttl = 0s;
      synthetic {""};
   }
   return (deliver);
}


sub vcl_fetch {

if ((req.request != "POST") && (!req.url ~ "accept_cookie.php")) {
    set beresp.ttl = 30m;
} else {
    set beresp.ttl = 0s;
   }

    if ((req.url ~ "/[\w\-]+/[\w\-]+/[\w\-]+/[\w\-]+/Permanent/[\w\-]+/[\w\-]+/[\w\-]+/[\w\-]+/$") && (beresp.ttl > 0s)) {
   unset beresp.http.cache-control;
   unset beresp.http.expires;
   unset beresp.http.cookie;
   set beresp.do_gzip = true;
   set beresp.storage = "bar";
   set beresp.http.x-storage = "bar";
   set beresp.http.Cache-Control = "public, max-age=21600, s-maxage=21600";
   remove beresp.http.Pragma;
   set beresp.ttl = 30d;
   return(deliver);
   }


   if ((req.url ~ "imagez|many") && (beresp.ttl > 0s)) {
   unset beresp.http.cache-control;
   unset beresp.http.expires;
   unset beresp.http.cookie;
   set beresp.do_gzip = true;
   set beresp.storage = "bar";
   set beresp.http.x-storage = "bar";      
   set beresp.http.Cache-Control = "public, max-age=12966777, s-maxage=12966777";
   remove beresp.http.Pragma;
   set beresp.ttl = 366d;
   return(deliver);
  }

if (beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {
#if (beresp.status >= 500) {
    set beresp.ttl = 0s;
}

# Varnish determined the object was not cacheable
if (beresp.ttl <= 0s) {
    set beresp.http.X-Cacheable = "NO:Not Cacheable";

# You don't wish to cache content for logged in users
} elsif (req.http.Cookie ~ "(UserID|_session)") {
    set beresp.http.X-Cacheable = "NO:Got Session";
    return(hit_for_pass);

# You are respecting the Cache-Control=private header from the backend
} elsif (beresp.http.Cache-Control ~ "private") {
    set beresp.http.X-Cacheable = "NO:Cache-Control=private";
    return(hit_for_pass);

# Varnish determined the object was cacheable
} else {
    set beresp.storage = "foo";
    set beresp.http.x-storage = "foo";        
    set beresp.http.Cache-Control = "public, max-age=14900, s-maxage=14900";
    remove beresp.http.Pragma;
    remove beresp.http.expires;
}

   #   set beresp.grace = 240m;
 set beresp.grace = 30m;

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

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

sub vcl_miss {
    if (req.request == "PURGE") {
            purge;
            error 404 "Not in cache";
    }
}
sub vcl_pass {
    if (req.request == "PURGE") {
            error 502 "PURGE on a passed object";
    }
 }

Solution

  • I don't really think it can benefit others as your VCL is unnecessarily complicated (my standard advice is to start from the empty default.vcl and add bits by bits as needed in order to understand how things work.

    Straight forward rewrite:

    vcl 4.0;
    
    backend default {
     .host = "00.00.0.0";
     .port = "8080";
    }
    
    acl purgers {
        "00.00.0.1";
        "00.00.0.2";
        "00.00.0.3";
        "00.00.0.4";
        "00.00.0.5";
        "192.168.0.0."/16;
        "192.168.1.0."/16;
        "00.00.0.0";
        "127.0.0.1";
    }
    
    # Routine to identify and classify a device based on User-Agent
    sub detect_device {
    
    # Default to classification as a PC
    set req.http.X-Device = "pc";
    
    if (req.http.User-Agent ~ "iPad" ) {
    # The User-Agent indicates it's a iPad - so classify as a tablet
    set req.http.X-Device = "mobile-tablet";
    }
    
    elsif (req.http.User-Agent ~ "iP(hone|od)" || req.http.User-Agent ~ "Android") {
    # The User-Agent indicates it's a iPhone, iPod or Android - so let's classify as a touch/smart phone
        set req.http.X-Device = "mobile-smart";
    }
    
      elsif (req.http.User-Agent ~ "SymbianOS" || req.http.User-Agent ~ "^BlackBerry" || req.http.User-Agent ~ "^SonyEricsson" || req.http.User-Agent ~ "^Nokia" || req.http.User-Agent ~ "^SAMSUNG" || req.http.User-Agent ~ "^LG")               {
    # The User-Agent indicates that it is some other mobile devices, so let's classify it as such.
    set req.http.X-Device = "mobile-other";
      }
    }
    
      sub vcl_hash {
      # If the device has been classified as any sort of mobile device, include the User-Agent in the hash
      # However, do not do this for any static assets as our web application returns                                                                                         the same ones for every device.
      if (!(req.url ~ "\.(gif|jpg|jpeg|swf|flv|mp3|mp4|pdf|ico|png|gz|tgz|bz2)(\?.*| )$")) {
    hash_data(req.http.X-Device);
      }
    }
    
    sub vcl_recv {
    
    # Everything to HTTPS
    
    if ( req.http.X-Forwarded-Proto !~ "(?i)https") {
        set req.http.X-Redir-Url = "https://" + req.http.Host + req.url;
        return (synth(750, ""));
    }
    
        call detect_device;
        set client.identity = req.http.cookie;
    
        if (req.method == "PURGE") {
                 if (!client.ip ~ purgers) {
                        return (synth(405, "Method not allowed"));
                 }
                 return(purge);
        }
    
    # SSL 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.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
        set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
    
        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);
        }
    
    // Remove has_js and Google Analytics __* cookies.
    set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
    // Remove a ";" prefix, if present.
    set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
    
    
        if (req.url ~ "spliting.php" || req.url ~ "featured") {
                return (pass);
        }
    
        if (req.url ~ "\.(ico|png|jpeg|jpg|gif|xpm|css|swf|flv|txt)$") {
                unset req.http.cookie;
                return (hash);
        }
    
        return (hash);
    }
    sub vcl_synth {
    
       if (resp.status == 750) {
          set resp.http.Location = req.http.X-Redir-Url;
          set resp.status = 301;
          return (deliver);
       }
    
       if (resp.status == 204) {
          unset resp.http.Server;
          unset resp.http.Content-Length;
          unset resp.http.Date;
          unset resp.http.X-Varnish;
          unset resp.http.Age;
          unset resp.http.Via;
          synthetic ({""});
          return (deliver);
       }
    
    }
    
    
    sub vcl_backend_response {
    
    if ((bereq.method != "POST") && (!bereq.url ~ "accept_cookie.php")) {
        set beresp.ttl = 30m;
    } else {
        set beresp.ttl = 0s;
       }
    
        if ((bereq.url ~ "/[\w\-]+/[\w\-]+/[\w\-]+/[\w\-]+/Permanent/[\w\-]+/[\w\-]+/[\w\-]+/[\w\-]+/$") && (beresp.ttl > 0s)) {
       unset beresp.http.cache-control;
       unset beresp.http.expires;
       unset beresp.http.cookie;
       set beresp.do_gzip = true;
       set beresp.http.storage = "bar";
       set beresp.http.x-storage = "bar";
       set beresp.http.Cache-Control = "public, max-age=21600, s-maxage=21600";
       unset beresp.http.Pragma;
       set beresp.ttl = 30d;
       return(deliver);
       }
    
    
       if ((bereq.url ~ "imagez|many") && (beresp.ttl > 0s)) {
       unset beresp.http.cache-control;
       unset beresp.http.expires;
       unset beresp.http.cookie;
       set beresp.do_gzip = true;
       set beresp.http.storage = "bar";
       set beresp.http.x-storage = "bar";
       set beresp.http.Cache-Control = "public, max-age=12966777, s-maxage=12966777";
       unset beresp.http.Pragma;
       set beresp.ttl = 366d;
       return(deliver);
      }
    
    if (beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {
        set beresp.ttl = 0s;
    }
    
    # Varnish determined the object was not cacheable
    if (beresp.ttl <= 0s) {
        set beresp.http.X-Cacheable = "NO:Not Cacheable";
    
    # You don't wish to cache content for logged in users
    } elsif (bereq.http.Cookie ~ "(UserID|_session)") {
        set beresp.http.X-Cacheable = "NO:Got Session";
        set beresp.uncacheable = true;
        set beresp.ttl = 120s;
        return (deliver);
    
    # You are respecting the Cache-Control=private header from the backend
    } elsif (beresp.http.Cache-Control ~ "private") {
        set beresp.http.X-Cacheable = "NO:Cache-Control=private";
        set beresp.uncacheable = true;
        set beresp.ttl = 120s;
        return (deliver);
    
    # Varnish determined the object was cacheable
    } else {
        set beresp.http.storage = "foo";
        set beresp.http.x-storage = "foo";
        set beresp.http.Cache-Control = "public, max-age=14900, s-maxage=14900";
        unset beresp.http.Pragma;
        unset beresp.http.expires;
    }
    
       #   set beresp.grace = 240m;
     set beresp.grace = 30m;
    
    return(deliver);
       }
       sub vcl_deliver {
        if (obj.hits > 0) {
                set resp.http.X-Cache = "HIT";
        } else {
                set resp.http.X-Cache = "MISS";
        }
    }