[master] c42b0d4 Reorder and simplify the logic for determining how we deliver the body (if at all)

Poul-Henning Kamp phk at FreeBSD.org
Mon Oct 27 21:21:28 CET 2014


commit c42b0d41cbf06dd15e79f2c195bcb092a86d255c
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Oct 27 19:56:07 2014 +0000

    Reorder and simplify the logic for determining how we deliver
    the body (if at all)

diff --git a/bin/varnishd/http1/cache_http1_deliver.c b/bin/varnishd/http1/cache_http1_deliver.c
index 0836f0e..f887a63 100644
--- a/bin/varnishd/http1/cache_http1_deliver.c
+++ b/bin/varnishd/http1/cache_http1_deliver.c
@@ -190,6 +190,7 @@ v1d_dorange(struct req *req, struct busyobj *bo, const char *r)
 
 /*--------------------------------------------------------------------
  */
+
 void
 V1D_Deliver(struct req *req, struct busyobj *bo)
 {
@@ -201,39 +202,41 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 
 	req->res_mode = 0;
 
+	/*
+	 * Determine ESI status first.  Not dependent on wantbody, because
+	 * we want ESI to supress C-L in HEAD too.
+	 */
 	if (!req->disable_esi &&
 	    ObjGetattr(req->wrk, req->objcore, OA_ESIDATA, NULL) != NULL)
 		req->res_mode |= RES_ESI;
 
+	/*
+	 * ESI-childen don't care about headers -> early escape
+	 */
 	if (req->esi_level > 0) {
 		ESI_DeliverChild(req, bo);
 		return;
 	}
 
 	if (req->res_mode & RES_ESI) {
-		/* nothing */
+		RFC2616_Weaken_Etag(req->resp);
+		http_Unset(req->resp, H_Content_Length);
 	} else if (http_IsStatus(req->resp, 304)) {
-		req->res_mode &= ~RES_LEN;
 		http_Unset(req->resp, H_Content_Length);
 		req->wantbody = 0;
-	} else if (bo != NULL) {
-		/* Streaming, decide CHUNKED/EOF later */
-	} else if ((req->objcore->flags & OC_F_PASS) && !req->wantbody) {
-		/*
-		 * if we pass a HEAD the C-L header may already be in the
-		 * object and it will not match the actual storage length
-		 * which is zero.
-		 * Hand that C-L header back to client.
-		 */
-		req->res_mode |= RES_LEN;
-	} else {
-		req->res_mode |= RES_LEN;
-		http_Unset(req->resp, H_Content_Length);
+	} 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));
 	}
 
+	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))
+			v1d_dorange(req, bo, r);
+	}
+
 	if (cache_param->http_gzip_support &&
 	    ObjCheckFlag(req->wrk, req->objcore, OF_GZIPED) &&
 	    !RFC2616_Req_Gzip(req->http)) {
@@ -242,66 +245,47 @@ V1D_Deliver(struct req *req, struct busyobj *bo)
 		 * XXX: we could cache that, but would still deliver
 		 * XXX: with multiple writes because of the gunzip buffer
 		 */
-		req->res_mode &= ~RES_LEN;
 		req->res_mode |= RES_GUNZIP;
+		http_Unset(req->resp, H_Content_Length);
+		http_Unset(req->resp, H_Content_Encoding);
+		VDP_push(req, VDP_gunzip, NULL, 0);
 	}
 
-	if (!(req->res_mode & (RES_LEN|RES_CHUNKED|RES_EOF))) {
-		/* We havn't chosen yet, do so */
-		if (!req->wantbody) {
-			/* Nothing */
-		} else if (req->http->protover >= 11) {
+	if (http_GetHdr(req->resp, H_Content_Length, NULL))
+		req->res_mode |= RES_LEN;
+
+	if (req->wantbody && !(req->res_mode & RES_LEN)) {
+		if (req->http->protover >= 11) {
 			req->res_mode |= RES_CHUNKED;
+			http_SetHeader(req->resp, "Transfer-Encoding: chunked");
 		} else {
 			req->res_mode |= RES_EOF;
 			req->doclose = SC_TX_EOF;
 		}
 	}
-	VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode);
-
-	if (!(req->res_mode & RES_LEN))
-		http_Unset(req->resp, H_Content_Length);
-
-	if (req->res_mode & RES_GUNZIP)
-		http_Unset(req->resp, H_Content_Encoding);
 
-	if (req->res_mode & RES_CHUNKED)
-		http_SetHeader(req->resp, "Transfer-Encoding: chunked");
-
-	if (req->res_mode & RES_ESI)
-		RFC2616_Weaken_Etag(req->resp);
+	VSLb(req->vsl, SLT_Debug, "RES_MODE %x", req->res_mode);
 
 	http_SetHeader(req->resp,
 	    req->doclose ? "Connection: close" : "Connection: keep-alive");
 
-	if (
-	    req->wantbody &&
-	    cache_param->http_range_support &&
-	    http_IsStatus(req->resp, 200)) {
-		http_SetHeader(req->resp, "Accept-Ranges: bytes");
-		if (http_GetHdr(req->http, H_Range, &r))
-			v1d_dorange(req, bo, r);
-	}
-
-	if (req->res_mode & RES_GUNZIP)
-		VDP_push(req, VDP_gunzip, NULL, 0);
-
 	VDP_push(req, v1d_bytes, NULL, 1);
 
 	V1L_Reserve(req->wrk, req->ws, &req->sp->fd, req->vsl, req->t_prev);
 
 	req->acct.resp_hdrbytes += HTTP1_Write(req->wrk, req->resp, HTTP1_Resp);
 
-	if (req->res_mode & RES_CHUNKED)
-		V1L_Chunked(req->wrk);
-
 	ois = OIS_DONE;
-	if (req->wantbody)
+	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);
+		(void)VDP_bytes(req, VDP_FLUSH, NULL, 0);
 
-	if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED))
-		V1L_EndChunk(req->wrk);
+		if (ois == OIS_DONE && (req->res_mode & RES_CHUNKED))
+			V1L_EndChunk(req->wrk);
+	}
 
 	if ((V1L_FlushRelease(req->wrk) || ois != OIS_DONE) && req->sp->fd >= 0)
 		SES_Close(req->sp, SC_REM_CLOSE);
diff --git a/bin/varnishtest/tests/r00801.vtc b/bin/varnishtest/tests/r00801.vtc
index f538d7f..ca1a567 100644
--- a/bin/varnishtest/tests/r00801.vtc
+++ b/bin/varnishtest/tests/r00801.vtc
@@ -13,6 +13,7 @@ varnish v1 -vcl+backend {
 	sub vcl_recv { return (pass); }
 	sub vcl_backend_response {
 		set beresp.do_stream = false;
+		unset beresp.http.content-length;
 	}
 } -start
 



More information about the varnish-commit mailing list