r5680 - in trunk/varnish-cache/bin: varnishd varnishtest/tests

phk at varnish-cache.org phk at varnish-cache.org
Tue Jan 4 11:51:58 CET 2011


Author: phk
Date: 2011-01-04 11:51:57 +0100 (Tue, 04 Jan 2011)
New Revision: 5680

Added:
   trunk/varnish-cache/bin/varnishtest/tests/g00001.vtc
Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_center.c
   trunk/varnish-cache/bin/varnishd/cache_response.c
Log:
Beat a path through, where we can successfully ungzip an trivial object,
when the client does not support gzip.



Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2011-01-04 10:50:53 UTC (rev 5679)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2011-01-04 10:51:57 UTC (rev 5680)
@@ -741,6 +741,7 @@
 /* cache_response.c */
 void RES_BuildHttp(struct sess *sp);
 void RES_WriteObj(struct sess *sp);
+void RES_WriteGunzipObj(struct sess *sp);
 
 /* cache_vary.c */
 struct vsb *VRY_Create(const struct sess *sp, const struct http *hp);

Modified: trunk/varnish-cache/bin/varnishd/cache_center.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_center.c	2011-01-04 10:50:53 UTC (rev 5679)
+++ trunk/varnish-cache/bin/varnishd/cache_center.c	2011-01-04 10:51:57 UTC (rev 5680)
@@ -210,7 +210,14 @@
 	sp->director = NULL;
 	sp->restarts = 0;
 
-	RES_WriteObj(sp);
+	if (params->http_gzip_support &&
+	    http_HdrIs(sp->wrk->resp, H_Content_Encoding, "gzip") &&
+	    !RFC2616_Req_Gzip(sp) &&
+	    sp->wantbody)
+		RES_WriteGunzipObj(sp);
+	else 
+		RES_WriteObj(sp);
+
 	AZ(sp->wrk->wfd);
 	(void)HSH_Deref(sp->wrk, NULL, &sp->obj);
 	sp->wrk->resp = NULL;
@@ -879,6 +886,15 @@
 	http_Setup(sp->wrk->bereq, sp->wrk->ws);
 	http_FilterHeader(sp, HTTPH_R_FETCH);
 	http_ForceGet(sp->wrk->bereq);
+	if (params->http_gzip_support) {
+		/*
+		 * We always ask the backend for gzip, even if the
+		 * client doesn't grok it.  We will uncompress for
+		 * the minority of clients which don't.
+		 */
+		http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->bereq,
+		    "Accept-Encoding: gzip");
+	}
 	sp->wrk->connect_timeout = 0;
 	sp->wrk->first_byte_timeout = 0;
 	sp->wrk->between_bytes_timeout = 0;

Modified: trunk/varnish-cache/bin/varnishd/cache_response.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_response.c	2011-01-04 10:50:53 UTC (rev 5679)
+++ trunk/varnish-cache/bin/varnishd/cache_response.c	2011-01-04 10:51:57 UTC (rev 5680)
@@ -246,7 +246,6 @@
 	unsigned low, high, ptr, off, len;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
-	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 
 	WRW_Reserve(sp->wrk, &sp->fd);
 
