]> err.no Git - varnish/commitdiff
Implement regexp matching of strings in VCL.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sat, 22 Jul 2006 12:00:18 +0000 (12:00 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Sat, 22 Jul 2006 12:00:18 +0000 (12:00 +0000)
For now we default to REG_EXTENDED, but it might make sense
to let the user control this flag and the case sensitivity.

Another concern is the stringification of regexps, it may lead
to backslash madness.  Maybe we should define '...' string types
also and do no backslash substitution in those at all.

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

varnish-cache/bin/varnishd/Makefile.am
varnish-cache/bin/varnishd/cache_vrt_re.c [new file with mode: 0644]
varnish-cache/include/vrt.h
varnish-cache/lib/libvcl/vcc_compile.c
varnish-cache/lib/libvcl/vcc_compile.h
varnish-cache/lib/libvcl/vcc_fixed_token.c

index 1d53f9467e65f4d7e979f1eeb03c77371de42ede..a8f4e80e28a830bc3424393c0d69adba7673537c 100644 (file)
@@ -31,6 +31,7 @@ varnishd_SOURCES = \
        cache_vcl.c \
        cache_vrt.c \
        cache_vrt_acl.c \
+       cache_vrt_re.c \
        cli_event.c \
        hash_simple_list.c \
        hash_classic.c \
diff --git a/varnish-cache/bin/varnishd/cache_vrt_re.c b/varnish-cache/bin/varnishd/cache_vrt_re.c
new file mode 100644 (file)
index 0000000..c739333
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Runtime support for compiled VCL programs, regexps
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <regex.h>
+
+#include "shmlog.h"
+#include "vrt.h"
+#include "vrt_obj.h"
+#include "sbuf.h"
+#include "vcl.h"
+#include "cache.h"
+
+void
+VRT_re_init(void **rep, const char *re)
+{
+       regex_t *t;
+       int i;
+
+       t = calloc(sizeof *t, 1);
+       assert(t != NULL);
+       i = regcomp(t, re, REG_EXTENDED | REG_NOSUB);
+       assert(i == 0);
+       *rep = t;
+}
+
+void
+VRT_re_fini(void *rep)
+{
+
+       if (rep != NULL)
+               regfree(rep);
+}
+
+int
+VRT_re_match(const char *s, void *re)
+{
+       regex_t *t;
+       int i;
+
+       t = re;
+       i = regexec(t, s, 0, NULL, 0);
+       if (i == 0)
+               return (1);
+       assert(i == REG_NOMATCH);
+       return (0);
+}
+
+int
+VRT_re_test(struct sbuf *sb, const char *re)
+{
+       int i, j;
+       regex_t t;      
+       char buf[BUFSIZ];
+
+       memset(&t, 0, sizeof t);
+       i = regcomp(&t, re, REG_EXTENDED | REG_NOSUB);
+       if (i == 0) {
+               regfree(&t);
+               return (0);
+       }
+       j = regerror(i, &t, buf, sizeof buf);
+       sbuf_printf(sb, "Regexp compilation error:\n\n%s\n\n", buf);
+       regfree(&t);
+       return (1);
+}
index 73cbcf63b649a31a086beef13ee61b8e8624e7b7..7b50770315f9e17840ff4a43aaa19b4530b79434 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 struct sess;
+struct sbuf;
 struct backend;
 struct VCL_conf;
 
@@ -32,6 +33,12 @@ int VRT_acl_match(struct sess *, const char *, struct vrt_acl *);
 void VRT_acl_init(struct vrt_acl *);
 void VRT_acl_fini(struct vrt_acl *);
 
+/* Regexp related */
+void VRT_re_init(void **, const char *);
+void VRT_re_fini(void *);
+int VRT_re_match(const char *, void *re);
+int VRT_re_test(struct sbuf *, const char *);
+
 void VRT_count(struct sess *, unsigned);
 int VRT_rewrite(const char *, const char *);
 void VRT_error(struct sess *, unsigned, const char *);
index 7b3caf07ed22404605670fe780453c8fc1320049..66898cb9bc9c47e556942a3277aed0e2c5de2f2d 100644 (file)
@@ -54,6 +54,7 @@
 #include "vcc_priv.h"
 #include "vcc_compile.h"
 
+#include "vrt.h"
 #include "libvcl.h"
 
 static struct method method_tab[] = {
@@ -468,6 +469,28 @@ RateVal(struct tokenlist *tl)
        Fc(tl, 0, "(%g * %g)", v, sc);
 }
 
+/*--------------------------------------------------------------------*/
+
+static void
+vcc_re(struct tokenlist *tl, const char *str, struct token *re)
+{
+       char buf[32], *p;
+
+       p = EncString(re);
+       if (VRT_re_test(tl->sb, p)) {
+               vcc_ErrWhere(tl, re);
+               return;
+       }
+       free(p);
+       sprintf(buf, "VGC_re_%u", tl->recnt++);
+
+       Fc(tl, 1, "VRT_re_match(%s, %s)\n", str, buf);
+       Fh(tl, 0, "void *%s;\n", buf);
+       Fi(tl, 0, "\tVRT_re_init(&%s, %T);\n", buf, re);
+       Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf);
+}
+
+
 /*--------------------------------------------------------------------*/
 
 static void
@@ -476,10 +499,9 @@ Cond_String(struct var *vp, struct tokenlist *tl)
 
        switch (tl->t->tok) {
        case '~':
-               Fc(tl, 1, "string_match(%s, ", vp->rname);
                vcc_NextToken(tl);
                ExpectErr(tl, CSTR);
-               Fc(tl, 0, "%T)\n", tl->t);
+               vcc_re(tl, vp->rname, tl->t);
                vcc_NextToken(tl);
                break;
        case T_EQ:
index 0ddfa437ea3fc26e7a0c1144a92f978e6ec6e924..db5302589b188ccf004a6f75c959e71b90997b53 100644 (file)
@@ -29,6 +29,8 @@ struct tokenlist {
        int                     nbackend;
        TAILQ_HEAD(, proc)      procs;
        struct proc             *curproc;
+
+       unsigned                recnt;
 };
 
 enum var_type {
index 4d8870c23b2bec8c9a2f1ff8e11ca44a4a1fa7b2..6675de1ed5547e11159afa761ae3a6bdcc2f5e00 100644 (file)
@@ -474,6 +474,7 @@ vcl_output_lang_h(FILE *f)
        fputs(" */\n", f);
        fputs("\n", f);
        fputs("struct sess;\n", f);
+       fputs("struct sbuf;\n", f);
        fputs("struct backend;\n", f);
        fputs("struct VCL_conf;\n", f);
        fputs("\n", f);
@@ -498,6 +499,12 @@ vcl_output_lang_h(FILE *f)
        fputs("void VRT_acl_init(struct vrt_acl *);\n", f);
        fputs("void VRT_acl_fini(struct vrt_acl *);\n", f);
        fputs("\n", f);
+       fputs("/* Regexp related */\n", f);
+       fputs("void VRT_re_init(void **, const char *);\n", f);
+       fputs("void VRT_re_fini(void *);\n", f);
+       fputs("int VRT_re_match(const char *, void *re);\n", f);
+       fputs("int VRT_re_test(struct sbuf *, const char *);\n", f);
+       fputs("\n", f);
        fputs("void VRT_count(struct sess *, unsigned);\n", f);
        fputs("int VRT_rewrite(const char *, const char *);\n", f);
        fputs("void VRT_error(struct sess *, unsigned, const char *);\n", f);