Hi,

After Per's recent post (1) and discussing it with him here's a patch that
uses this to initialize beresp.grace.
I've reused cache_rfc2616.c but perhaps this should be moved into its own
file, i.e. cache_rfc5861.c.
Comments?

f.-

1.
https://www.varnish-software.com/blog/grace-varnish-4-stale-while-revalidate-semantics-varnish
 bin/varnishd/cache/cache.h         |  3 ++-
 bin/varnishd/cache/cache_fetch.c   |  2 ++
 bin/varnishd/cache/cache_rfc2616.c | 32 +++++++++++++++++++++++++++++
 bin/varnishtest/tests/b00043.vtc   | 41 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 2b10f59..759633f 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -1244,12 +1244,13 @@ char *WS_Snapshot(struct ws *ws);
 int WS_Overflowed(const struct ws *ws);
 void *WS_Printf(struct ws *ws, const char *fmt, ...) __printflike(2, 3);
 
-/* rfc2616.c */
+/* cache_rfc2616.c */
 void RFC2616_Ttl(struct busyobj *, double now);
 enum body_status RFC2616_Body(struct busyobj *, struct dstat *);
 unsigned RFC2616_Req_Gzip(const struct http *);
 int RFC2616_Do_Cond(const struct req *sp);
 void RFC2616_Weaken_Etag(struct http *hp);
+void RFC5861_Stale(struct busyobj *);
 
 
 /* stevedore.c */
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index a768170..c4ad0f1 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -348,6 +348,8 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
        EXP_Clr(&bo->exp);
        RFC2616_Ttl(bo, now);
 
+       RFC5861_Stale(bo);
+
        /* private objects have negative TTL */
        if (bo->fetch_objcore->flags & OC_F_PRIVATE)
                bo->exp.ttl = -1.;
diff --git a/bin/varnishd/cache/cache_rfc2616.c 
b/bin/varnishd/cache/cache_rfc2616.c
index bb0a85e..3db28f6 100644
--- a/bin/varnishd/cache/cache_rfc2616.c
+++ b/bin/varnishd/cache/cache_rfc2616.c
@@ -365,3 +365,35 @@ RFC2616_Weaken_Etag(struct http *hp)
        http_Unset(hp, H_ETag);
        http_PrintfHeader(hp, "ETag: W/%s", p);
 }
+
+/*
+ * RFC5861 outlines a way to control the use of stale responses.
+ * We use this to initialize the grace period.
+ */
+
+void
+RFC5861_Stale(struct busyobj *bo)
+{
+       char *p;
+       const struct http *hp;
+       struct exp *expp;
+
+       expp = &bo->exp;
+
+       /*
+        * If we are not meant to cache this ignore any potential
+        * stale-while-revalidate values.
+        */
+       if (expp->ttl <= 0.)
+               return;
+
+       hp = bo->beresp;
+
+       if (http_GetHdrField(hp, H_Cache_Control,
+           "stale-while-revalidate", &p) && p != NULL) {
+               if (*p == '-')
+                       expp->grace = 0;
+               else
+                       expp->grace = strtoul(p, NULL, 0);
+       }
+}
diff --git a/bin/varnishtest/tests/b00043.vtc b/bin/varnishtest/tests/b00043.vtc
new file mode 100644
index 0000000..e5b5102
--- /dev/null
+++ b/bin/varnishtest/tests/b00043.vtc
@@ -0,0 +1,41 @@
+varnishtest "Test stale-while-revalidate"
+
+server s1 {
+       rxreq
+       txresp -hdr "Cache-Control: max-age=30, stale-while-revalidate=30"
+       rxreq
+       txresp -hdr "Cache-Control: max-age=0, stale-while-revalidate=30"
+       rxreq
+       txresp -hdr "Cache-Control: max-age=30, stale-while-revalidate=30" -hdr 
"Age: 40"
+       rxreq
+       txresp -status 500 -hdr "Cache-Control: max-age=30, 
stale-while-revalidate=30"
+} -start
+
+varnish v1 -vcl+backend {
+       sub vcl_backend_response {
+               set beresp.http.grace = beresp.grace;
+               set beresp.http.ttl = beresp.ttl;
+       }
+} -start
+
+client c1 {
+       txreq -url /1
+       rxresp
+       expect resp.http.grace == 30.000
+       expect resp.http.ttl == 30.000
+
+       txreq -url /2
+       rxresp
+       expect resp.http.grace == 10.000
+       expect resp.http.ttl == 0.000
+
+       txreq -url /3
+       rxresp
+       expect resp.http.grace == 10.000
+       expect resp.http.ttl == 0.000
+
+       txreq -url /4
+       rxresp
+       expect resp.http.grace == 10.000
+       expect resp.http.ttl == 0.000
+} -run
_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev

Reply via email to