Commit f65dea33 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Implement almost complete ESI parsing for objects spanning multiple

storage chunks.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@2277 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent ac7f6af3
...@@ -156,7 +156,8 @@ esi_addbit(struct esi_work *ew) ...@@ -156,7 +156,8 @@ esi_addbit(struct esi_work *ew)
VTAILQ_INSERT_TAIL(&ew->sp->obj->esibits, ew->eb, list); VTAILQ_INSERT_TAIL(&ew->sp->obj->esibits, ew->eb, list);
ew->eb->verbatim = ew->dst; ew->eb->verbatim = ew->dst;
sprintf(ew->eb->chunk_length, "%x\r\n", Tlen(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); return(ew->eb);
} }
...@@ -169,6 +170,8 @@ static void ...@@ -169,6 +170,8 @@ static void
esi_addverbatim(struct esi_work *ew) 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) if (ew->o.b != ew->dst.e)
memmove(ew->dst.e, ew->o.b, Tlen(ew->o)); memmove(ew->dst.e, ew->o.b, Tlen(ew->o));
ew->dst.e += Tlen(ew->o); ew->dst.e += Tlen(ew->o);
...@@ -543,19 +546,27 @@ esi_parse2(struct esi_work *ew) ...@@ -543,19 +546,27 @@ esi_parse2(struct esi_work *ew)
/* Not an element we care about */ /* Not an element we care about */
p = q + 1; p = q + 1;
} }
assert(p == t.e);
return (p); return (p);
} }
static int static char *
esi_parse(struct esi_work *ew) esi_parse(struct esi_work *ew)
{ {
char *p; char *p;
VSL(SLT_Debug, ew->sp->fd, "Parse: %d <%.*s>",
Tlen(ew->t), Tlen(ew->t), ew->t.b);
p = esi_parse2(ew); p = esi_parse2(ew);
assert(ew->o.b >= ew->t.b);
assert(ew->o.e <= ew->t.e);
ew->o.e = p; ew->o.e = p;
if (Tlen(ew->o)) if (Tlen(ew->o))
esi_addverbatim(ew); 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 @@ esi_parse(struct esi_work *ew) ...@@ -563,11 +574,14 @@ esi_parse(struct esi_work *ew)
void void
VRT_ESI(struct sess *sp) VRT_ESI(struct sess *sp)
{ {
struct storage *st; struct storage *st, *st2;
struct esi_work *ew, eww[1]; struct esi_work *ew, eww[1];
int i; txt t;
unsigned u;
char *p, *q;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
assert(sp->obj->busy);
if (sp->cur_method != VCL_MET_FETCH) { if (sp->cur_method != VCL_MET_FETCH) {
/* XXX: we should catch this at compile time */ /* XXX: we should catch this at compile time */
WSP(sp, SLT_VCL_error, WSP(sp, SLT_VCL_error,
...@@ -583,19 +597,64 @@ VRT_ESI(struct sess *sp) ...@@ -583,19 +597,64 @@ VRT_ESI(struct sess *sp)
ew->sp = sp; ew->sp = sp;
ew->off = 1; ew->off = 1;
p = NULL;
VTAILQ_FOREACH(st, &sp->obj->store, list) { VTAILQ_FOREACH(st, &sp->obj->store, list) {
ew->t.b = (void *)st->ptr; if (p != NULL) {
ew->t.e = ew->t.b + st->len; assert ((void*)p > (void *)st->ptr);
i = esi_parse(ew); assert ((void*)p <= (void *)(st->ptr + st->len));
ew->off += st->len; if (p == (void*)(st->ptr + st->len))
if (i < st->len) { break;
/* XXX: Handle complications */ ew->t.b = p;
if (VTAILQ_NEXT(st, list)) 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(); 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) { if (!ew->is_esi) {
ESI_Destroy(sp->obj); ESI_Destroy(sp->obj);
......
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