From: phk Date: Wed, 24 Oct 2007 20:34:24 +0000 (+0000) Subject: Push hole through the esi:include path, making a very trivial example X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b4a04f90d5cd52996821a462d956416ccc13ef36;p=varnish 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:
	
	
git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2170 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 5f936f3e..f0cfa60a 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -279,6 +279,7 @@ struct sess { unsigned xid; int restarts; + int esis; struct worker *wrk; diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index 2b8a7254..2015e4b3 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -211,6 +211,11 @@ cnt_done(struct sess *sp) 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) { diff --git a/varnish-cache/bin/varnishd/cache_response.c b/varnish-cache/bin/varnishd/cache_response.c index cfe84a1d..33eaea50 100644 --- a/varnish-cache/bin/varnishd/cache_response.c +++ b/varnish-cache/bin/varnishd/cache_response.c @@ -150,11 +150,17 @@ RES_WriteObj(struct sess *sp) { 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 @@ RES_WriteObj(struct sess *sp) } 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"); } diff --git a/varnish-cache/bin/varnishd/cache_vrt_esi.c b/varnish-cache/bin/varnishd/cache_vrt_esi.c index 91e86b0a..7b6ff545 100644 --- a/varnish-cache/bin/varnishd/cache_vrt_esi.c +++ b/varnish-cache/bin/varnishd/cache_vrt_esi.c @@ -256,16 +256,18 @@ esi_addinclude(struct esi_work *ew, txt t) { 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 @@ ESI_Deliver(struct sess *sp) { 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); } }