[master] e012bc3 Introduce a req->resp_len field to hold the number of bytes we actually expect to deliver, and use it to eliminate most of the C-L header munging.

Poul-Henning Kamp phk at FreeBSD.org
Mon May 4 20:55:40 CEST 2015


commit e012bc3e5489785339b678945bd7ef23e04df1ea
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon May 4 18:54:51 2015 +0000

    Introduce a req->resp_len field to hold the number of bytes we actually
    expect to deliver, and use it to eliminate most of the C-L header munging.

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index b9c1dd7..54422bc 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -591,7 +591,10 @@ struct req {
 	/* HTTP request */
 	struct http		*http;
 	struct http		*http0;
+
+	/* HTTP response */
 	struct http		*resp;
+	intmax_t		resp_len;
 
 	struct ws		ws[1];
 	struct objcore		*objcore;
diff --git a/bin/varnishd/cache/cache_deliver_proc.c b/bin/varnishd/cache/cache_deliver_proc.c
index a74b41f..86f4df2 100644
--- a/bin/varnishd/cache/cache_deliver_proc.c
+++ b/bin/varnishd/cache/cache_deliver_proc.c
@@ -140,7 +140,7 @@ VDP_DeliverObj(struct req *req)
 			WRONG("Wrong OIS value");
 		}
 	} while (ois == OIS_DATA || ois == OIS_STREAM);
+	(void)VDP_bytes(req, VDP_FLUSH, NULL, 0);
 	ObjIterEnd(req->objcore, &oi);
 	return (ois);
 }
-
diff --git a/bin/varnishd/cache/cache_esi_deliver.c b/bin/varnishd/cache/cache_esi_deliver.c
index a5c79a2..d8edb91 100644
--- a/bin/varnishd/cache/cache_esi_deliver.c
+++ b/bin/varnishd/cache/cache_esi_deliver.c
@@ -635,6 +635,7 @@ ESI_DeliverChild(struct req *req, struct busyobj *bo)
 		if (bo != NULL)
 			VBO_waitstate(bo, BOS_FINISHED);
 		ved_stripgzip(req);
+		(void)VDP_bytes(req, VDP_FLUSH, NULL, 0);
 	} else {
 		if (req->gzip_resp && !i)
 			VDP_push(req, ved_pretend_gzip, NULL, 0);
@@ -643,6 +644,5 @@ ESI_DeliverChild(struct req *req, struct busyobj *bo)
 
 		(void)VDP_DeliverObj(req);
 	}
-	(void)VDP_bytes(req, VDP_FLUSH, NULL, 0);
 	VDP_close(req);
 }
diff --git a/bin/varnishd/cache/cache_gzip.c b/bin/varnishd/cache/cache_gzip.c
index 652af2f..041d890 100644
--- a/bin/varnishd/cache/cache_gzip.c
+++ b/bin/varnishd/cache/cache_gzip.c
@@ -293,14 +293,14 @@ VDP_gunzip(struct req *req, enum vdp_action act, void **priv,
 		VGZ_Obuf(vg, vg->m_buf, vg->m_sz);
 		*priv = vg;
 
-		http_Unset(req->resp, H_Content_Length);
 		p = ObjGetattr(req->wrk, req->objcore, OA_GZIPBITS, &dl);
 		if (p != NULL && dl == 32) {
 			u = vbe64dec(p + 24);
 			/* XXX: Zero is suspect: OA_GZIPBITS wasn't set */
 			if (u != 0)
-				http_PrintfHeader(req->resp,
-				    "Content-Length: %ju", (uintmax_t)u);
+				req->resp_len = u;
+			else
+				req->resp_len = -1;
 		}
 		http_Unset(req->resp, H_Content_Encoding);
 		return (0);
diff --git a/bin/varnishd/cache/cache_range.c b/bin/varnishd/cache/cache_range.c
index be29ece..1cb50fa 100644
--- a/bin/varnishd/cache/cache_range.c
+++ b/bin/varnishd/cache/cache_range.c
@@ -151,9 +151,7 @@ VRG_dorange(struct req *req, struct busyobj *bo, const char *r)
 
 	http_PrintfHeader(req->resp, "Content-Range: bytes %jd-%jd/%jd",
 	    (intmax_t)low, (intmax_t)high, (intmax_t)len);
-	http_Unset(req->resp, H_Content_Length);
-	http_PrintfHeader(req->resp, "Content-Length: %jd",
-	    (intmax_t)(1 + high - low));
+	req->resp_len = (intmax_t)(1 + high - low);
 	http_PutResponse(req->resp, "HTTP/1.1", 206, NULL);
 
 	vrg_priv = WS_Alloc(req->ws, sizeof *vrg_priv);
diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c
index 5db8754..27d4f72 100644
--- a/bin/varnishd/http1/cache_http1_deliver.c
+++ b/bin/varnishd/http1/cache_http1_deliver.c
@@ -70,6 +70,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
 
 	req->res_mode = 0;
+	req->resp_len = -2;
 
 	/*
 	 * Determine ESI status first.  Not dependent on wantbody, because
@@ -92,12 +93,8 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 	} else if (http_IsStatus(req->resp, 304)) {
 		http_Unset(req->resp, H_Content_Length);
 		req->wantbody = 0;
-	} else if (bo == NULL &&
-	    !http_GetHdr(req->resp, H_Content_Length, NULL)) {
-		http_PrintfHeader(req->resp,
-		    "Content-Length: %ju", (uintmax_t)ObjGetLen(
-		    req->wrk, req->objcore));
-	}
+	} else if (bo == NULL && req->wantbody)
+		req->resp_len = ObjGetLen(req->wrk, req->objcore);
 
 	if (cache_param->http_gzip_support &&
 	    ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) &&
@@ -114,6 +111,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 	if (req->res_mode & RES_ESI) {
 		/* Gunzip could have added back a C-L */
 		http_Unset(req->resp, H_Content_Length);
+		req->resp_len = -1;
 	}
 
 	/*
@@ -126,11 +124,15 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 			VRG_dorange(req, bo, r);
 	}
 
+	if (req->resp_len >= -1 && req->wantbody)
+		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 (http_GetHdr(req->resp, H_Content_Length, NULL))
 		req->res_mode |= RES_LEN;
-
-	if (req->wantbody && !(req->res_mode & RES_LEN)) {
+	else if (req->wantbody) {
 		if (req->http->protover == 11) {
 			req->res_mode |= RES_CHUNKED;
 			http_SetHeader(req->resp, "Transfer-Encoding: chunked");
@@ -162,10 +164,7 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 	if (req->wantbody) {
 		if (req->res_mode & RES_CHUNKED)
 			V1L_Chunked(req->wrk);
-
 		ois = VDP_DeliverObj(req);
-		(void)VDP_bytes(req, VDP_FLUSH, NULL, 0);
-
 		if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED))
 			V1L_EndChunk(req->wrk);
 	}



More information about the varnish-commit mailing list