VCL code to enable purging

There are two ways to do purging, this one will just get rid of the single variant of the object that is hit, so it will not purge a compressed version if you hit the uncompressed, for instance.

acl purge {
        "localhost";
        "192.0.2.14";
}

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

sub vcl_hit {
        if (req.request == "PURGE") {
                set obj.ttl = 0s;
                error 200 "Purged.";
        }
}

sub vcl_miss {
        if (req.request == "PURGE") {
                error 404 "Not in cache.";
        }
}

The other option is to use purge_url like:

acl purge {
        "localhost";
        "192.0.2.14";
}

sub vcl_recv {
        if (req.request == "PURGE") {
                if (!client.ip ~ purge) {
                        error 405 "Not allowed.";
                }
                purge("req.url == " req.url " && req.http.host == " req.http.host);
                error 200 "Purged.";
        }

With this in your VCL file, we have implemented purging through HTTP. That means that if you now send a

PURGE / HTTP/1.0
Host: www.example.com

to Varnish over port 80 (restricted to client with IP 192.0.2.14), your / document from the www.example.com website will be purged.

However, this way of implementing purge does not support wildcard purge. If you want to do that, use something like:

acl purge {
        "localhost";
        "192.0.2.14";
}

sub vcl_recv {
        if (req.request == "PURGE") {
                if (!client.ip ~ purge) {
                        error 405 "Not allowed.";
                }
                purge("req.url ~ " req.url " && req.http.host == " req.http.host);
                error 200 "Purged.";
        }
}

where the URL is then a regular expression to purge.