]> err.no Git - varnish/commitdiff
Implement the new-purge case where the entire expression comes
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sat, 24 Jan 2009 10:36:46 +0000 (10:36 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sat, 24 Jan 2009 10:36:46 +0000 (10:36 +0000)
from VCL.

It is possible to instigate purges two ways from VCL now:

        sub vcl_recv {
# Purge the req.url
                if (req.request == "PURGE") {
                        purge (req.url == req.url);
                        error 410;
                }

# Take entire purge instruction from "Purge:" header
                if (req.request == "PURGESTR") {
                        purge ("" req.http.purge);
                        error 410;
                }

Testcase for this.

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

varnish-cache/bin/varnishd/cache_vrt.c
varnish-cache/bin/varnishtest/tests/c00022.vtc [new file with mode: 0644]
varnish-cache/include/vrt.h
varnish-cache/lib/libvcl/vcc_action.c
varnish-cache/lib/libvcl/vcc_fixed_token.c

index 120c9c2a4ce979ee66caabd0576860053f8d2b26..e2fd9eef44980b0de1920aeb2aa92e5e12f937ce 100644 (file)
@@ -788,11 +788,61 @@ VRT_purge(struct sess *sp, char *cmds, ...)
                good = 1;
        }
        if (!good) 
+               /* XXX: report error how ? */
                BAN_Free(b);
        else
                BAN_Insert(b);
 }
 
+/*--------------------------------------------------------------------*/
+
+void
+VRT_purge_string(struct sess *sp, char *str, ...)
+{
+       char *p, *a1, *a2, *a3;
+       char **av;
+       va_list ap;
+       struct ban *b;
+       int good;
+       int i;
+
+       va_start(ap, str);
+       p = vrt_assemble_string(sp->http, NULL, str, ap);
+       if (p == NULL)
+               /* XXX: report error how ? */
+               return;
+
+       av = ParseArgv(p, 0);
+       if (av[0] != NULL) {
+               /* XXX: report error how ? */
+               FreeArgv(av);
+               return;
+       }
+       b = BAN_New();
+       good = 0;
+       for (i = 1; ; i += 3) {
+               a1 = av[i];
+               if (a1 == NULL)
+                       break;
+               good = 0;
+               a2 = av[i + 1];
+               if (a2 == NULL)
+                       break;
+               a3 = av[i + 2];
+               if (a3 == NULL)
+                       break;
+               if (BAN_AddTest(NULL, b, a1, a2, a3))
+                       break;
+               good = 1;
+       }
+       if (!good) 
+               /* XXX: report error how ? */
+               BAN_Free(b);
+       else
+               BAN_Insert(b);
+       FreeArgv(av);
+}
+
 /*--------------------------------------------------------------------
  * Simple stuff
  */
