[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