Not seeing a successful purge

John Norman john at 7fff.com
Thu Feb 11 23:25:18 CET 2010


Hi, folks.

I'm trying to purge with the pseudo HTTP "PURGE" method Varnish supports.

I do seem to have a cached page, but the PURGE response suggests that
it's missing.

So . . . any idea why the PURGE isn't working?

In my VCL, my vcl_hash looks like this (I intend it to only hash on
the request URL and compression):

sub vcl_hash {
  set req.hash += req.url;

  if (req.http.Accept-Encoding ~ "gzip") {
    set req.hash += "gzip";
  } else if (req.http.Accept-Encoding ~ "deflate") {
    set req.hash += "deflate";
  }
  return (hash);
}

And the checks for PURGE look like this (full VCL way below):

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

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

And in vcl_recv:

  if (req.request == "PURGE") {
    lookup;
  }

Below is some output from varnishlog, first showing the return of the
cached page -- then the response for the PURGE.

The request from the browser comes through HAProxy first, then into Varnish.

The PURGE request is via Ruby Mechanize.

4 ReqStart     c 10.253.191.95 60271 904319188
4 RxRequest    c GET
4 RxURL        c /products/sillyputty
4 RxProtocol   c HTTP/1.1
4 RxHeader     c Host: staging1.example.com
4 RxHeader     c User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X
10.5; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB7.0
4 RxHeader     c Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
4 RxHeader     c Accept-Language: en-us,en;q=0.5
4 RxHeader     c Accept-Encoding: gzip,deflate
4 RxHeader     c Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
4 RxHeader     c Keep-Alive: 300
4 RxHeader     c Connection: keep-alive
4 RxHeader     c Cookie: cehq-id=10.252.66.194.1263417178788050;
__utma=240927894.185175319.1263417179.1265907679.1265923273.61;
__utmz=240927894.1263591912.11.2.utmcsr=localhost:3000|utmccn=(referral)|utmcmd=referral|utmcct=/;
__utma=229000926.194920698.1263480064.126591
4 RxHeader     c X-Forwarded-For: 75.150.106.113
4 VCL_call     c recv
4 VCL_return   c lookup
4 VCL_call     c hash
4 VCL_return   c hash
4 Hit          c 904319089
4 VCL_call     c hit
4 VCL_return   c deliver
4 Length       c 13825
4 VCL_call     c deliver
4 VCL_return   c deliver
4 TxProtocol   c HTTP/1.1
4 TxStatus     c 200
4 TxResponse   c OK
4 TxHeader     c Server: Apache/2.2.12 (Ubuntu)
4 TxHeader     c X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9
4 TxHeader     c Cache-Control: max-age=7680, public
4 TxHeader     c X-Runtime: 56860
4 TxHeader     c ETag: "1de74468f783ce10a7af58decf0b5871"
4 TxHeader     c Status: 200
4 TxHeader     c Vary: Accept-Encoding,User-Agent
4 TxHeader     c Content-Encoding: gzip
4 TxHeader     c Content-Type: text/html; charset=utf-8
4 TxHeader     c Content-Length: 13825
4 TxHeader     c Date: Thu, 11 Feb 2010 22:09:33 GMT
4 TxHeader     c X-Varnish: 904319188 904319089
4 TxHeader     c Age: 852
4 TxHeader     c Via: 1.1 varnish
4 TxHeader     c Connection: keep-alive
4 ReqEnd       c 904319188 1265926173.262102842 1265926173.262276649
0.000060797 0.000109196 0.000064611