diff --git a/varnish-cache/bin/varnishtest/tests/c00022.vtc b/varnish-cache/bin/varnishtest/tests/c00022.vtc
new file mode 100644 (file)
index 0000000..d8f0b8a
--- /dev/null
@@ -0,0 +1,162 @@
+# $Id$
+
+test "Test banning a url with VCL purge"
+
+server s1 {
+       rxreq
+       expect req.url == "/foo"
+       txresp -hdr "foo: bar5" -body "1111\n"
+
+       rxreq
+       expect req.url == "/foo"
+       txresp -hdr "foo: bar6" -body "11111\n"
+
+       rxreq
+       expect req.url == "/foo"
+       txresp -hdr "foo: bar7" -body "111111\n"
+
+       rxreq
+       expect req.url == "/foo"
+       txresp -hdr "foo: bar8" -body "1111111\n"
+} -start
+
+varnish v1 -vcl+backend { 
+       sub vcl_recv {
+               if (req.request == "PURGE") {
+                       purge (req.url == req.url);
+                       error 410;
+               }
+               if (req.request == "PURGESTR") {
+                       purge ("" req.http.purge);
+                       error 410;
+               }
+       }
+} -start
+
+# Fetch into cache
+client c1 {
+       txreq -url "/foo"
+       rxresp
+       expect resp.status == 200
+       expect resp.http.foo == bar5
+       expect resp.bodylen == 5
+} -run
+
+# Purge something else
+client c1 {
+       txreq -req PURGE -url /foox
+       rxresp
+       expect resp.status == 410
+} -run
+varnish v1 -cliok "purge.list"
+
+# Still in cache
+client c1 {
+       txreq -url "/foo"
+       rxresp
+       expect resp.status == 200
+       expect resp.http.foo == bar5
+       expect resp.bodylen == 5
+} -run
+
+# Purge it
+client c1 {
+       txreq -req PURGE -url /foo
+       rxresp
+       expect resp.status == 410
+} -run
+varnish v1 -cliok "purge.list"
+
+# New obj 
+client c1 {
+       txreq -url "/foo"
+       rxresp
+       expect resp.status == 200
+       expect resp.http.foo == bar6
+       expect resp.bodylen == 6
+} -run
+
+# Purge everything else
+client c1 {
+       txreq -req PURGESTR -hdr "purge=req.url != /foo"
+       rxresp
+       expect resp.status == 410
+} -run
+varnish v1 -cliok "purge.list"
+
+# still there
+client c1 {
+       txreq -url "/foo"
+       rxresp
+       expect resp.status == 200
+       expect resp.http.foo == bar6
+       expect resp.bodylen == 6
+} -run
+
+# Purge it
+client c1 {
+       txreq -req PURGESTR -hdr "Purge: obj.http.foo == \"bar6\""
+       rxresp
+       expect resp.status == 410
+} -run
+varnish v1 -cliok "purge.list"
+
+# New one
+client c1 {
+       txreq -url "/foo"
+       rxresp
+       expect resp.status == 200
+       expect resp.http.foo == bar7
+       expect resp.bodylen == 7
+} -run
+
+# Purge something else
+client c1 {
+       txreq -req PURGESTR -hdr "Purge: obj.http.foo == \"bar6\""
+       rxresp
+       expect resp.status == 410
+} -run
+varnish v1 -cliok "purge.list"
+
+# Still there
+client c1 {
+       txreq -url "/foo"
+       rxresp
+       expect resp.status == 200
+       expect resp.http.foo == bar7
+       expect resp.bodylen == 7
+} -run
+
+# Header match
+client c1 {
+       txreq -req PURGESTR -hdr "Purge: req.http.foo == \"barcheck\""
+       rxresp
+       expect resp.status == 410
+} -run
+varnish v1 -cliok "purge.list"
+
+client c1 {
+       txreq -url "/foo" -hdr "foo: barcheck" 
+       rxresp
+       expect resp.status == 200
+       expect resp.http.foo == bar8
+       expect resp.bodylen == 8
+} -run
+
+# Header match
+client c1 {
+       txreq -req PURGESTR -hdr "Purge: obj.http.foo == \"barcheck\""
+       rxresp
+       expect resp.status == 410
+} -run
+varnish v1 -cliok "purge.list"
+
+client c1 {
+       txreq -url "/foo"
+       rxresp
+       expect resp.status == 200
+       expect resp.http.foo == bar8
+       expect resp.bodylen == 8
+} -run
+
+
index 4569c47937e8ba8e78a988d4e8de66d2b015bf19..5a0f60dc95bcf2c295e934a158b6e0c864fce712 100644 (file)
@@ -143,6 +143,7 @@ const char *VRT_regsub(const struct sess *sp, int all, const char *,
 
 void VRT_panic(struct sess *sp, const char *, ...);
 void VRT_purge(struct sess *sp, char *, ...);
+void VRT_purge_string(struct sess *sp, char *, ...);
 
 void VRT_count(const struct sess *, unsigned);
 int VRT_rewrite(const char *, const char *);
index 586f4eda33302d051af8b02f1a3af9e81586d9ae..d6dd0c9e5d2eacd882dd49bf599ee9ea5c366ebe 100644 (file)
@@ -401,7 +401,7 @@ parse_purge(struct tokenlist *tl)
                do
                        Fb(tl, 0, ", ");
                while (vcc_StringVal(tl));
-               Fb(tl, 0, ", 0);\n");
+               Fb(tl, 0, "vrt_magic_string_end);\n");
        }
 
        Expect(tl, ')');
index 83c6482d89e642f4747acb56208679d9ae4ab18e..bb6df1d88ed8ed57e3a3ce8873a05b72a1fbb82b 100644 (file)
@@ -235,10 +235,10 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, " * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWI");
        vsb_cat(sb, "SE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFT");
        vsb_cat(sb, "WARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n");
-       vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 3406 2008-11-19 14:");
-       vsb_cat(sb, "13:57Z petter $\n *\n * Runtime support for compiled V");
-       vsb_cat(sb, "CL programs.\n *\n * XXX: When this file is changed, l");
-       vsb_cat(sb, "ib/libvcl/vcc_gen_fixed_token.tcl\n");
+       vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 3541 2009-01-23 21:");
+       vsb_cat(sb, "17:02Z phk $\n *\n * Runtime support for compiled VCL ");
+       vsb_cat(sb, "programs.\n *\n * XXX: When this file is changed, lib/");
+       vsb_cat(sb, "libvcl/vcc_gen_fixed_token.tcl\n");
        vsb_cat(sb, " * XXX: *MUST* be rerun.\n */\n");
        vsb_cat(sb, "\nstruct sess;\nstruct vsb;\nstruct cli;\n");
        vsb_cat(sb, "struct director;\nstruct VCL_conf;\n");
@@ -289,6 +289,7 @@ vcl_output_lang_h(struct vsb *sb)
        vsb_cat(sb, " const char *,\n    void *, const char *);\n");
        vsb_cat(sb, "\nvoid VRT_panic(struct sess *sp, const char *, ...);\n");
        vsb_cat(sb, "void VRT_purge(struct sess *sp, char *, ...);\n");
+       vsb_cat(sb, "void VRT_purge_string(struct sess *sp, char *, ...);\n");
        vsb_cat(sb, "\nvoid VRT_count(const struct sess *, unsigned);\n");
        vsb_cat(sb, "int VRT_rewrite(const char *, const char *);\n");
        vsb_cat(sb, "void VRT_error(struct sess *, unsigned, const char *);");