[master] af87aa4 Implement the easy case of gzip/ESI interaction: Receiving a gzip'ed object but wanting to store it ungzip'ed.

Poul-Henning Kamp phk at project.varnish-software.com
Fri Jan 21 13:01:13 CET 2011


commit af87aa4c0bb6fc67038cd351c4f3e9c800defe77
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Jan 21 12:00:41 2011 +0000

    Implement the easy case of gzip/ESI interaction: Receiving a gzip'ed
    object but wanting to store it ungzip'ed.

diff --git a/bin/varnishd/cache_esi_fetch.c b/bin/varnishd/cache_esi_fetch.c
index d36e694..b9cc5fc 100644
--- a/bin/varnishd/cache_esi_fetch.c
+++ b/bin/varnishd/cache_esi_fetch.c
@@ -111,8 +111,52 @@ vfp_esi_bytes_ug(struct sess *sp, struct http_conn *htc, size_t bytes)
 static int __match_proto__()
 vfp_esi_bytes_gu(struct sess *sp, struct http_conn *htc, size_t bytes)
 {
+	struct vgz *vg;
+	ssize_t l, w;
+	struct storage *st;
+	uint8_t	ibuf[1024 * params->gzip_stack_buffer];
+	int i;
+	size_t dl;
+	const void *dp;
 
-	return (vfp_esi_bytes_uu(sp, htc, bytes));
+	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+	vg = sp->wrk->vgz_rx;
+
+	while (bytes > 0) {
+		if (sp->wrk->storage == NULL) {
+			l = params->fetch_chunksize * 1024LL;
+			sp->wrk->storage = STV_alloc(sp, l);
+		}
+		if (sp->wrk->storage == NULL) {
+			errno = ENOMEM;
+			return (-1);
+		}
+		st = sp->wrk->storage;
+
+		VGZ_Obuf(vg, st->ptr + st->len, st->space - st->len);
+
+		if (VGZ_IbufEmpty(vg) && bytes > 0) {
+			l = sizeof ibuf;
+			if (l > bytes)
+				l = bytes;
+			w = HTC_Read(htc, ibuf, l);
+			if (w <= 0)
+				return (w);
+			VGZ_Ibuf(vg, ibuf, w);
+			bytes -= w;
+		}
+		i = VGZ_Gunzip(vg, &dp, &dl);
+		VEP_parse(sp, dp, dl);
+		st->len += dl;
+		sp->obj->len += dl;
+		if (st->len == st->space) {
+			VTAILQ_INSERT_TAIL(&sp->obj->store,
+			    sp->wrk->storage, list);
+			sp->wrk->storage = NULL;
+			st = NULL;
+		}
+	}
+	return (1);
 }
 
 /*---------------------------------------------------------------------
@@ -137,6 +181,9 @@ vfp_esi_begin(struct sess *sp, size_t estimate)
 
 	VEP_Init(sp);
 
+	if (sp->wrk->is_gzip && sp->wrk->do_gunzip)
+		sp->wrk->vgz_rx = VGZ_NewUngzip(sp, sp->ws);
+
 	(void)estimate;
 }
 
@@ -165,6 +212,8 @@ vfp_esi_end(struct sess *sp)
 	ssize_t l;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+	if (sp->wrk->is_gzip && sp->wrk->do_gunzip)
+		VGZ_Destroy(&sp->wrk->vgz_rx);
 
 	vsb = VEP_Finish(sp);
 
diff --git a/bin/varnishtest/tests/e00020.vtc b/bin/varnishtest/tests/e00020.vtc
new file mode 100644
index 0000000..3fe9239
--- /dev/null
+++ b/bin/varnishtest/tests/e00020.vtc
@@ -0,0 +1,36 @@
+# $Id$
+
+test "ESI:remove"
+
+
+server s1 {
+	rxreq 
+	txresp -gzipbody {
+		<esi:remove>
+		This is a test: Unseen University
+		<esi:include src="trick question">
+		<!--esi XXX -->
+		</esi:remove>
+		<esX>This is a test: Hello world
+	}
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_fetch {
+		set beresp.do_esi = true;
+		set beresp.do_gunzip = true;
+	}
+} -start 
+
+varnish v1 -cliok "param.set esi_syntax 4"
+varnish v1 -cliok "param.set http_gzip_support true"
+
+client c1 {
+	txreq 
+	rxresp
+	expect resp.status == 200
+	expect resp.bodylen == 40
+}
+
+client c1 -run
+varnish v1 -expect esi_errors == 2



More information about the varnish-commit mailing list