>From d1701c99b24e2455c44566c29fe7d5a01140df64 Mon Sep 17 00:00:00 2001
From: Nils Goroll <[email protected]>
Date: Thu, 18 Dec 2014 13:18:55 +0100
Subject: [PATCH] expose response 304 status to VCL

---
 bin/varnishd/cache/cache_fetch.c             |  3 ++-
 bin/varnishd/cache/cache_http.c              |  4 ++--
 bin/varnishtest/tests/b00039.vtc             |  7 +++++++
 doc/sphinx/users-guide/vcl-built-in-subs.rst | 16 +++++++++++++++-
 4 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 93d6ea7..c1d563b 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -404,7 +404,6 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
 		}
 		http_Unset(bo->beresp, H_Content_Length);
 		HTTP_Merge(bo->wrk, bo->ims_oc, bo->beresp);
-		assert(http_IsStatus(bo->beresp, 200));
 		do_ims = 1;
 	} else
 		do_ims = 0;
@@ -439,6 +438,8 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)
 
 	assert(bo->state == BOS_REQ_DONE);
 
+	if (do_ims && ! http_IsStatus(bo->beresp, 200))
+		http_SetStatus(bo->beresp, 200);
 	if (bo->do_esi)
 		bo->do_stream = 0;
 	if (bo->do_pass || bo->uncacheable)
diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c
index e655fa0..fbfddf6 100644
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@ -959,13 +959,13 @@ HTTP_Merge(struct worker *wrk, struct objcore *oc, struct http *to)
 	ptr = ObjGetattr(wrk, oc, OA_HEADERS, NULL);
 	AN(ptr);
 
-	to->status = vbe16dec(ptr + 2);
+	/* Skip nhd and status */
 	ptr += 4;
 
+	/* skip HTTP_HDR_PROTO, HTTP_HDR_STATUS, HTTP_HDR_REASON */
 	for (u = 0; u < HTTP_HDR_FIRST; u++) {
 		if (u == HTTP_HDR_METHOD || u == HTTP_HDR_URL)
 			continue;
-		http_SetH(to, u, ptr);
 		ptr = strchr(ptr, '\0') + 1;
 	}
 	while (*ptr != '\0') {
diff --git a/bin/varnishtest/tests/b00039.vtc b/bin/varnishtest/tests/b00039.vtc
index cf1e9dc..5417391 100644
--- a/bin/varnishtest/tests/b00039.vtc
+++ b/bin/varnishtest/tests/b00039.vtc
@@ -10,6 +10,10 @@ server s1 {
 
 varnish v1 -vcl+backend {
 	sub vcl_backend_response {
+		if (bereq.http.If-Modified-Since &&
+		    beresp.status != 304) {
+			return(abandon);
+		}
 		set beresp.ttl = 2s;
 		set beresp.grace = 20s;
 		set beresp.keep = 1m;
@@ -20,6 +24,7 @@ client c1 {
 	txreq
 	rxresp
 	expect resp.status == 200
+	expect resp.http.Last-Modified == "Wed, 11 Sep 2013 13:36:55 GMT"
 	expect resp.body == "Geoff Rules"
 } -run
 
@@ -29,6 +34,7 @@ client c1 {
 	txreq
 	rxresp
 	expect resp.status == 200
+	expect resp.http.Last-Modified == "Wed, 11 Sep 2013 13:36:55 GMT"
 	expect resp.body == "Geoff Rules"
 } -run
 
@@ -36,5 +42,6 @@ client c1 {
 	txreq
 	rxresp
 	expect resp.status == 200
+	expect resp.http.Last-Modified == "Wed, 11 Sep 2013 13:36:55 GMT"
 	expect resp.body == "Geoff Rules"
 } -run
diff --git a/doc/sphinx/users-guide/vcl-built-in-subs.rst b/doc/sphinx/users-guide/vcl-built-in-subs.rst
index cd78355..864a99f 100644
--- a/doc/sphinx/users-guide/vcl-built-in-subs.rst
+++ b/doc/sphinx/users-guide/vcl-built-in-subs.rst
@@ -277,11 +277,25 @@ vcl_backend_response
 Called after the response headers have been successfully retrieved from
 the backend.
 
+For a 304 response, varnish core code amends ``beresp`` before calling
+`vcl_backend_response`:
+
+* If the gzip status changed, ``Content-Encoding`` is unset and any
+  ``Etag`` is weakened
+
+* Any headers not present in the 304 response are copied from the
+  existing cache object. ``Content-Length`` is copied if present in
+  the existing cache object and discarded otherwise.
+
 The `vcl_backend_response` subroutine may terminate with calling
 ``return()`` with one of the following keywords:
 
   ``deliver``
-    For a 304 response, create an updated cache object.
+    For a 304 response, set the status to 200 and create an updated
+    cache object. Conditional requests will be handled on the client
+    side, so clients may still receive a 304 response based on their
+    requst headers.
+
     Otherwise, fetch the object body from the backend and initiate
     delivery to any waiting client requests, possibly in parallel
     (streaming).
-- 
2.1.3

_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev

Reply via email to