]> err.no Git - varnish/commitdiff
Push hole through the esi:include path, making a very trivial example
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 24 Oct 2007 20:34:24 +0000 (20:34 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 24 Oct 2007 20:34:24 +0000 (20:34 +0000)
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: svn+ssh://projects.linpro.no/svn/varnish/trunk@2170 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache.h
varnish-cache/bin/varnishd/cache_center.c
varnish-cache/bin/varnishd/cache_response.c
varnish-cache/bin/varnishd/cache_vrt_esi.c

index 5f936f3efccd9ce016b253895c515a47fab6fe14..f0cfa60a75695718d9755594aff31f1c3780bec2 100644 (file)
@@ -279,6 +279,7 @@ struct sess {
        unsigned                xid;
 
        int                     restarts;
+       int                     esis;
 
        struct worker           *wrk;
 
index 2b8a7254d6da5eded8364099f22fbd0bdeb45124..2015e4b398b1c89879987b96e0f4ac81fa3b16aa 100644 (file)
@@ -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) {
index cfe84a1de12e85d0f9dec187e98d3ce65796774b..33eaea505199e638a732f40c47c9a051f249ec12 100644 (file)
@@ -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");
 }
index 91e86b0aa9cf2a6a63e5c77e09d0ddddcb416e39..7b6ff545b55cdb51a9216b1c15348777b930c2db 100644 (file)
@@ -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);
        }
 }