Search code examples
regexvarnishcache-controlvarnish-vcl

How to invalidate varnish cached object with Ban expression


Consider my requested url is www.example.com/foo/emplooyee?names = test1;test2. and varnish stores this entire URL along with query parameters to uniquely identify the cache.

now, in my backend, I'm running one service and which I'm supposed to configure as whenever there are changes in names (i.e. test1 or test2) is should fire an HTTP ban with an older name (single name at a time in ban expression) to invalidate all the cached URL which entered with similar names.

Questions: My client request url could be like this,

How to write a VCL code and in Ban expression to invalidate all object which has query parameter as test1?


Solution

  • This is the VCL code you need for banning:

    vcl 4.1;
    
    acl purge {
        "localhost";
        "192.168.55.0"/24;
    }
    
    sub vcl_recv {
        if (req.method == "PURGE") {
            if (!client.ip ~ purge) {
                return(synth(405));
            }
            if(!req.http.x-invalidate-pattern) {
                return(purge);
            }
            ban("obj.http.x-url ~ " + req.http.x-invalidate-pattern
                + " && obj.http.x-host == " + req.http.host);
            return (synth(200,"Ban added"));
        }
    }
    
    sub vcl_backend_response {
        set beresp.http.x-url = bereq.url;
        set beresp.http.x-host = bereq.http.host;
    }
    
    sub vcl_deliver {
        unset resp.http.x-url;
        unset resp.http.x-host;
    }
    

    Here's an example HTTP request to invalidate all requests that contain a test1 value in the query string:

    PURGE / HTTP/1.1
    Host: www.example.com
    X-Invalidate-Pattern: ^/foo/emplooyee\?names=([^;]+;)*test1(;[^;]+)*$
    

    Here's the same request via curl:

    curl -XPURGE -H'X-Invalidate-Pattern: ^/foo/emplooyee\?names=([^;]+;)*test1(;[^;]+)*$' http://www.example.com
    

    This VCL snippet has the flexibility to remove multiple items from cache through banning, but if you don't set the pattern through the X-Invalidate-Pattern header, it will just remove the URL itself from cache.

    Here's an example where we just remove http://www.example.com/foo/emplooyee?names=test1 from the cache:

    curl -XPURGE 'http://www.example.com/foo/emplooyee?names=test1'
    

    Don't forget to modify the acl block in the VCL code and add the right IP addresses or IP ranges.