[4.0] a4d271d Add Range error handling with HTTP 416.

Lasse Karstensen lkarsten at varnish-software.com
Thu Jan 15 16:35:44 CET 2015


commit a4d271deb62d7af3f08813446ac1e4a585f729b2
Author: Lasse Karstensen <lkarsten at varnish-software.com>
Date:   Thu Jan 15 10:40:11 2015 +0100

    Add Range error handling with HTTP 416.
    
    A set of robustness fixes for Range handling backported from master.
    
    Patch by Federico G. Schwindt.

diff --git a/bin/varnishd/cache/cache_http1_deliver.c b/bin/varnishd/cache/cache_http1_deliver.c
index 623b07b..dcb290f 100644
--- a/bin/varnishd/cache/cache_http1_deliver.c
+++ b/bin/varnishd/cache/cache_http1_deliver.c
@@ -101,14 +101,12 @@ v1d_dorange(struct req *req, struct busyobj *bo, const char *r)
 	else
 		len = req->obj->len;
 
-	if (strncmp(r, "bytes=", 6))
+	if (strncasecmp(r, "bytes=", 6))
 		return;
 	r += 6;
 
 	/* The low end of range */
 	has_low = low = 0;
-	if (!vct_isdigit(*r) && *r != '-')
-		return;
 	while (vct_isdigit(*r)) {
 		has_low = 1;
 		low *= 10;
@@ -116,9 +114,6 @@ v1d_dorange(struct req *req, struct busyobj *bo, const char *r)
 		r++;
 	}
 
-	if (low >= len)
-		return;
-
 	if (*r != '-')
 		return;
 	r++;
@@ -131,22 +126,31 @@ v1d_dorange(struct req *req, struct busyobj *bo, const char *r)
 			high += *r - '0';
 			r++;
 		}
+		if (high < low)
+			return;
 		if (!has_low) {
 			low = len - high;
 			if (low < 0)
 				low = 0;
 			high = len - 1;
-		}
-	} else
+		} else if (high >= len)
+			high = len - 1;
+	} else if (has_low)
 		high = len - 1;
-	if (*r != '\0')
+	else
 		return;
 
-	if (high >= len)
-		high = len - 1;
+	if (*r != '\0')
+		return;
 
-	if (low > high)
+	if (low >= len) {
+		http_PrintfHeader(req->resp, "Content-Range: bytes */%jd",
+		    (intmax_t)len);
+		http_Unset(req->resp, H_Content_Length);
+		http_PutResponse(req->resp, "HTTP/1.1", 416, NULL);
+		req->wantbody = 0;
 		return;
+	}
 
 	http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd",
 	    (intmax_t)low, (intmax_t)high, (intmax_t)len);
diff --git a/bin/varnishtest/tests/c00034.vtc b/bin/varnishtest/tests/c00034.vtc
index 23910de..9eeee15 100644
--- a/bin/varnishtest/tests/c00034.vtc
+++ b/bin/varnishtest/tests/c00034.vtc
@@ -5,13 +5,11 @@ server s1 {
 	txresp -bodylen 100
 } -start
 
-varnish v1 -vcl+backend {
-
+varnish v1 -arg "-p http_range_support=off" -vcl+backend {
 	sub vcl_backend_response {
 		set beresp.do_stream = false;
 	}
 } -start
-varnish v1 -cliok "param.set http_range_support off"
 
 client c1 {
 	txreq -hdr "Range: bytes=0-9"
@@ -45,61 +43,71 @@ client c1 {
 	expect resp.status == 200
 	expect resp.bodylen == 100
 
+	txreq -hdr "Range: bytes=-"
+	rxresp
+	expect resp.status == 200
+	expect resp.bodylen == 100
+
+	txreq -hdr "Range: bytes=5-2"
+	rxresp
+	expect resp.status == 200
+	expect resp.bodylen == 100
 } -run
 
-varnish v1 -expect s_resp_bodybytes == 500
+varnish v1 -expect s_resp_bodybytes == 700
 
 client c1 {
-
-	txreq -hdr "Range: bytes=0-9"
+	txreq -hdr "Range: bytes=-0"
 	rxresp
-	expect resp.status == 206
-	expect resp.bodylen == 10
+	expect resp.status == 416
+	expect resp.bodylen == 0
+	expect resp.http.content-range == "bytes */100"
 
-	txreq -hdr "Range: bytes=10-19"
+	txreq -hdr "Range: bytes=100-"
 	rxresp
-	expect resp.status == 206
-	expect resp.bodylen == 10
+	expect resp.status == 416
+	expect resp.bodylen == 0
+	expect resp.http.content-range == "bytes */100"
+} -run
 
-	txreq -hdr "Range: bytes=90-"
-	rxresp
-	expect resp.status == 206
-	expect resp.bodylen == 10
+varnish v1 -expect s_resp_bodybytes == 700
 
-	txreq -hdr "Range: bytes=-9"
+client c1 {
+	txreq -hdr "Range: bytes=0-49"
 	rxresp
 	expect resp.status == 206
-	expect resp.bodylen == 9
+	expect resp.bodylen == 50
+	expect resp.http.content-range == "bytes 0-49/100"
 
-	txreq -hdr "Range: bytes=-"
+	txreq -hdr "Range: bytes=50-99"
 	rxresp
 	expect resp.status == 206
-	expect resp.bodylen == 100
-
-	txreq -hdr "Range: bytes=102-102"
-	rxresp
-	expect resp.status == 200
-	expect resp.bodylen == 100
+	expect resp.bodylen == 50
+	expect resp.http.content-range == "bytes 50-99/100"
 
-	txreq -hdr "Range: bytes=99-"
+	txreq -hdr "Range: bytes=-50"
 	rxresp
 	expect resp.status == 206
-	expect resp.bodylen == 1
+	expect resp.bodylen == 50
+	expect resp.http.content-range == "bytes 50-99/100"
 
-	txreq -hdr "Range: bytes=99-70"
+	txreq -hdr "Range: bytes=50-"
 	rxresp
-	expect resp.status == 200
-	expect resp.bodylen == 100
+	expect resp.status == 206
+	expect resp.bodylen == 50
+	expect resp.http.content-range == "bytes 50-99/100"
 
-	txreq -hdr "Range: bytes=-"
+	txreq -hdr "Range: bytes=0-0"
 	rxresp
 	expect resp.status == 206
-	expect resp.bodylen == 100
+	expect resp.bodylen == 1
+	expect resp.http.content-range == "bytes 0-0/100"
 
-	txreq -hdr "Range: bytes=-101"
+	txreq -hdr "Range: bytes=-2000"
 	rxresp
 	expect resp.status == 206
 	expect resp.bodylen == 100
+	expect resp.http.content-range == "bytes 0-99/100"
 } -run
 
-varnish v1 -expect s_resp_bodybytes == 1040
+varnish v1 -expect s_resp_bodybytes == 1001



More information about the varnish-commit mailing list