[master] a2519bc Add a VSL_Glob2Tags function to the API.
Martin Blix Grydeland
martin at varnish-cache.org
Tue Oct 1 14:48:18 CEST 2013
commit a2519bc9477791baa4ac60792443bdb1b2f297be
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date: Tue Sep 24 12:31:46 2013 +0200
Add a VSL_Glob2Tags function to the API.
VSL_Glob2Tags allows matching VSL tags against a glob expression.
diff --git a/include/vapi/vsl.h b/include/vapi/vsl.h
index 7f6f98d..7c998de 100644
--- a/include/vapi/vsl.h
+++ b/include/vapi/vsl.h
@@ -96,6 +96,15 @@ typedef int VSLQ_dispatch_f(struct VSL_data *vsl,
* !=0: Makes VSLQ_Dispatch return with this return value immediatly
*/
+typedef void VSL_glob2tags_f(int tag, void *priv);
+ /*
+ * The callback function type for use with VSL_Glob2Tags.
+ *
+ * Arguments:
+ * tag: Tag number (= enum VSL_tag_e)
+ * priv: The priv argument from VSL_Glob2Tag
+ */
+
extern const char *VSL_tags[SLT__MAX];
/*
* Tag to string array. Contains NULL for invalid tags.
@@ -117,6 +126,25 @@ int VSL_Name2Tag(const char *name, int l);
* -2: Multiple tags match substring
*/
+int VSL_Glob2Tags(const char *glob, int l, VSL_glob2tags_f *func, void *priv);
+ /*
+ * Convert a string to multiple tag matches. The string can have
+ * either a prefix or postfix wildcard (*) character. For each
+ * matching tag func is called. Matching is done case insensitive.
+ *
+ * Arguments:
+ * glob: The string to match
+ * l: The length of glob. -1 to use strlen.
+ * func: The function to call (can be NULL)
+ * priv: An argument that will be passed to func.
+ *
+ * Return values:
+ * >0: Number of times func was called for matching tags.
+ * -1: No tag matches
+ * -2: Multiple tags match non-glob input
+ * -3: Syntax error
+ */
+
int VSLQ_Name2Grouping(const char *name, int l);
/*
* Convert string to grouping (= enum VSL_grouping_e)
diff --git a/lib/libvarnishapi/libvarnishapi.map b/lib/libvarnishapi/libvarnishapi.map
index 384c0e1..42315a0 100644
--- a/lib/libvarnishapi/libvarnishapi.map
+++ b/lib/libvarnishapi/libvarnishapi.map
@@ -115,5 +115,6 @@ LIBVARNISHAPI_1.3 {
VSLQ_Dispatch;
VSLQ_Flush;
VSLQ_Name2Grouping;
+ VSL_Glob2Tags;
# Variables:
} LIBVARNISHAPI_1.0;
diff --git a/lib/libvarnishapi/vsl_arg.c b/lib/libvarnishapi/vsl_arg.c
index 8a2c48d..da54295 100644
--- a/lib/libvarnishapi/vsl_arg.c
+++ b/lib/libvarnishapi/vsl_arg.c
@@ -83,6 +83,75 @@ VSL_Name2Tag(const char *name, int l)
return (n);
}
+int
+VSL_Glob2Tags(const char *glob, int l, VSL_glob2tags_f *func, void *priv)
+{
+ int i, r, l2;
+ int pre = 0;
+ int post = 0;
+ char buf[64];
+
+ AN(glob);
+ if (l < 0)
+ l = strlen(glob);
+ if (l == 0 || l > sizeof buf - 1)
+ return (-1);
+ if (strchr(glob, '*') != NULL) {
+ if (glob[0] == '*') {
+ /* Prefix wildcard */
+ pre = 1;
+ glob++;
+ l--;
+ }
+ if (l > 0 && glob[l - 1] == '*') {
+ /* Postfix wildcard */
+ post = 1;
+ l--;
+ }
+ }
+ if (pre && post)
+ /* Support only post or prefix wildcards */
+ return (-3);
+ memcpy(buf, glob, l);
+ buf[l] = '\0';
+ if (strchr(buf, '*') != NULL)
+ /* No multiple wildcards */
+ return (-3);
+ if (pre == 0 && post == 0) {
+ /* No wildcards, use VSL_Name2Tag */
+ i = VSL_Name2Tag(buf, l);
+ if (i < 0)
+ return (i);
+ if (func != NULL)
+ (func)(i, priv);
+ return (1);
+ }
+
+ r = 0;
+ for (i = 0; i < SLT__MAX; i++) {
+ if (VSL_tags[i] == NULL)
+ continue;
+ l2 = strlen(VSL_tags[i]);
+ if (l2 < l)
+ continue;
+ if (pre) {
+ /* Prefix wildcard match */
+ if (strcasecmp(buf, VSL_tags[i] + l2 - l))
+ continue;
+ } else {
+ /* Postfix wildcard match */
+ if (strncasecmp(buf, VSL_tags[i], l))
+ continue;
+ }
+ if (func != NULL)
+ (func)(i, priv);
+ r++;
+ }
+ if (r == 0)
+ return (-1);
+ return (r);
+}
+
static const char * const vsl_grouping[] = {
[VSL_g_raw] = "raw",
[VSL_g_vxid] = "vxid",
More information about the varnish-commit
mailing list