[4.1] 926c9ee For range requests we need a strong validator

Lasse Karstensen lkarsten at varnish-software.com
Thu Jan 14 15:15:09 CET 2016


commit 926c9ee46b7a3d30e9d7ca75dc2ee7660921cbe2
Author: Federico G. Schwindt <fgsch at lodoss.net>
Date:   Sat Dec 12 12:14:50 2015 +0000

    For range requests we need a strong validator
    
    That is, if both If-None-Match and Range are present we need to use a
    strong comparison as the representation needs to be byte-for-byte
    identical.

diff --git a/bin/varnishd/cache/cache_rfc2616.c b/bin/varnishd/cache/cache_rfc2616.c
index d3fa8a2..0c0e127 100644
--- a/bin/varnishd/cache/cache_rfc2616.c
+++ b/bin/varnishd/cache/cache_rfc2616.c
@@ -233,13 +233,22 @@ RFC2616_Req_Gzip(const struct http *hp)
 /*--------------------------------------------------------------------*/
 
 static inline int
+rfc2616_strong_compare(const char *p, const char *e)
+{
+	if ((p[0] == 'W' && p[1] == '/') ||
+	    (e[0] == 'W' && e[1] == '/'))
+		return (0);
+	return (strcmp(p, e) == 0);
+}
+
+static inline int
 rfc2616_weak_compare(const char *p, const char *e)
 {
 	if (p[0] == 'W' && p[1] == '/')
 		p += 2;
 	if (e[0] == 'W' && e[1] == '/')
 		e += 2;
-	return (strcmp(p, e) != 0);
+	return (strcmp(p, e) == 0);
 }
 
 int
@@ -255,9 +264,12 @@ RFC2616_Do_Cond(const struct req *req)
 	 */
 	if (http_GetHdr(req->http, H_If_None_Match, &p) &&
 	    http_GetHdr(req->resp, H_ETag, &e)) {
-		if (rfc2616_weak_compare(p, e))
+		if (http_GetHdr(req->http, H_Range, NULL))
+			do_cond = rfc2616_strong_compare(p, e);
+		else
+			do_cond = rfc2616_weak_compare(p, e);
+		if (!do_cond)
 			return (0);
-		do_cond = 1;
 	}
 
 	if (http_GetHdr(req->http, H_If_Modified_Since, &p)) {
diff --git a/bin/varnishtest/tests/c00025.vtc b/bin/varnishtest/tests/c00025.vtc
index 9b7fc95..f5b8988 100644
--- a/bin/varnishtest/tests/c00025.vtc
+++ b/bin/varnishtest/tests/c00025.vtc
@@ -27,6 +27,10 @@ client c1 {
 	rxresp -no_obj
 	expect resp.status == 304
 
+	txreq -hdr "Range: bytes=1-2" -hdr {If-None-Match: "123456789"}
+	rxresp -no_obj
+	expect resp.status == 304
+
 	txreq -hdr {If-None-Match: W/"12345678"}
 	rxresp
 	expect resp.status == 200
@@ -34,9 +38,11 @@ client c1 {
 	txreq -hdr {If-None-Match: W/"123456789"}
 	rxresp -no_obj
 	expect resp.status == 304
-} -run
 
-client c2 {
+	txreq -hdr "Range: bytes=1-2" -hdr {If-None-Match: W/"123456789"}
+	rxresp
+	expect resp.status == 206
+
 	txreq -url /other
 	rxresp
 	expect resp.status == 200
@@ -51,6 +57,11 @@ client c2 {
 	rxresp -no_obj
 	expect resp.status == 304
 
+	txreq -url /other -hdr "Range: bytes=1-2" \
+	    -hdr {If-None-Match: "123456789"}
+	rxresp
+	expect resp.status == 206
+
 	txreq -url /other -hdr {If-None-Match: W/"12345678"}
 	rxresp
 	expect resp.status == 200
@@ -58,4 +69,9 @@ client c2 {
 	txreq -url /other -hdr {If-None-Match: W/"123456789"}
 	rxresp -no_obj
 	expect resp.status == 304
+
+	txreq -url /other -hdr "Range: bytes=1-2" \
+	    -hdr {If-None-Match: W/"123456789"}
+	rxresp
+	expect resp.status == 206
 } -run



More information about the varnish-commit mailing list