@@ -274,7 +273,7 @@
 	high = sp->obj->len - 1;
 
 	if (sp->disable_esi || sp->esis == 0) {
-		/* For none ESI and non ESI-included objects, try Range */
+		/* For non-ESI and non ESI-included objects, try Range */
 		if (params->http_range_support &&
 		    (sp->disable_esi || sp->esis == 0) &&
 		    sp->obj->response == 200 &&
@@ -358,3 +357,109 @@
 	if (WRW_FlushRelease(sp->wrk))
 		vca_close_session(sp, "remote closed");
 }
+
+/*--------------------------------------------------------------------
+ * We have a gzip'ed object and need to ungzip it for a client which
+ * does not understand gzip.
+ */
+
+void
+RES_WriteGunzipObj(struct sess *sp)
+{
+	struct storage *st;
+	unsigned u = 0;
+#if 0
+	char lenbuf[20];
+#endif
+	struct vgz *vg;
+	const void *dp;
+	size_t dl;
+	int i;
+
+	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+	AN(sp->wantbody);
+
+	WRW_Reserve(sp->wrk, &sp->fd);
+
+	/* We don't know the length  (XXX: Cache once we do ?) */
+	http_Unset(sp->wrk->resp, H_Content_Length);
+	http_Unset(sp->wrk->resp, H_Content_Encoding);
+	http_Unset(sp->wrk->resp, H_Connection);
+
+	http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->resp, "Connection: %s",
+	    "close");
+	sp->doclose = "Gunzip EOF";
+
+	/*
+	 * ESI objects get special delivery
+	 */
+	if (!sp->disable_esi && sp->obj->esidata != NULL) {
+		INCOMPL();
+#if 0
+		if (sp->esis == 0)
+			/* no headers for interior ESI includes */
+			sp->acct_tmp.hdrbytes +=
+			    http_Write(sp->wrk, sp->wrk->resp, 1);
+
+		if (WRW_FlushRelease(sp->wrk)) {
+			vca_close_session(sp, "remote closed");
+		} else 
+			ESI_Deliver(sp);
+		return;
+#endif
+	}
+
+	if (sp->disable_esi || sp->esis == 0) {
+		sp->acct_tmp.hdrbytes += http_Write(sp->wrk, sp->wrk->resp, 1);
+	} else if (!sp->disable_esi &&
+	    sp->esis > 0 &&
+	    sp->http->protover >= 1.1 &&
+	    sp->obj->len > 0) {
+		INCOMPL();
+#if 0
+		/*
+		 * Interior ESI includes (which are not themselves ESI
+		 * objects) use chunked encoding (here) or EOF (nothing)
+		 */
+		sprintf(lenbuf, "%x\r\n", sp->obj->len);
+		(void)WRW_Write(sp->wrk, lenbuf, -1);
+#endif
+	}
+
+	vg = VGZ_NewUnzip(sp, sp->ws, sp->wrk->ws);
+	AN(vg);
+
+	VTAILQ_FOREACH(st, &sp->obj->store, list) {
+		CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+		CHECK_OBJ_NOTNULL(st, STORAGE_MAGIC);
+		u += st->len;
+
+		sp->acct_tmp.bodybytes += st->len;
+		VSC_main->n_objwrite++;
+
+		VGZ_Feed(vg, st->ptr, st->len);
+		do {
+			i = VGZ_Produce(vg, &dp, &dl);
+			if (dl != 0) {
+				(void)WRW_Write(sp->wrk, dp, dl);
+				if (WRW_Flush(sp->wrk))
+					break;
+			}
+		} while (i == 0);
+	}
+	VGZ_Destroy(&vg);
+	assert(u == sp->obj->len);
+	if (!sp->disable_esi &&
+	    sp->esis > 0 &&
+	    sp->http->protover >= 1.1 &&
+	    sp->obj->len > 0) {
+		INCOMPL();
+#if 0
+		/* post-chunk new line */
+		(void)WRW_Write(sp->wrk, "\r\n", -1);
+#endif
+	}
+
+	if (WRW_FlushRelease(sp->wrk))
+		vca_close_session(sp, "remote closed");
+}

Added: trunk/varnish-cache/bin/varnishtest/tests/g00001.vtc
===================================================================
--- trunk/varnish-cache/bin/varnishtest/tests/g00001.vtc	                        (rev 0)
+++ trunk/varnish-cache/bin/varnishtest/tests/g00001.vtc	2011-01-04 10:51:57 UTC (rev 5680)
@@ -0,0 +1,27 @@
+# $Id$
+
+test "test basic gunzip for client"
+
+server s1 {
+	rxreq
+	expect req.http.accept-encoding == "gzip"
+	txresp -gzipbody FOO
+} -start
+
+varnish v1 -cliok "param.set http_gzip_support true" -vcl+backend {
+} -start
+
+client c1 {
+	txreq 
+	rxresp
+	expect resp.bodylen == "3"
+	expect resp.http.content-encoding == "resp.http.content-encoding"
+} -run
+
+client c1 {
+	txreq -hdr "Accept-encoding: gzip;q=0.1"
+	rxresp
+	expect resp.http.content-encoding == "gzip"
+	gunzip
+	expect resp.bodylen == "3"
+} -run


Property changes on: trunk/varnish-cache/bin/varnishtest/tests/g00001.vtc
___________________________________________________________________
Added: svn:keywords
   + Id




More information about the varnish-commit mailing list