Commit 259e2b8f authored by Dridi Boukelmoune's avatar Dridi Boukelmoune

vmod_cookie: Use the new REGEX type

And get a glimpse at how we can simplify VMODs making use of regular
expressions without breaking existing VCL.
parent 2b132048
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include <cache/cache.h> #include <cache/cache.h>
#include <vsb.h> #include <vsb.h>
#include <vre.h>
#include "vcc_cookie_if.h" #include "vcc_cookie_if.h"
...@@ -53,8 +52,6 @@ enum filter_action { ...@@ -53,8 +52,6 @@ enum filter_action {
whitelist whitelist
}; };
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
struct cookie { struct cookie {
unsigned magic; unsigned magic;
#define VMOD_COOKIE_ENTRY_MAGIC 0x3BB41543 #define VMOD_COOKIE_ENTRY_MAGIC 0x3BB41543
...@@ -237,76 +234,23 @@ vmod_get(VRT_CTX, struct vmod_priv *priv, VCL_STRING name) ...@@ -237,76 +234,23 @@ vmod_get(VRT_CTX, struct vmod_priv *priv, VCL_STRING name)
} }
static vre_t *
compile_re(VRT_CTX, VCL_STRING expression)
{
vre_t *vre;
const char *error;
int erroroffset;
vre = VRE_compile(expression, 0, &error, &erroroffset);
if (vre == NULL) {
VSLb(ctx->vsl, SLT_Error,
"cookie: PCRE compile error at char %i: %s",
erroroffset, error);
}
return (vre);
}
static void
free_re(void *priv)
{
vre_t *vre;
AN(priv);
vre = priv;
VRE_free(&vre);
AZ(vre);
}
static const struct vmod_priv_methods cookie_re_priv_methods[1] = {{
.magic = VMOD_PRIV_METHODS_MAGIC,
.type = "vmod_cookie_re",
.fini = free_re
}};
VCL_STRING VCL_STRING
vmod_get_re(VRT_CTX, struct vmod_priv *priv, struct vmod_priv *priv_call, vmod_get_re(VRT_CTX, struct vmod_priv *priv, VCL_REGEX re)
VCL_STRING expression)
{ {
struct vmod_cookie *vcp = cobj_get(priv); struct vmod_cookie *vcp = cobj_get(priv);
int i, ovector[VRE_MAX_GROUPS];
struct cookie *cookie = NULL; struct cookie *cookie = NULL;
struct cookie *current; struct cookie *current;
vre_t *vre = NULL; unsigned match;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (expression == NULL || *expression == '\0') AN(re);
return (NULL);
if (priv_call->priv == NULL) {
AZ(pthread_mutex_lock(&mtx));
vre = compile_re(ctx, expression);
if (vre == NULL) {
AZ(pthread_mutex_unlock(&mtx));
return (NULL);
}
priv_call->priv = vre;
priv_call->methods = cookie_re_priv_methods;
AZ(pthread_mutex_unlock(&mtx));
}
VTAILQ_FOREACH(current, &vcp->cookielist, list) { VTAILQ_FOREACH(current, &vcp->cookielist, list) {
CHECK_OBJ_NOTNULL(current, VMOD_COOKIE_ENTRY_MAGIC); CHECK_OBJ_NOTNULL(current, VMOD_COOKIE_ENTRY_MAGIC);
VSLb(ctx->vsl, SLT_Debug, "cookie: checking %s", current->name); VSLb(ctx->vsl, SLT_Debug, "cookie: checking %s", current->name);
i = VRE_exec(vre, current->name, strlen(current->name), 0, 0, match = VRT_re_match(ctx, current->name, re);
ovector, VRE_MAX_GROUPS, NULL); if (!match)
if (i < 0)
continue; continue;
VSLb(ctx->vsl, SLT_Debug, "cookie: %s is a match for regex '%s'",
current->name, expression);
cookie = current; cookie = current;
break; break;
} }
...@@ -425,37 +369,23 @@ vmod_filter(VRT_CTX, struct vmod_priv *priv, VCL_STRING blacklist_s) ...@@ -425,37 +369,23 @@ vmod_filter(VRT_CTX, struct vmod_priv *priv, VCL_STRING blacklist_s)
} }
static VCL_VOID static VCL_VOID
re_filter(VRT_CTX, struct vmod_priv *priv, struct vmod_priv *priv_call, re_filter(VRT_CTX, struct vmod_priv *priv, VCL_REGEX re, enum filter_action mode)
VCL_STRING expression, enum filter_action mode)
{ {
struct vmod_cookie *vcp = cobj_get(priv); struct vmod_cookie *vcp = cobj_get(priv);
struct cookie *current, *safeptr; struct cookie *current, *safeptr;
int i, ovector[VRE_MAX_GROUPS]; unsigned match;
vre_t *vre;
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (priv_call->priv == NULL) { AN(re);
AZ(pthread_mutex_lock(&mtx));
vre = compile_re(ctx, expression);
if (vre == NULL) {
AZ(pthread_mutex_unlock(&mtx));
return; // Not much else to do, error already logged.
}
priv_call->priv = vre;
priv_call->methods = cookie_re_priv_methods;
AZ(pthread_mutex_unlock(&mtx));
}
VTAILQ_FOREACH_SAFE(current, &vcp->cookielist, list, safeptr) { VTAILQ_FOREACH_SAFE(current, &vcp->cookielist, list, safeptr) {
CHECK_OBJ_NOTNULL(current, VMOD_COOKIE_ENTRY_MAGIC); CHECK_OBJ_NOTNULL(current, VMOD_COOKIE_ENTRY_MAGIC);
i = VRE_exec(priv_call->priv, current->name, match = VRT_re_match(ctx, current->name, re);
strlen(current->name), 0, 0, ovector, VRE_MAX_GROUPS, NULL);
switch (mode) { switch (mode) {
case blacklist: case blacklist:
if (i < 0) if (!match)
continue; continue;
VSLb(ctx->vsl, SLT_Debug, VSLb(ctx->vsl, SLT_Debug,
"Removing matching cookie %s (value: %s)", "Removing matching cookie %s (value: %s)",
...@@ -463,12 +393,8 @@ re_filter(VRT_CTX, struct vmod_priv *priv, struct vmod_priv *priv_call, ...@@ -463,12 +393,8 @@ re_filter(VRT_CTX, struct vmod_priv *priv, struct vmod_priv *priv_call,
VTAILQ_REMOVE(&vcp->cookielist, current, list); VTAILQ_REMOVE(&vcp->cookielist, current, list);
break; break;
case whitelist: case whitelist:
if (i >= 0) { if (match)
VSLb(ctx->vsl, SLT_Debug,
"Cookie %s matches expression '%s'",
current->name, expression);
continue; continue;
}
VSLb(ctx->vsl, SLT_Debug, VSLb(ctx->vsl, SLT_Debug,
"Removing cookie %s (value: %s)", "Removing cookie %s (value: %s)",
...@@ -483,22 +409,20 @@ re_filter(VRT_CTX, struct vmod_priv *priv, struct vmod_priv *priv_call, ...@@ -483,22 +409,20 @@ re_filter(VRT_CTX, struct vmod_priv *priv, struct vmod_priv *priv_call,
VCL_VOID VCL_VOID
vmod_keep_re(VRT_CTX, struct vmod_priv *priv, struct vmod_priv *priv_call, vmod_keep_re(VRT_CTX, struct vmod_priv *priv, VCL_REGEX re)
VCL_STRING expression)
{ {
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
re_filter(ctx, priv, priv_call, expression, whitelist); re_filter(ctx, priv, re, whitelist);
} }
VCL_VOID VCL_VOID
vmod_filter_re(VRT_CTX, struct vmod_priv *priv, struct vmod_priv *priv_call, vmod_filter_re(VRT_CTX, struct vmod_priv *priv, VCL_REGEX re)
VCL_STRING expression)
{ {
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
re_filter(ctx, priv, priv_call, expression, blacklist); re_filter(ctx, priv, re, blacklist);
} }
......
...@@ -81,7 +81,7 @@ Example:: ...@@ -81,7 +81,7 @@ Example::
} }
$Function VOID filter_re(PRIV_TASK, PRIV_CALL, STRING expression) $Function VOID filter_re(PRIV_TASK, REGEX expression)
Delete all cookies from internal vmod storage that matches the Delete all cookies from internal vmod storage that matches the
regular expression ``expression``. regular expression ``expression``.
...@@ -109,7 +109,7 @@ Example:: ...@@ -109,7 +109,7 @@ Example::
# "cookie1: value1; cookie2: value2;"; # "cookie1: value1; cookie2: value2;";
} }
$Function VOID keep_re(PRIV_TASK, PRIV_CALL, STRING expression) $Function VOID keep_re(PRIV_TASK, REGEX expression)
Delete all cookies from internal vmod storage that does not match Delete all cookies from internal vmod storage that does not match
expression ``expression``. expression ``expression``.
...@@ -155,7 +155,7 @@ Example:: ...@@ -155,7 +155,7 @@ Example::
std.log("cookie1 value is: " + cookie.get("cookie1")); std.log("cookie1 value is: " + cookie.get("cookie1"));
} }
$Function STRING get_re(PRIV_TASK, PRIV_CALL, STRING expression) $Function STRING get_re(PRIV_TASK, REGEX expression)
Get the value of the first cookie in internal vmod storage that matches Get the value of the first cookie in internal vmod storage that matches
regular expression ``expression``. If nothing matches, an empty string regular expression ``expression``. If nothing matches, an empty string
......
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