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

Implement regexp matching of strings in VCL.

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: http://www.varnish-cache.org/svn/trunk/varnish-cache@559 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 87ffa18d
......@@ -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 \
......
/*
* $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);
}
......@@ -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 *);
......
......@@ -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:
......
......@@ -29,6 +29,8 @@ struct tokenlist {
int nbackend;
TAILQ_HEAD(, proc) procs;
struct proc *curproc;
unsigned recnt;
};
enum var_type {
......
......@@ -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);
......
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