Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PURGE fails in Varnish cache

I am using the following code to PURGE the homepage of a site:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "http://www.mysite.com:8080/");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PURGE");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 1000);

$r = curl_exec($ch);

echo "<PRE>$r</PRE>";

curl_close($ch);

The response from Varnish is as expected:

HTTP/1.1 200 Purged.
Server: Varnish
Content-Type: text/html; charset=utf-8
Retry-After: 5
Content-Length: 382
Accept-Ranges: bytes
Date: Fri, 10 Aug 2012 10:50:56 GMT
X-Varnish: 617777456
Age: 0
Via: 1.1 varnish
Connection: close
X-Cache: MISS

So now I think that it is purged, but a further call to the page to check the headers suggest that it is not purged. As Age: 15 and X-Cache: HIT are both set, suggesting that the page is still cached and is 15 seconds old.

The TTL is 120.

Am I missing something?

Thanks Jake

like image 777
Jake N Avatar asked Jan 16 '23 20:01

Jake N


2 Answers

To eliminate all other php/curl issues I would start with the most basic low-level check.

This works for me:

netcat -C varnish_hostname 80 <<EOF
PURGE /the/url
Host: hostname

EOF
  • Replace varnish_hostname by your actual varnish hostname.
  • Replace 80 by the actual port varnish listens on.
  • Replace /the/url by the path part of the url to purge
  • Replace hostname by the hostname part in the URL you want to purge.

Once you get this to work, you know that your VCL rules and ACLs are not an issue and you may proceed to the curl/php level.

EDIT Two notes:

  1. you may have to type the above fast to prevent the connection from closing prematurely because many http stacks these days don't allow a long delay between the connection establishment and the HTTP request to prevent half-open DoS attacks. You can achieve this by preparing the whole input ahead of time, copy it to your paste buffer, and pasting the whole blurb with one click of the mouse.
  2. The HTTP request header has to end with a double new line as shown above. The netcat -C option is there to convert newlines to CRLF char pairs per the HTTP protocol.
like image 187
arielf Avatar answered Jan 18 '23 10:01

arielf


I think you would not have checked for purging in the default.vcl The default.vcl should contain something like following:

acl purge {
        "localhost";
        "192.168.55.0"/24;
}

sub vcl_recv {
        # allow PURGE from localhost and 192.168.55...

        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") {
                error 200 "OK but nothing to purge - URL was not in cache";
        }
}
like image 32
deep Avatar answered Jan 18 '23 11:01

deep