[master] df48e70 Add the vfp_testgzip which verifies that gzip'ed data are indeed gzip'ed data and extracts the magic bits should it ever be included from ESI.

Poul-Henning Kamp phk at project.varnish-software.com
Sat Jan 22 23:58:28 CET 2011


commit df48e70aa1077b935783ceac0d4d0f5aba06b02e
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Sat Jan 22 20:12:25 2011 +0000

    Add the vfp_testgzip which verifies that gzip'ed data are
    indeed gzip'ed data and extracts the magic bits should it ever
    be included from ESI.
    
    In general Varnish is not in the business of inspecting content
    and with the exception of ESI we still do not do so.
    
    What we do here is make sure that we do not serve corrupt data,
    in the same sense as we bail out on chunked encoding trouble or
    HTTP header trouble from the backend.

diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h
index 2779a00..af1bfd2 100644
--- a/bin/varnishd/cache.h
+++ b/bin/varnishd/cache.h
@@ -225,6 +225,7 @@ struct vfp {
 
 extern struct vfp vfp_gunzip;
 extern struct vfp vfp_gzip;
+extern struct vfp vfp_testgzip;
 extern struct vfp vfp_esi;
 
 /*--------------------------------------------------------------------*/
diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c
index 99e5d81..ec945d2 100644
--- a/bin/varnishd/cache_center.c
+++ b/bin/varnishd/cache_center.c
@@ -639,6 +639,8 @@ cnt_fetch(struct sess *sp)
 		sp->wrk->vfp = &vfp_gunzip;
 	else if (sp->wrk->do_gzip)
 		sp->wrk->vfp = &vfp_gzip;
+	else if (sp->wrk->is_gzip)
+		sp->wrk->vfp = &vfp_testgzip;
 
 	l = http_EstimateWS(sp->wrk->beresp,
 	    sp->pass ? HTTPH_R_PASS : HTTPH_A_INS, &nhttp);
diff --git a/bin/varnishd/cache_gzip.c b/bin/varnishd/cache_gzip.c
index 6e929e9..a4ea296 100644
--- a/bin/varnishd/cache_gzip.c
+++ b/bin/varnishd/cache_gzip.c
@@ -492,3 +492,78 @@ struct vfp vfp_gzip = {
         .bytes  =       vfp_gzip_bytes,
         .end    =       vfp_gzip_end,
 };
+
+/*--------------------------------------------------------------------
+ * VFP_TESTGZIP
+ *
+ * A VFP for testing that received gzip data is valid, and for
+ * collecting the magic bits while we're at it.
+ */
+
+static void __match_proto__()
+vfp_testgzip_begin(struct sess *sp, size_t estimate)
+{
+	(void)estimate;
+	sp->wrk->vgz_rx = VGZ_NewUngzip(sp, sp->ws);
+}
+
+static int __match_proto__()
+vfp_testgzip_bytes(struct sess *sp, struct http_conn *htc, ssize_t bytes)
+{
+	struct vgz *vg;
+	ssize_t l, w;
+	int i = -100;
+	uint8_t	ibuf[1024 * params->gzip_stack_buffer];
+	size_t dl;
+	const void *dp;
+	struct storage *st;
+
+	vg = sp->wrk->vgz_rx;
+	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
+	AZ(vg->vz.avail_in);
+	while (bytes > 0) {
+		if (FetchStorage(sp))
+			return (-1);
+		st = sp->wrk->storage;
+		l = st->space - st->len;
+		if (l > bytes)
+			l = bytes;
+		w = HTC_Read(htc, st->ptr + st->len, l);
+		if (w <= 0)
+			return (w);
+		bytes -= w;
+		VGZ_Ibuf(vg, st->ptr + st->len, w);
+		st->len += w;
+		sp->obj->len += w;
+
+		while (!VGZ_IbufEmpty(vg)) {
+			VGZ_Obuf(vg, ibuf, sizeof ibuf);
+			i = VGZ_Gunzip(vg, &dp, &dl);
+			assert(i == Z_OK || i == Z_STREAM_END);
+		}
+	}
+	if (i == Z_STREAM_END)
+		return (1);
+	return (-1);
+}
+
+static int __match_proto__()
+vfp_testgzip_end(struct sess *sp)
+{
+	struct vgz *vg;
+
+	vg = sp->wrk->vgz_rx;
+	CHECK_OBJ_NOTNULL(vg, VGZ_MAGIC);
+	VGZ_UpdateObj(vg, sp->obj);
+	VGZ_Destroy(&vg);
+	sp->obj->gziped = 1;
+	return (0);
+}
+
+struct vfp vfp_testgzip = {
+        .begin  =       vfp_testgzip_begin,
+        .bytes  =       vfp_testgzip_bytes,
+        .end    =       vfp_testgzip_end,
+};
+
+



More information about the varnish-commit mailing list