[master] 092ab4d Get closer to req->resp_len meaning "bytes to actually send, if known"

Poul-Henning Kamp phk at FreeBSD.org
Thu May 7 11:12:57 CEST 2015


commit 092ab4d952a8d88e2c665cf43d57a8fae112d54a
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu May 7 09:12:09 2015 +0000

    Get closer to req->resp_len meaning "bytes to actually send, if known"

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index bad856f..71dc7b0 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -985,7 +985,7 @@ size_t V1L_Write(const struct worker *w, const void *ptr, ssize_t len);
 task_func_t VPX_Proto_Sess;
 
 /* cache_range.c [VRG] */
-void VRG_dorange(struct req *req, const struct busyobj *bo, const char *r);
+void VRG_dorange(struct req *req, const char *r);
 
 /* cache_req.c */
 struct req *Req_New(const struct worker *, struct sess *);
diff --git a/bin/varnishd/cache/cache_range.c b/bin/varnishd/cache/cache_range.c
index fcff78a..55a78ba 100644
--- a/bin/varnishd/cache/cache_range.c
+++ b/bin/varnishd/cache/cache_range.c
@@ -86,7 +86,7 @@ vrg_range_bytes(struct req *req, enum vdp_action act, void **priv,
 /*--------------------------------------------------------------------*/
 
 static int
-vrg_dorange(struct req *req, ssize_t len, const char *r)
+vrg_dorange(struct req *req, const char *r)
 {
 	ssize_t low, high, has_low, has_high, t;
 	struct vrg_priv *vrg_priv;
@@ -127,16 +127,16 @@ vrg_dorange(struct req *req, ssize_t len, const char *r)
 		return (__LINE__);
 
 	if (!has_low) {
-		if (len < 0)
+		if (req->resp_len < 0)
 			return (0);		// Allow 200 response
 		if (high == 0)
 			return (__LINE__);
-		low = len - high;
+		low = req->resp_len - high;
 		if (low < 0)
 			low = 0;
-		high = len - 1;
-	} else if (len >= 0 && (high >= len || !has_high))
-		high = len - 1;
+		high = req->resp_len - 1;
+	} else if (req->resp_len >= 0 && (high >= req->resp_len || !has_high))
+		high = req->resp_len - 1;
 	else if (!has_high)
 		return (0);			// Allow 200 response
 	/*
@@ -149,12 +149,12 @@ vrg_dorange(struct req *req, ssize_t len, const char *r)
 	if (high < low)
 		return (__LINE__);
 
-	if (len >= 0 && low >= len)
+	if (req->resp_len >= 0 && low >= req->resp_len)
 		return (__LINE__);
 
-	if (len >= 0)
+	if (req->resp_len >= 0)
 		http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd",
-		    (intmax_t)low, (intmax_t)high, (intmax_t)len);
+		    (intmax_t)low, (intmax_t)high, (intmax_t)req->resp_len);
 	else
 		http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/*",
 		    (intmax_t)low, (intmax_t)high);
@@ -172,9 +172,8 @@ vrg_dorange(struct req *req, ssize_t len, const char *r)
 }
 
 void
-VRG_dorange(struct req *req, const struct busyobj *bo, const char *r)
+VRG_dorange(struct req *req, const char *r)
 {
-	ssize_t len;
 	int i;
 
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
@@ -182,19 +181,17 @@ VRG_dorange(struct req *req, const 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 = http_GetContentLength(bo->beresp);
-	else
-		len = ObjGetLen(req->wrk, req->objcore);
 
-	i = vrg_dorange(req, len, r);
+	i = vrg_dorange(req, r);
 	if (i) {
 		VSLb(req->vsl, SLT_Debug, "RANGE_FAIL line %d", i);
 		http_Unset(req->resp, H_Content_Length);
-		if (bo == NULL)
+		if (req->resp_len >= 0)
 			http_PrintfHeader(req->resp,
-			    "Content-Range: bytes */%jd", (intmax_t)len);
+			    "Content-Range: bytes */%jd",
+			    (intmax_t)req->resp_len);
 		http_PutResponse(req->resp, "HTTP/1.1", 416, NULL);
+		req->resp_len = -1;
 		req->wantbody = 0;
 	}
 }
diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c
index c2cc57c..e541f01 100644
--- a/bin/varnishd/http1/cache_http1_deliver.c
+++ b/bin/varnishd/http1/cache_http1_deliver.c
@@ -70,7 +70,10 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
 
 	req->res_mode = 0;
-	req->resp_len = -2;
+	if (bo != NULL)
+		req->resp_len = http_GetContentLength(bo->beresp);
+	else
+		req->resp_len = ObjGetLen(req->wrk, req->objcore);
 
 	/*
 	 * Determine ESI status first.  Not dependent on wantbody, because
@@ -90,6 +93,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 
 	if (req->res_mode & RES_ESI) {
 		RFC2616_Weaken_Etag(req->resp);
+		req->resp_len = -1;
 		VDP_push(req, VDP_ESI, NULL, 0);
 	} else if (http_IsStatus(req->resp, 304)) {
 		http_Unset(req->resp, H_Content_Length);
@@ -109,11 +113,8 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 		VDP_push(req, VDP_gunzip, NULL, 1);
 	}
 
-	if (req->res_mode & RES_ESI) {
-		/* Gunzip could have added back a C-L */
-		http_Unset(req->resp, H_Content_Length);
+	if (req->res_mode & RES_ESI)
 		assert(req->resp_len < 0);
-	}
 
 	/*
 	 * Range comes after the others and pushes on bottom because it
@@ -122,17 +123,22 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 	if (cache_param->http_range_support && http_IsStatus(req->resp, 200)) {
 		http_SetHeader(req->resp, "Accept-Ranges: bytes");
 		if (req->wantbody && http_GetHdr(req->http, H_Range, &r))
-			VRG_dorange(req, bo, r);
+			VRG_dorange(req, r);
 	}
 
-	if (req->resp_len >= -1 && req->wantbody)
+	if ((req->objcore->flags & OC_F_PRIVATE) &&
+	    !strcasecmp(http_GetMethod(req->http0), "HEAD")) {
+		/* HEAD+pass is allowed to send the C-L through unmolested. */
+	} else {
 		http_Unset(req->resp, H_Content_Length);
-	if (req->resp_len >= 0 && req->wantbody)
-		http_PrintfHeader(req->resp,
-		    "Content-Length: %jd", req->resp_len);
+		if (req->resp_len >= 0 && !http_IsStatus(req->resp, 304)) 
+			http_PrintfHeader(req->resp,
+			    "Content-Length: %jd", req->resp_len);
+	}
 
 	if (http_GetHdr(req->resp, H_Content_Length, NULL))
 		req->res_mode |= RES_LEN;
+
 	else if (req->wantbody) {
 		if (req->http->protover == 11) {
 			req->res_mode |= RES_CHUNKED;



More information about the varnish-commit mailing list