4 ReqStart     c 10.253.191.95 60313 904319225
4 RxRequest    c PURGE
4 RxURL        c /products/sillyputty
4 RxProtocol   c HTTP/1.1
4 RxHeader     c Accept: */*
4 RxHeader     c User-Agent: WWW-Mechanize/1.0.0
(http://rubyforge.org/projects/mechanize/)
4 RxHeader     c Connection: keep-alive
4 RxHeader     c Keep-Alive: 300
4 RxHeader     c Accept-Encoding: gzip,identity
4 RxHeader     c Accept-Language: en-us,en;q=0.5
4 RxHeader     c Host: staging1:8000
4 RxHeader     c Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
4 VCL_call     c recv
4 VCL_return   c lookup
4 VCL_call     c hash
4 VCL_return   c hash
4 VCL_call     c miss
0 Debug        - "VCL_error(404, Not in cache.)"
4 VCL_return   c error
4 VCL_call     c error
4 VCL_return   c deliver
4 Length       c 340
4 VCL_call     c deliver
4 VCL_return   c deliver
4 TxProtocol   c HTTP/1.1
4 TxStatus     c 404
4 TxResponse   c Not in cache.
4 TxHeader     c Server: Varnish
4 TxHeader     c Retry-After: 0
4 TxHeader     c Content-Type: text/html; charset=utf-8
4 TxHeader     c Content-Length: 340
4 TxHeader     c Date: Thu, 11 Feb 2010 22:10:02 GMT
4 TxHeader     c X-Varnish: 904319225
4 TxHeader     c Age: 0
4 TxHeader     c Via: 1.1 varnish
4 TxHeader     c Connection: close
4 ReqEnd       c 904319225 1265926202.794907331 1265926202.795089960
0.000054121 0.000142574 0.000040054

For the sake of completeness, here's the full VCL (the reason for the
director with one server is 'cos on product we round-robin against 3
backends):

backend reviews0 {
  .host = "10.253.191.95";
  .port = "7000";

#    .probe = {
#      .url = "/heartbeat";
#      .timeout = 10.0 s;
#      .interval = 120 s;
#      .window = 10;
#      .threshold = 7;
#    }

}


director reviews round-robin {

    { .backend = reviews0; }

}

sub vcl_hash {
  set req.hash += req.url;

  if (req.http.Accept-Encoding ~ "gzip") {
    set req.hash += "gzip";
  } else if (req.http.Accept-Encoding ~ "deflate") {
    set req.hash += "deflate";
  }
  return (hash);
}

sub vcl_recv {

  set req.backend = reviews;

  set req.grace = 2m;

  unset req.http.user-agent;

  # Workaround for Varnish bug in handling x-forwarded-for
  # The bug should be fixed in 2.0.7, and allow for taking the prior
proxy's x-forwarded-for
  # See http://varnish-cache.org/ticket/601
  #     https://wiki.fourkitchens.com/display/PF/Workaround+for+Varnish+X-Forwarded-For+bug
  if (req.http.X-Forwarded-For) {
    set req.http.X-Real-Forwarded-For = req.http.X-Forwarded-For ", "
regsub(client.ip, ":.*", "");
    unset req.http.X-Forwarded-For;
  } else {
    set req.http.X-Real-Forwarded-For = regsub(client.ip, ":.*", "");
  }

  # Remove some irrelevant parameters from the URL
  set req.url = regsuball(req.url,
"(\?|&)(qid|x|y|country|reviewId)=[^?&]*", "");
  # Put the ? back in if we removed it and need it
  if (req.url !~ "\?" && req.url ~ "&") {
    set req.url = regsub(req.url, "&", "?");
  }

  if (req.request == "PURGE") {
    lookup;
  }

	if (req.request == "POST") {
		pass;
	}

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

  if (req.http.Authorization) {
		# Not cacheable by default
		pass;
  }

	lookup;
}

sub vcl_fetch {

  set obj.grace = 2m;

  unset obj.http.user-agent;

	if (!obj.cacheable) {
	    pass;
	}

	if (obj.http.Pragma ~ "no-cache" ||
	  obj.http.Cache-Control ~ "no-cache" ||
	  obj.http.Cache-Control ~ "private") {
	       pass;
	}

	if (obj.http.Cache-Control ~ "public") {
    unset obj.http.Set-Cookie;
		deliver;
	}
	pass;
}

# Implement PURGE: See http://varnish.projects.linpro.no/wiki/VCLExampleAlexc
sub vcl_hit {
  if (req.request == "PURGE") {
    set obj.ttl = 0s;
    error 200 "Purged.";
  }
  if (!obj.cacheable) {
    pass;
  }

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

# Standard error, but without the Guru meditation line
sub vcl_error {
  set obj.http.Content-Type = "text/html; charset=utf-8";
  synthetic {"
 	<?xml version="1.0" encoding="utf-8"?>
 	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 	 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 	<html>
 	  <head>
 	    <title>"} obj.status " " obj.response {"</title>
 	  </head>
 	  <body>
 	    <h1>Error "} obj.status " " obj.response {"</h1>
 	    <p>"} obj.response {"</p>
 	    <hr>
 	  </body>
 	</html>
  "};
  return (deliver);
}


More information about the varnish-misc mailing list