Search code examples
varnishvarnish-4

Invalidate varnish by HTTP headers or by * in url


So I have some urls like this www.example.com/userID/productID this url sets this HTTP headers X-Cache-Tags: product-productID, user-userID, product

Now I want to purge all caches where X-Cache-Tags is product-productID or I want to purge all urls that are www.example.com/*/productID

Is that possible?


Solution

  • Here's the VCL code you need to make it happen:

    vcl 4.0;
    
    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-tag && !req.http.x-invalidate-pattern) {
                return(purge);
            }
            if(req.http.x-invalidate-tag) {
                ban("obj.http.X-Cache-Tags ~ " + req.http.x-invalidate-tag);
            } else {
                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;
    }
    

    There are 3 ways you can remove content from the cache using this VCL:

    1. Purge an individual URL
    2. Ban all objects that match a cache tag
    3. Ban all objects where the URL matches a pattern

    Purge URL

    When a request with an approved client IP performs an PURGE request, only the exact URL is used to remove an object from cache:

    curl -XPURGE http://example.com/20/100
    

    Ban using cache tags

    The following curl request will remove all objects from cache that have an X-Cache-Tags response header that contains the tag product-10:

    curl -XPURGE -H "x-invalidate-tag: product-10" http://example.com/
    

    Ban using URL pattern

    The following curl request will remove all objects from cache where for a product 10, for all users:

    curl -XPURGE -H "x-invalidate-pattern: ^/[0-9]+/10/?$" http://example.com/
    

    Conclusion

    As long as your VCL is flexible enough, you can use all kinds of mechanisms and rules to invalidate the cache.

    Please secure access to content invalidation via an ACL, as mentioned in the VCL example. You can also add extra protections such as password authentication or firewalling.