r2170 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Wed Oct 24 22:34:24 CEST 2007


Author: phk
Date: 2007-10-24 22:34:24 +0200 (Wed, 24 Oct 2007)
New Revision: 2170

Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_center.c
   trunk/varnish-cache/bin/varnishd/cache_response.c
   trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c
Log:
Push hole through the esi:include path, making a very trivial example
work fully, leaving a trail of XXX and other devastation:

Add an esi nesting counter to the session.

Teach RES_WriteObj() to send an object as a chunk in chunked encoding.

Bail cnt_done() early for nested ESI transactions.

Catch the src="" attribute in esi:include and store it in the esibit.

In ESI_Deliver(), recurse into CNT_Session(STP_RECV) in order to handle
the include element of an esibit.

Recursion is probably not the ideal solution here, but it might quite
conceiveably be the best one, since it is quite cheap and very trivial.

Outstanding issues: too many to list still.

The following example worked for me:

	<html>
	<body>
	<pre>
	<esi:include src="/esi.txt"/>
	</pre>
	</body>
	</html>



Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2007-10-24 19:38:43 UTC (rev 2169)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2007-10-24 20:34:24 UTC (rev 2170)
@@ -279,6 +279,7 @@
 	unsigned		xid;
 
 	int			restarts;
+	int			esis;
 
 	struct worker		*wrk;
 

Modified: trunk/varnish-cache/bin/varnishd/cache_center.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_center.c	2007-10-24 19:38:43 UTC (rev 2169)
+++ trunk/varnish-cache/bin/varnishd/cache_center.c	2007-10-24 20:34:24 UTC (rev 2170)
@@ -211,6 +211,11 @@
 	sp->t_req = NAN;
 	sp->t_resp = NAN;
 	WSL_Flush(sp->wrk);
+
+	/* If we did an ESI include, don't mess up our state */
+	if (sp->esis > 0)
+		return (1);
+
 	if (sp->fd >= 0 && sp->doclose != NULL)
 		vca_close_session(sp, sp->doclose);
 	if (sp->fd < 0) {

Modified: trunk/varnish-cache/bin/varnishd/cache_response.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_response.c	2007-10-24 19:38:43 UTC (rev 2169)
+++ trunk/varnish-cache/bin/varnishd/cache_response.c	2007-10-24 20:34:24 UTC (rev 2170)
@@ -150,11 +150,17 @@
 {
 	struct storage *st;
 	unsigned u = 0;
+	char lenbuf[20];
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 
 	WRK_Reset(sp->wrk, &sp->fd);
-	sp->wrk->acct.hdrbytes += http_Write(sp->wrk, sp->http, 1);
+	if (sp->esis == 0) {
+		sp->wrk->acct.hdrbytes += http_Write(sp->wrk, sp->http, 1);
+	} else {
+		sprintf(lenbuf, "%x\r\n", sp->obj->len);
+		sp->wrk->acct.hdrbytes += WRK_Write(sp->wrk, lenbuf, -1);
+	}
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 
 	if (sp->wantbody && !VTAILQ_EMPTY(&sp->obj->esibits)) {
@@ -186,6 +192,8 @@
 		}
 		assert(u == sp->obj->len);
 	}
+	if (sp->esis > 0) 
+		WRK_Write(sp->wrk, "\r\n", -1);
 	if (WRK_Flush(sp->wrk))
 		vca_close_session(sp, "remote closed");
 }

Modified: trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c	2007-10-24 19:38:43 UTC (rev 2169)
+++ trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c	2007-10-24 20:34:24 UTC (rev 2170)
@@ -256,16 +256,18 @@
 {
 	struct esi_bit *eb;
 	txt tag;
-	txt cont;
+	txt val;
 
+	VSL(SLT_Debug, 0, "Incl \"%.*s\"", t.e - t.b, t.b);
 	eb = esi_addbit(ew);
-	while (esi_attrib(ew, &t, &tag, &cont) == 1) {
+	while (esi_attrib(ew, &t, &tag, &val) == 1) {
 		VSL(SLT_Debug, 0, "<%.*s> -> <%.*s>",
 		    tag.e - tag.b, tag.b,
-		    cont.e - cont.b, cont.b);
+		    val.e - val.b, val.b);
+		if (Tlen(tag) != 3 && memcmp(tag.b, "src", 3))
+			continue;
+		eb->include = val;
 	}
-	eb->include = t;
-	VSL(SLT_Debug, 0, "Incl \"%.*s\"", t.e - t.b, t.b);
 }
 
 /*--------------------------------------------------------------------
@@ -543,14 +545,38 @@
 {
 
 	struct esi_bit *eb;
+	struct object *obj;
 
 	VTAILQ_FOREACH(eb, &sp->obj->esibits, list) {
 		WRK_Write(sp->wrk, eb->chunk_length, -1);
 		WRK_Write(sp->wrk, eb->verbatim.b, Tlen(eb->verbatim));
-		if (VTAILQ_NEXT(eb, list))
-			WRK_Write(sp->wrk, "\r\n", -1);
-		else
-			WRK_Write(sp->wrk, "\r\n0\r\n", -1);
+		WRK_Write(sp->wrk, "\r\n", -1);
+		if (eb->include.b != NULL) {
+			/*
+			 * We flush here, because the next transaction is
+			 * quite likely to take some time, so we should get
+			 * as many bits to the client as we can already
+			 */
+			WRK_Flush(sp->wrk);
+			/*
+			 * XXX: Must edit url relative to the one we have
+			 * XXX: at this point, and not the http0 url.
+			 */
+			printf("INCL: %.*s\n",
+				Tlen(eb->include), eb->include.b);
+			*eb->include.e = '\0'; /* XXX ! */
+			sp->esis++;
+			obj = sp->obj;
+			sp->obj = NULL;
+			*sp->http = *sp->http0;
+			http_SetH(sp->http, HTTP_HDR_URL, eb->include.b);
+			sp->step = STP_RECV;
+			CNT_Session(sp);
+			sp->esis--;
+			sp->obj = obj;
+		}
+		if (!VTAILQ_NEXT(eb, list))
+			WRK_Write(sp->wrk, "0\r\n", -1);
 	}
 }
 




More information about the varnish-commit mailing list