r2277 - trunk/varnish-cache/bin/varnishd
phk at projects.linpro.no
phk at projects.linpro.no
Tue Nov 20 21:08:14 CET 2007
Author: phk
Date: 2007-11-20 21:08:13 +0100 (Tue, 20 Nov 2007)
New Revision: 2277
Modified:
trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c
Log:
Implement almost complete ESI parsing for objects spanning multiple
storage chunks.
Modified: trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c 2007-11-20 18:33:09 UTC (rev 2276)
+++ trunk/varnish-cache/bin/varnishd/cache_vrt_esi.c 2007-11-20 20:08:13 UTC (rev 2277)
@@ -156,7 +156,8 @@
VTAILQ_INSERT_TAIL(&ew->sp->obj->esibits, ew->eb, list);
ew->eb->verbatim = ew->dst;
sprintf(ew->eb->chunk_length, "%x\r\n", Tlen(ew->dst));
- VSL(SLT_Debug, ew->sp->fd, "AddBit: %.*s", Tlen(ew->dst), ew->dst.b);
+ VSL(SLT_Debug, ew->sp->fd, "AddBit: %d <%.*s>",
+ Tlen(ew->dst), Tlen(ew->dst), ew->dst.b);
return(ew->eb);
}
@@ -169,6 +170,8 @@
esi_addverbatim(struct esi_work *ew)
{
+ VSL(SLT_Debug, ew->sp->fd, "AddVer: %d <%.*s>",
+ Tlen(ew->o), Tlen(ew->o), ew->o.b);
if (ew->o.b != ew->dst.e)
memmove(ew->dst.e, ew->o.b, Tlen(ew->o));
ew->dst.e += Tlen(ew->o);
@@ -543,19 +546,27 @@
/* Not an element we care about */
p = q + 1;
}
+ assert(p == t.e);
return (p);
}
-static int
+static char *
esi_parse(struct esi_work *ew)
{
char *p;
+ VSL(SLT_Debug, ew->sp->fd, "Parse: %d <%.*s>",
+ Tlen(ew->t), Tlen(ew->t), ew->t.b);
p = esi_parse2(ew);
+ assert(ew->o.b >= ew->t.b);
+ assert(ew->o.e <= ew->t.e);
ew->o.e = p;
if (Tlen(ew->o))
esi_addverbatim(ew);
- return (p - ew->t.b);
+ if (Tlen(ew->dst))
+ esi_addbit(ew);
+ ew->off += (p - ew->t.b);
+ return (p);
}
/*--------------------------------------------------------------------*/
@@ -563,11 +574,14 @@
void
VRT_ESI(struct sess *sp)
{
- struct storage *st;
+ struct storage *st, *st2;
struct esi_work *ew, eww[1];
- int i;
+ txt t;
+ unsigned u;
+ char *p, *q;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+ assert(sp->obj->busy);
if (sp->cur_method != VCL_MET_FETCH) {
/* XXX: we should catch this at compile time */
WSP(sp, SLT_VCL_error,
@@ -583,19 +597,64 @@
ew->sp = sp;
ew->off = 1;
+ p = NULL;
VTAILQ_FOREACH(st, &sp->obj->store, list) {
- ew->t.b = (void *)st->ptr;
- ew->t.e = ew->t.b + st->len;
- i = esi_parse(ew);
- ew->off += st->len;
- if (i < st->len) {
- /* XXX: Handle complications */
- if (VTAILQ_NEXT(st, list))
+ if (p != NULL) {
+ assert ((void*)p > (void *)st->ptr);
+ assert ((void*)p <= (void *)(st->ptr + st->len));
+ if (p == (void*)(st->ptr + st->len))
+ break;
+ ew->t.b = p;
+ p = NULL;
+ } else
+ ew->t.b = (void *)st->ptr;
+ ew->t.e = (void *)(st->ptr + st->len);
+ p = esi_parse(ew);
+ if (p == ew->t.e) {
+ p = NULL;
+ continue;
+ }
+
+ if (VTAILQ_NEXT(st, list) == NULL) {
+ /*
+ * XXX: illegal XML input, but did we handle
+ * XXX: all of it, or do we leave the final
+ * XXX: element dangling ?
+ */
+ INCOMPL();
+ }
+
+ /* Move remainder to workspace */
+ u = ew->t.e - p;
+ t.b = sp->obj->ws_o->f;
+ t.e = t.b + WS_Reserve(sp->obj->ws_o, 0);
+ assert(t.e > t.b + u); /* XXX incredibly long element ? */
+ memcpy(t.b, p, u);
+
+ /* Peel start off next chunk, until and including '<' */
+ st2 = VTAILQ_NEXT(st, list);
+ AN(st2);
+ q = t.b + u;
+ p = (void*)st2->ptr;
+ while (1) {
+ if (p >= (char *)st2->ptr + st2->len)
INCOMPL();
+ if (q >= t.e)
+ INCOMPL();
+ *q = *p++;
+ if (*q++ == '>')
+ break;
}
+ WS_ReleaseP(sp->obj->ws_o, q);
+ t.e = q;
+
+ /* Parse this bit */
+ ew->t = t;
+ q = esi_parse(ew);
+ assert(q == ew->t.e); /* XXX */
+
+ /* 'p' is cached starting point for next storage part */
}
- if (Tlen(ew->dst))
- esi_addbit(ew);
if (!ew->is_esi) {
ESI_Destroy(sp->obj);
More information about the varnish-commit
mailing list