Commit 654a323c authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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>



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@2170 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 00c1eff2
......@@ -279,6 +279,7 @@ struct sess {
unsigned xid;
int restarts;
int esis;
struct worker *wrk;
......
......@@ -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) {
......
......@@ -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");
}
......@@ -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);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment