[master] fe361cf Complete support for gunzip'ing during streaming delivery.

Poul-Henning Kamp phk at varnish-cache.org
Mon May 2 14:32:51 CEST 2011


commit fe361cf2ec69425f1352c9a5d6e32668d0f3aa98
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon May 2 12:32:11 2011 +0000

    Complete support for gunzip'ing during streaming delivery.

diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h
index b42385f..885974a 100644
--- a/bin/varnishd/cache.h
+++ b/bin/varnishd/cache.h
@@ -878,7 +878,7 @@ void RES_BuildHttp(struct sess *sp);
 void RES_WriteObj(struct sess *sp);
 void RES_StreamStart(struct sess *sp);
 void RES_StreamEnd(struct sess *sp);
-void RES_StreamPoll(const struct sess *sp);
+void RES_StreamPoll(struct sess *sp);
 
 /* cache_vary.c */
 struct vsb *VRY_Create(const struct sess *sp, const struct http *hp);
diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c
index 4514346..4b408ae 100644
--- a/bin/varnishd/cache_center.c
+++ b/bin/varnishd/cache_center.c
@@ -857,7 +857,6 @@ cnt_streambody(struct sess *sp)
 
 	RES_StreamStart(sp);
 
-	/* Use unmodified headers*/
 	i = FetchBody(sp);
 
 	sp->wrk->h_content_length = NULL;
@@ -888,6 +887,8 @@ cnt_streambody(struct sess *sp)
 	sp->restarts = 0;
 
 	RES_StreamEnd(sp);
+	if (sp->wrk->res_mode & RES_GUNZIP)
+		VGZ_Destroy(&sctx.vgz);
 
 	sp->wrk->sctx = NULL;
 	assert(WRW_IsReleased(sp->wrk));
diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c
index 2239884..290da72 100644
--- a/bin/varnishd/cache_gzip.c
+++ b/bin/varnishd/cache_gzip.c
@@ -569,6 +569,8 @@ vfp_gzip_end(struct sess *sp)
 		i = VGZ_Gzip(vg, &dp, &dl, VGZ_FINISH);
 		sp->obj->len += dl;
 	} while (i != Z_STREAM_END);
+	if (sp->wrk->do_stream)
+		RES_StreamPoll(sp);
 	VGZ_UpdateObj(vg, sp->obj);
 	VGZ_Destroy(&vg);
 	return (0);
diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c
index bdf2814..9ffb95e 100644
--- a/bin/varnishd/cache_response.c
+++ b/bin/varnishd/cache_response.c
@@ -418,7 +418,7 @@ RES_StreamStart(struct sess *sp)
 }
 
 void
-RES_StreamPoll(const struct sess *sp)
+RES_StreamPoll(struct sess *sp)
 {
 	struct stream_ctx *sctx;
 	struct storage *st;
@@ -438,11 +438,17 @@ RES_StreamPoll(const struct sess *sp)
 		}
 		l2 = st->len + l - sctx->stream_next;
 		ptr = st->ptr + (sctx->stream_next - l);
-		(void)WRW_Write(sp->wrk, ptr, l2);
+		if (sp->wrk->res_mode & RES_GUNZIP) {
+			(void)VGZ_WrwGunzip(sp, sctx->vgz, ptr, l2,
+			    sctx->obuf, sctx->obuf_len, &sctx->obuf_ptr);
+		} else {
+			(void)WRW_Write(sp->wrk, ptr, l2);
+		}
 		l += st->len;
 		sctx->stream_next += l2;
 	}
-	(void)WRW_Flush(sp->wrk);
+	if (!(sp->wrk->res_mode & RES_GUNZIP))
+		(void)WRW_Flush(sp->wrk);
 
 	if (sp->objcore == NULL || (sp->objcore->flags & OC_F_PASS)) {
 		/*
@@ -469,10 +475,8 @@ RES_StreamEnd(struct sess *sp)
 	sctx = sp->wrk->sctx;
 	CHECK_OBJ_NOTNULL(sctx, STREAM_CTX_MAGIC);
 
-	if (sp->wrk->res_mode & RES_GUNZIP) {
-		INCOMPL();
-		res_WriteGunzipObj(sp);
-	}
+	if (sp->wrk->res_mode & RES_GUNZIP && sctx->obuf_ptr > 0)
+		(void)WRW_Write(sp->wrk, sctx->obuf, sctx->obuf_ptr);
 	if (sp->wrk->res_mode & RES_CHUNKED &&
 	    !(sp->wrk->res_mode & RES_ESI_CHILD))
 		WRW_EndChunk(sp->wrk);
diff --git a/bin/varnishtest/tests/t00001.vtc b/bin/varnishtest/tests/t00001.vtc
new file mode 100644
index 0000000..5fefc70
--- /dev/null
+++ b/bin/varnishtest/tests/t00001.vtc
@@ -0,0 +1,49 @@
+varnishtest "Test stream/gunzip"
+
+server s1 {
+	rxreq
+	expect req.url == "/bar"
+	txresp -body "foobar"
+
+	rxreq
+	expect req.url == "/bla"
+	expect req.http.accept-encoding == "gzip"
+	txresp -gzipbody blablabla
+
+	rxreq
+	expect req.url == "/foo"
+	txresp -body "snafu"
+
+	rxreq
+	expect req.url == "/barf"
+	expect req.http.accept-encoding == "gzip"
+	txresp -gzipbody Iamoutofnonsensewords
+
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_fetch {
+		if (req.url == "/foo") {
+			set beresp.do_gzip = true;
+		}
+		if (req.url == "/barf") {
+			set beresp.do_gunzip = true;
+		}
+		set beresp.do_stream = true;
+	}
+} -start 
+
+client c1 {
+	txreq  -url /bar
+	rxresp 
+	expect resp.bodylen == 6
+	txreq  -url /bla
+	rxresp 
+	expect resp.bodylen == 9
+	txreq  -url /foo
+	rxresp 
+	expect resp.bodylen == 5
+	txreq  -url /barf
+	rxresp 
+	expect resp.bodylen == 21
+} -run



More information about the varnish-commit mailing list