]> err.no Git - varnish/commitdiff
Add an (unlocked) counter for number of ESI objects we have parsed.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 3 Feb 2009 10:26:02 +0000 (10:26 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Tue, 3 Feb 2009 10:26:02 +0000 (10:26 +0000)
Add two test-cases for objects we should not esi parse.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@3566 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/cache_vrt_esi.c
varnish-cache/bin/varnishtest/tests/e00007.vtc
varnish-cache/bin/varnishtest/tests/e00013.vtc [new file with mode: 0644]
varnish-cache/bin/varnishtest/tests/e00014.vtc [new file with mode: 0644]
varnish-cache/include/stat_field.h

index 73079a9f7873c575f3d9da2ce755b79684e1da28..4fde71ee0879f2eef3cfbd678df211566cf2e564 100644 (file)
@@ -630,6 +630,59 @@ esi_parse(struct esi_work *ew)
        return (p);
 }
 
+/*--------------------------------------------------------------------
+ * See if this looks like XML: first non-white char must be '<'
+ */
+
+static int
+looks_like_xml(struct object *obj) {
+       struct storage *st;
+       unsigned u;
+
+       VTAILQ_FOREACH(st, &obj->store, list) {
+               AN(st);
+               for (u = 0; u < st->len; u++) {
+                       if (isspace(st->ptr[u]))
+                               continue;
+                       if (st->ptr[u] == '<')
+                               return (1);
+                       else
+                               return (0);
+               }
+       }
+       return (0);
+}
+
+/*--------------------------------------------------------------------
+ * A quick stroll through the object, to find out if it contains any
+ * esi sequences at all.
+ */
+
+static int
+contain_esi(struct object *obj) {
+       struct storage *st;
+       unsigned u;
+       const char *r;
+       static const char *wanted = "<esi:";
+
+       /*
+        * Do a fast check to see if there is any '<esi:' sequences at all
+        */
+       r = wanted;
+       VTAILQ_FOREACH(st, &obj->store, list) {
+               AN(st);
+               for (u = 0; u < st->len; u++) {
+                       if (st->ptr[u] != *r) {
+                               r = wanted;
+                               continue;
+                       }
+                       if (*++r == '\0')
+                               return (1);
+               }
+       }
+       return (0);
+}
+
 /*--------------------------------------------------------------------*/
 
 void
@@ -642,6 +695,8 @@ VRT_ESI(struct sess *sp)
        char *p, *q;
 
        CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
+       CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
+
        assert(sp->obj->busy);
        if (sp->cur_method != VCL_MET_FETCH) {
                /* XXX: we should catch this at compile time */
@@ -653,28 +708,25 @@ VRT_ESI(struct sess *sp)
        if (VTAILQ_EMPTY(&sp->obj->store))
                return;
 
-       CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);
-
        if (!(params->esi_syntax & 0x00000001)) {
                /*
                 * By default, we will not ESI process an object where
                 *  the first non-space character is different from '<'
                 */
-               st = VTAILQ_FIRST(&sp->obj->store);
-               AN(st);
-               for (u = 0; u < st->len; u++) {
-                       if (isspace(st->ptr[u]))
-                               continue;
-                       if (st->ptr[u] == '<')
-                               break;
+               if (!looks_like_xml(sp->obj)) {
                        WSP(sp, SLT_ESI_xmlerror,
-                           "No ESI processing, "
-                           "binary object: 0x%02x at pos %u.",
-                           st->ptr[u], u);
+                           "No ESI processing, first char not '<'");
                        return;
                }
        }
 
+       /*
+        * Do a fast check to see if there is any '<esi:' sequences at all
+        */
+       if (!contain_esi(sp->obj))
+               return;
+
+       VSL_stats->esi_parse++;
        /* XXX: only if GET ? */
        ew = eww;
        memset(eww, 0, sizeof eww);
index 992d5f4cefda55492ae0f553596685a2b1c6b5f8..b8c8bf9144feb1510029ae89314f5a160d151bca 100644 (file)
@@ -22,7 +22,9 @@ varnish v1 -vcl+backend {
        sub vcl_fetch {
                esi;
        }
-} -start -cli "debug.fragfetch 32"
+} -start
+
+varnish v1 -cliok "debug.fragfetch 32"
 
 client c1 {
        txreq -url /foo/bar -hdr "Host: froboz"
diff --git a/varnish-cache/bin/varnishtest/tests/e00013.vtc b/varnish-cache/bin/varnishtest/tests/e00013.vtc
new file mode 100644 (file)
index 0000000..d7212ef
--- /dev/null
@@ -0,0 +1,25 @@
+# $Id$
+
+test "All white-space object, in multiple storage segments"
+
+server s1 {
+        rxreq
+        expect req.url == "/foo"
+        txresp -hdr "Connection: close"
+        send {                                         }
+} -start
+
+varnish v1 -vcl+backend {
+        sub vcl_fetch {
+                esi;
+        }
+} -start
+
+varnish v1 -cliok "debug.fragfetch 4"
+
+client c1 {
+        txreq -url /foo
+        rxresp
+} -run
+
+varnish v1 -expect esi_parse == 0
diff --git a/varnish-cache/bin/varnishtest/tests/e00014.vtc b/varnish-cache/bin/varnishtest/tests/e00014.vtc
new file mode 100644 (file)
index 0000000..10d9e9e
--- /dev/null
@@ -0,0 +1,25 @@
+# $Id$
+
+test "Check <esi: detector"
+
+server s1 {
+        rxreq
+        expect req.url == "/foo"
+        txresp -hdr "Connection: close"
+        send {           <a>   <esi/>                          }
+} -start
+
+varnish v1 -vcl+backend {
+        sub vcl_fetch {
+                esi;
+        }
+} -start
+
+varnish v1 -cliok "debug.fragfetch 4"
+
+client c1 {
+        txreq -url /foo
+        rxresp
+} -run
+
+varnish v1 -expect esi_parse == 0
index 8516b24babaa85028e2a84ec7d4ffb7ac9064345..fa45391a8ea691e4a4be398017e46b944db9ac76 100644 (file)
@@ -130,3 +130,5 @@ MAC_STAT(n_purge_dups,              uint64_t, 'a', "N duplicate purges removed")
 MAC_STAT(hcb_nolock,           uint64_t, 'a', "HCB Lookups without lock")
 MAC_STAT(hcb_lock,             uint64_t, 'a', "HCB Lookups with lock")
 MAC_STAT(hcb_insert,           uint64_t, 'a', "HCB Inserts")
+
+MAC_STAT(esi_parse,            uint64_t, 'a', "Objects ESI parsed (unlock)")