[4.0] fee7016 Deal with known zero length objects properly when handling do_gzip/do_gunzip

Martin Blix Grydeland martin at varnish-software.com
Wed Mar 11 16:23:16 CET 2015


commit fee70166ca0c520b2ce46f9dc540e5a6dd1f9063
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Wed Mar 11 16:21:39 2015 +0100

    Deal with known zero length objects properly when handling do_gzip/do_gunzip
    
    Original patch: fgs
    
    Fixes: #1602

diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index 3308ae6..fbb7110 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -435,6 +435,9 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 
 	assert(wrk->handling == VCL_RET_DELIVER);
 
+	AN(bo->vbc);
+	est = V1F_Setup_Fetch(bo);
+
 	/*
 	 * The VCL variables beresp.do_g[un]zip tells us how we want the
 	 * object processed before it is stored.
@@ -445,10 +448,18 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 	 *	"Content-Encoding: gzip"	--> object is gzip'ed.
 	 *	no Content-Encoding		--> object is not gzip'ed.
 	 *	anything else			--> do nothing wrt gzip
-	 *
-	 * XXX: BS_NONE/cl==0 should avoid gzip/gunzip
 	 */
 
+	/*
+	 * If the length is known to be zero, it's not gziped and no
+	 * action is needed.  A similar issue exists for chunked encoding
+	 * but we don't handle that.  See #1320.
+	 */
+	if (est == 0) {
+		http_Unset(bo->beresp, H_Content_Encoding);
+		bo->do_gzip = bo->do_gunzip = 0;
+	}
+
 	/* We do nothing unless the param is set */
 	if (!cache_param->http_gzip_support)
 		bo->do_gzip = bo->do_gunzip = 0;
@@ -468,20 +479,6 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)
 	if (bo->do_gzip && !bo->is_gunzip)
 		bo->do_gzip = 0;
 
-	AN(bo->vbc);
-	est = V1F_Setup_Fetch(bo);
-
-	if (est == 0) {
-		/*
-		 * If the length is known to be zero, it's not gziped.
-		 * A similar issue exists for chunked encoding but we
-		 * don't handle that.  See #1320.
-		 */
-		http_Unset(bo->beresp, H_Content_Encoding);
-		bo->is_gzip = 0;
-		bo->is_gunzip = 1;
-	}
-
 	/* But we can't do both at the same time */
 	assert(bo->do_gzip == 0 || bo->do_gunzip == 0);
 
diff --git a/bin/varnishd/cache/cache_http1_fetch.c b/bin/varnishd/cache/cache_http1_fetch.c
index b6d72dd..e0085a6 100644
--- a/bin/varnishd/cache/cache_http1_fetch.c
+++ b/bin/varnishd/cache/cache_http1_fetch.c
@@ -185,6 +185,8 @@ V1F_Setup_Fetch(struct busyobj *bo)
 	case BS_CHUNKED:
 		VFP_Push(bo, v1f_pull_chunked, -1);
 		return (-1);
+	case BS_NONE:
+		return (0);
 	default:
 		break;
 	}
diff --git a/bin/varnishtest/tests/r01602.vtc b/bin/varnishtest/tests/r01602.vtc
new file mode 100644
index 0000000..39d6f65
--- /dev/null
+++ b/bin/varnishtest/tests/r01602.vtc
@@ -0,0 +1,20 @@
+varnishtest "Content-Encoding gzip with no content"
+
+server s1 {
+	rxreq
+	txresp -gzipbody {<esi:include src="/foo"/>}
+	rxreq
+	txresp -status 204
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_backend_response {
+		set beresp.do_gzip = true;
+		set beresp.do_esi = true;
+	}
+} -start
+
+client c1 {
+	txreq -hdr "Accept-Encoding: gzip"
+	rxresp
+} -run



More information about the varnish-commit mailing list