[master] ea7a162 If there is a C-L in the object, trust it for Range header purposes.

Poul-Henning Kamp phk at FreeBSD.org
Tue May 5 14:29:24 CEST 2015


commit ea7a162f81bb5fd6a39d4ca6cea3d052e15e9dc0
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue May 5 12:29:01 2015 +0000

    If there is a C-L in the object, trust it for Range header purposes.

diff --git a/bin/varnishd/cache/cache_range.c b/bin/varnishd/cache/cache_range.c
index 31ec81e..3bb4753 100644
--- a/bin/varnishd/cache/cache_range.c
+++ b/bin/varnishd/cache/cache_range.c
@@ -86,13 +86,11 @@ vrg_range_bytes(struct req *req, enum vdp_action act, void **priv,
 /*--------------------------------------------------------------------*/
 
 static int
-vrg_dorange(struct req *req, const struct busyobj *bo, ssize_t len,
-    const char *r)
+vrg_dorange(struct req *req, ssize_t len, const char *r)
 {
 	ssize_t low, high, has_low, has_high, t;
 	struct vrg_priv *vrg_priv;
 
-	(void)bo;
 	if (strncasecmp(r, "bytes=", 6))
 		return (__LINE__);
 	r += 6;
@@ -129,7 +127,7 @@ vrg_dorange(struct req *req, const struct busyobj *bo, ssize_t len,
 		return (__LINE__);
 
 	if (!has_low) {
-		if (bo != NULL)
+		if (len < 0)
 			return (0);		// Allow 200 response
 		if (high == 0)
 			return (__LINE__);
@@ -137,7 +135,7 @@ vrg_dorange(struct req *req, const struct busyobj *bo, ssize_t len,
 		if (low < 0)
 			low = 0;
 		high = len - 1;
-	} else if (bo == NULL && (high >= len || !has_high))
+	} else if (len >= 0 && (high >= len || !has_high))
 		high = len - 1;
 	else if (!has_high)
 		return (0);			// Allow 200 response
@@ -151,11 +149,15 @@ vrg_dorange(struct req *req, const struct busyobj *bo, ssize_t len,
 	if (high < low)
 		return (__LINE__);
 
-	if (bo == NULL && low >= len)
+	if (len >= 0 && low >= len)
 		return (__LINE__);
 
-	http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd",
-	    (intmax_t)low, (intmax_t)high, (intmax_t)len);
+	if (len >= 0)
+		http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd",
+		    (intmax_t)low, (intmax_t)high, (intmax_t)len);
+	else
+		http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/*",
+		    (intmax_t)low, (intmax_t)high);
 	req->resp_len = (intmax_t)(1 + high - low);
 	http_PutResponse(req->resp, "HTTP/1.1", 206, NULL);
 
@@ -172,7 +174,7 @@ vrg_dorange(struct req *req, const struct busyobj *bo, ssize_t len,
 void
 VRG_dorange(struct req *req, struct busyobj *bo, const char *r)
 {
-	size_t len;
+	ssize_t len;
 	int i;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
@@ -180,12 +182,17 @@ VRG_dorange(struct req *req, struct busyobj *bo, const char *r)
 	assert(http_IsStatus(req->resp, 200));
 
 	/* We must snapshot the length if we're streaming from the backend */
-	if (bo != NULL)
-		len = VBO_waitlen(req->wrk, bo, -1);
-	else
+	if (bo != NULL) {
+		len = http_GetContentLength(bo->beresp);
+VSLb(req->vsl, SLT_Debug, "UUU 1 %jd", (intmax_t)len);
+#if 0
+		if (len < 0)
+			len = VBO_waitlen(req->wrk, bo, -1);
+#endif
+	} else
 		len = ObjGetLen(req->wrk, req->objcore);
 
-	i = vrg_dorange(req, bo, len, r);
+	i = vrg_dorange(req, len, r);
 	if (i) {
 		VSLb(req->vsl, SLT_Debug, "RANGE_FAIL line %d", i);
 		http_Unset(req->resp, H_Content_Length);
diff --git a/bin/varnishtest/tests/c00034.vtc b/bin/varnishtest/tests/c00034.vtc
index f479498..ee46e29 100644
--- a/bin/varnishtest/tests/c00034.vtc
+++ b/bin/varnishtest/tests/c00034.vtc
@@ -113,3 +113,60 @@ client c1 {
 } -run
 
 varnish v1 -expect s_resp_bodybytes == 401
+
+# Test Range streaming with streaming objects with C-L
+
+server s1 -repeat 2 {
+	rxreq
+	txresp -nolen -hdr "Content-Length: 100"
+	send "0123456789"
+	send "0123456789"
+	send "0123456789"
+	send "0123456789"
+	send "0123456789"
+	sema r1 sync 2
+	send "0123456789"
+	send "0123456789"
+	send "0123456789"
+	send "0123456789"
+	send "0123456789"
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_backend_response {
+		if (bereq.url == "/2") {
+			set beresp.do_gzip = true;
+		}
+	}
+}
+
+client c1 {
+	# Open ended range to force C-L usage
+	txreq -url /1 \
+		-hdr "Range: bytes=20-" \
+		-hdr "Connection: close"
+	rxresphdrs
+	expect resp.status == 206
+	expect resp.http.Content-Range == "bytes 20-99/100"
+	recv 10
+	sema r1 sync 2
+	recv 70
+	expect_close
+} -run
+
+delay .1
+
+client c1 {
+	# Closed C-L because we cannot use C-L
+	txreq -url /2 \
+		-hdr "Range: bytes=20-29" \
+		-hdr "Connection: close" \
+		-hdr "Accept-encoding: gzip"
+	rxresphdrs
+	expect resp.status == 206
+	expect resp.http.Content-Range == "bytes 20-29/*"
+	expect resp.http.Content-Length == 10
+	sema r1 sync 2
+	recv 10
+	expect_close
+} -run



More information about the varnish-commit mailing list