Commit f4369ade authored by Geoff Simmons's avatar Geoff Simmons

Backport to Varnish 5.2.x.

parent 4f62d54f
......@@ -18,20 +18,13 @@ Varnish Module for matching strings associated with backends, regexen and other
:Manual section: 3
.. _VMOD re2: https://code.uplex.de/uplex-varnish/libvmod-re2
SYNOPSIS
========
::
import selector [from "path"] ;
import selector;
::
# Set creation
new <obj> = selector.set([BOOL case_sensitive])
......@@ -314,11 +307,20 @@ or the longest match, and so on::
# bar_backend for /foo/bar/quux
# foo_backend for /foo/quux
CONTENTS
========
* set(BOOL)
* STRING version()
.. _obj_set:
new xset = set(BOOL case_sensitive=1)
-------------------------------------
set
---
::
new OBJ = set(BOOL case_sensitive=1)
Create a set object. When ``case_sensitive`` is ``false``, matches
using the ``.match()`` and ``.hasprefix()`` methods are
......@@ -337,17 +339,12 @@ Example::
.. _func_set.add:
set.add(...)
------------
set.add
-------
::
VOID xset.add(
STRING,
STRING string=0,
STRING regex=0,
BACKEND backend=0
)
VOID set.add(STRING, STRING string=0, STRING regex=0, BACKEND backend=0)
Add the given string to the set. As indicated above, elements added to
the set are implicitly numbered in the order in which they are added
......@@ -384,11 +381,14 @@ Example::
regex="^/quux/([^/]+)/");
}
.. _func_set.create_stats:
VOID xset.create_stats()
------------------------
set.create_stats
----------------
::
VOID set.create_stats(PRIV_VCL)
Creates statistics counters for this object that are displayed by
tools such as ``varnishstat(1)``. See `STATISTICS`_ below for details.
......@@ -417,11 +417,14 @@ Example::
myset.create_stats();
}
.. _func_set.match:
BOOL xset.match(STRING)
-----------------------
set.match
---------
::
BOOL set.match(STRING)
Returns ``true`` if the given STRING exactly matches one of the
strings in the set. The match is case insensitive if and only if the
......@@ -442,11 +445,14 @@ Example::
call do_on_match;
}
.. _func_set.hasprefix:
BOOL xset.hasprefix(STRING)
---------------------------
set.hasprefix
-------------
::
BOOL set.hasprefix(STRING)
Returns ``true`` if the STRING to be matched has a prefix that is in
the set. The match is case insensitive if ``case_sensitive`` was set
......@@ -461,11 +467,14 @@ Example::
call do_if_prefix_matched;
}
.. _func_set.nmatches:
INT xset.nmatches()
-------------------
set.nmatches
------------
::
INT set.nmatches()
Returns the number of elements that were matched by the most recent
successful invocation of ``.match()`` or ``.hasprefix()`` for the same
......@@ -495,11 +504,14 @@ Example::
set bereq.backend = myset.backend(select=UNIQUE);
}
.. _func_set.matched:
BOOL xset.matched(INT)
----------------------
set.matched
-----------
::
BOOL set.matched(INT)
After a successful ``.match()`` or ``.hasprefix()`` call for the same
set object in the same task scope, return ``true`` if the element
......@@ -526,17 +538,14 @@ Example::
}
}
.. _func_set.which:
INT xset.which(ENUM select)
---------------------------
set.which
---------
::
INT xset.which(
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
INT set.which(ENUM {UNIQUE,EXACT,FIRST,LAST,SHORTEST,LONGEST} select="UNIQUE")
After a successful ``.match()`` or ``.hasprefix()`` call for the same
set object in the same task scope, return the index of the matching
......@@ -567,18 +576,14 @@ Example::
}
}
.. _func_set.element:
STRING xset.element(INT n, ENUM select)
---------------------------------------
set.element
-----------
::
STRING xset.element(
INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
STRING set.element(INT n=0, ENUM {UNIQUE,EXACT,FIRST,LAST,SHORTEST,LONGEST} select="UNIQUE")
Returns the element of the set indicated by the ``n`` and ``select``
parameters as described above. Thus if ``n`` >= 1, the ``n``-th
......@@ -609,18 +614,14 @@ Example::
set resp.http.Location = "http://other.com" + myset.element();
}
.. _func_set.backend:
BACKEND xset.backend(INT n, ENUM select)
----------------------------------------
set.backend
-----------
::
BACKEND xset.backend(
INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
BACKEND set.backend(INT n=0, ENUM {UNIQUE,EXACT,FIRST,LAST,SHORTEST,LONGEST} select="UNIQUE")
Returns the backend associated with the element of the set indicated
by ``n`` and ``select``, according to the rules given above; that is,
......@@ -642,18 +643,14 @@ Example::
set bereq.backend = myset.backend(select=LONGEST);
}
.. _func_set.string:
STRING xset.string(INT n, ENUM select)
--------------------------------------
set.string
----------
::
STRING xset.string(
INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
STRING set.string(INT n=0, ENUM {UNIQUE,EXACT,FIRST,LAST,SHORTEST,LONGEST} select="UNIQUE")
Returns the string set by the ``string`` parameter for the element of
the set indicated by ``n`` and ``select``, according to the rules
......@@ -672,19 +669,14 @@ Example::
set req.url = myset.string();
}
.. _func_set.re_match:
BOOL xset.re_match(STRING subject, INT n, ENUM select)
------------------------------------------------------
set.re_match
------------
::
BOOL xset.re_match(
STRING subject,
INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
BOOL set.re_match(STRING subject, INT n=0, ENUM {UNIQUE,EXACT,FIRST,LAST,SHORTEST,LONGEST} select="UNIQUE")
Using the regular expression set by the ``regex`` parameter for the
element of the set indicated by ``n`` and ``select``, return the
......@@ -721,21 +713,14 @@ Example::
}
}
.. _func_set.sub:
set.sub(...)
------------
set.sub
-------
::
STRING xset.sub(
STRING str,
STRING sub,
BOOL all=0,
INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
STRING set.sub(STRING str, STRING sub, BOOL all=0, INT n=0, ENUM {UNIQUE,EXACT,FIRST,LAST,SHORTEST,LONGEST} select="UNIQUE")
Using the regular expression set by the ``regex`` parameter for the
element of the set indicated by ``n`` and ``select``, return the
......@@ -782,22 +767,25 @@ Example::
# /foo/bar/1/2/* is rewritten as /foo/bar/2/1/*
# /foo/bar/baz/1/2/* is rewritten as /foo/bar/baz/2/1/*
.. _func_set.debug:
STRING xset.debug()
-------------------
set.debug
---------
Intentionally not documented.
::
STRING set.debug()
Intentionally not documented.
.. _func_version:
version
-------
.. _func_version:
::
STRING version()
----------------
STRING version()
Return the version string for this VMOD.
......@@ -852,11 +840,6 @@ The VMOD currently provides the following statistics:
The values of the stats are constant; they do not change during the
lifetime of the VCL instance.
The stats for a VCL instance are removed from view when the instance is
set to the cold state, and become visible again when it set to the warm
state. They are removed permanently when the VCL instance is discarded
(see varnish-cli(7)).
ERRORS
======
......@@ -950,3 +933,6 @@ COPYRIGHT
See LICENSE
.. _VMOD re2: https://code.uplex.de/uplex-varnish/libvmod-re2
......@@ -37,9 +37,8 @@ AM_CONDITIONAL(HAVE_RST2MAN, [test "x$RST2MAN" != "xno"])
m4_ifndef([VARNISH_PREREQ], AC_MSG_ERROR([Need varnish.m4 -- see README.rst]))
VARNISH_PREREQ([6.0.0])
VARNISH_PREREQ([5.2.0 5.2.1])
VARNISH_VMODS([selector])
VARNISH_COUNTERS([selector])
VMOD_TESTS="$(cd $srcdir/src && echo tests/*.vtc)"
AC_SUBST(VMOD_TESTS)
......@@ -92,6 +91,24 @@ if test "x$enable_debugging" != "xno"; then
[])
fi
# Varnish since 5.2.0 depends on AC_DEFINE(STATIC_ASSERT)
save_LIBS="${LIBS}"
LIBS=""
AC_CACHE_CHECK([for _Static_assert],
[ac_cv_static_assert],
[AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
_Static_assert(1 == sizeof(char), "didn't work");
]],[[
]])],
[ac_cv_static_assert=yes],
[ac_cv_static_assert=no])
])
if test "$ac_cv_static_assert" = yes; then
AC_DEFINE([STATIC_ASSERT], [1], [Define if _Static_assert is availabel])
fi
LIBS="${save_LIBS}"
AC_CONFIG_FILES([
Makefile
src/Makefile
......
......@@ -18,7 +18,8 @@ nodist_libvmod_selector_la_SOURCES = \
dist_man_MANS = vmod_selector.3
@BUILD_VSC_SELECTOR@
VSC_selector.c VSC_selector.h: selector.vsc
$(PYTHON) $(VSCTOOL) -ch $(srcdir)/selector.vsc
vmod_selector.c patricia.c: patricia.h
......
......@@ -31,6 +31,8 @@
* implementation.
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
......
......@@ -68,11 +68,10 @@ varnish v1 -expect SELECTOR.vcl2.e.dmin == 0
varnish v1 -expect SELECTOR.vcl2.e.dmax == 0
varnish v1 -expect SELECTOR.vcl2.e.davg == 0
# When vcl1 is set to cold, stats for vcl2.p but not vcl1.s appear.
# cold/warm states do *not* affect stats visibility in Varnish < 6.0.0
varnish v1 -cliok "vcl.state vcl1 cold"
varnish v1 -vsc SELECTOR.*
# When vcl1 is set back to warm, stats for vcl2.p and vcl1.s appear.
varnish v1 -cliok "vcl.state vcl1 warm"
varnish v1 -vsc SELECTOR.*
varnish v1 -expect SELECTOR.vcl1.s.elements == 4
......
......@@ -37,6 +37,7 @@
#include "cache/cache.h"
#include "vcl.h"
#include "vrt.h"
#include "vre.h"
#include "vbm.h"
#include "cache/cache_director.h"
......@@ -93,7 +94,7 @@ struct vsc_entry {
unsigned magic;
#define VMOD_SELECTOR_VSC_MAGIC 0x4b99b64a
VSLIST_ENTRY(vsc_entry) list;
struct vsc_seg *vsc_seg;
struct VSC_selector *vsc;
};
VSLIST_HEAD(vsc_head, vsc_entry);
......@@ -128,23 +129,14 @@ event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
while (!VSLIST_EMPTY(vsc_head)) {
vsc_entry = VSLIST_FIRST(vsc_head);
CHECK_OBJ_NOTNULL(vsc_entry, VMOD_SELECTOR_VSC_MAGIC);
VSC_selector_Destroy(&vsc_entry->vsc_seg);
VSC_selector_Destroy(&vsc_entry->vsc);
VSLIST_REMOVE_HEAD(vsc_head, list);
FREE_OBJ(vsc_entry);
}
free(vsc_head);
break;
case VCL_EVENT_WARM:
VSLIST_FOREACH(vsc_entry, vsc_head, list) {
CHECK_OBJ_NOTNULL(vsc_entry, VMOD_SELECTOR_VSC_MAGIC);
VRT_VSC_Reveal(vsc_entry->vsc_seg);
}
break;
case VCL_EVENT_COLD:
VSLIST_FOREACH(vsc_entry, vsc_head, list) {
CHECK_OBJ_NOTNULL(vsc_entry, VMOD_SELECTOR_VSC_MAGIC);
VRT_VSC_Hide(vsc_entry->vsc_seg);
}
break;
default:
WRONG("illegal event enum");
......@@ -537,7 +529,8 @@ select(VRT_CTX, const struct match_data * const restrict match,
const char * const restrict obj, VCL_ENUM const restrict selects,
const char * const restrict method)
{
if (selects == vmod_enum_EXACT) {
if (selects[0] == 'E') {
AZ(strcmp(selects + 1, "XACT"));
if (match->exact == UINT_MAX)
VERR(ctx, "%s.%s(select=EXACT): "
"no element matched exactly", obj, method);
......@@ -546,20 +539,26 @@ select(VRT_CTX, const struct match_data * const restrict match,
if (match->n == 1)
return match->indices[0];
if (selects == vmod_enum_UNIQUE) {
switch(selects[0]) {
case 'U':
AZ(strcmp(selects + 1, "NIQUE"));
VERR(ctx, "%s.%s(select=UNIQUE): %d elements were matched",
obj, method, match->n);
return (UINT_MAX);
}
if (selects == vmod_enum_FIRST)
case 'F':
AZ(strcmp(selects + 1, "IRST"));
return match->min;
if (selects == vmod_enum_LAST)
return match->max;
if (selects == vmod_enum_SHORTEST)
case 'S':
AZ(strcmp(selects + 1, "HORTEST"));
return match->indices[0];
if (selects == vmod_enum_LONGEST)
return match->indices[match->n - 1];
WRONG("illegal select enum");
case 'L':
if (strcmp(selects + 1, "AST") == 0)
return match->max;
if (strcmp(selects + 1, "ONGEST") == 0)
return match->indices[match->n - 1];
default:
WRONG("illegal select enum");
}
return (UINT_MAX);
}
......@@ -739,7 +738,6 @@ vmod_set_create_stats(VRT_CTX, struct vmod_selector_set *set,
{
struct pt_stats stats = { .magic = PT_STATS_MAGIC };
struct VSC_selector *vsc;
struct vsc_seg *vsc_seg;
struct vsc_head *vsc_head;
struct vsc_entry *vsc_entry;
......@@ -771,8 +769,7 @@ vmod_set_create_stats(VRT_CTX, struct vmod_selector_set *set,
assert(stats.davg <= stats.dmax);
}
vsc = VSC_selector_New(NULL, &vsc_seg, "%s.%s", VCL_Name(ctx->vcl),
set->vcl_name);
vsc = VSC_selector_New("%s.%s", VCL_Name(ctx->vcl), set->vcl_name);
vsc->elements = set->nmembers;
vsc->nodes = stats.nodes;
vsc->leaves = stats.leaves;
......@@ -782,7 +779,7 @@ vmod_set_create_stats(VRT_CTX, struct vmod_selector_set *set,
ALLOC_OBJ(vsc_entry, VMOD_SELECTOR_VSC_MAGIC);
AN(vsc_entry);
vsc_entry->vsc_seg = vsc_seg;
vsc_entry->vsc = vsc;
VSLIST_INSERT_HEAD(vsc_head, vsc_entry, list);
}
......
......@@ -7,21 +7,12 @@
# See LICENSE
#
$Module selector 3 Varnish Module for matching strings associated with backends, regexen and other strings
$ABI vrt
.. _VMOD re2: https://code.uplex.de/uplex-varnish/libvmod-re2
$Synopsis manual
SYNOPSIS
========
$Module selector 3 Varnish Module for matching strings associated with backends, regexen and other strings
::
import selector;
# Set creation
new <obj> = selector.set([BOOL case_sensitive])
VOID <obj>.add(STRING [, STRING string] [, STRING regex]
......@@ -480,7 +471,7 @@ Example::
}
$Method INT .which(ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
select="UNIQUE")
After a successful ``.match()`` or ``.hasprefix()`` call for the same
set object in the same task scope, return the index of the matching
......@@ -513,7 +504,7 @@ Example::
$Method STRING .element(INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
select="UNIQUE")
Returns the element of the set indicated by the ``n`` and ``select``
parameters as described above. Thus if ``n`` >= 1, the ``n``-th
......@@ -546,7 +537,7 @@ Example::
$Method BACKEND .backend(INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
select="UNIQUE")
Returns the backend associated with the element of the set indicated
by ``n`` and ``select``, according to the rules given above; that is,
......@@ -570,7 +561,7 @@ Example::
$Method STRING .string(INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
select="UNIQUE")
Returns the string set by the ``string`` parameter for the element of
the set indicated by ``n`` and ``select``, according to the rules
......@@ -591,7 +582,7 @@ Example::
$Method BOOL .re_match(STRING subject, INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
select="UNIQUE")
Using the regular expression set by the ``regex`` parameter for the
element of the set indicated by ``n`` and ``select``, return the
......@@ -630,7 +621,7 @@ Example::
$Method STRING .sub(STRING str, STRING sub, BOOL all=0, INT n=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
select="UNIQUE")
Using the regular expression set by the ``regex`` parameter for the
element of the set indicated by ``n`` and ``select``, return the
......@@ -736,11 +727,6 @@ The VMOD currently provides the following statistics:
The values of the stats are constant; they do not change during the
lifetime of the VCL instance.
The stats for a VCL instance are removed from view when the instance is
set to the cold state, and become visible again when it set to the warm
state. They are removed permanently when the VCL instance is discarded
(see varnish-cli(7)).
ERRORS
======
......@@ -822,3 +808,5 @@ SEE ALSO
* `VMOD re2`_: https://code.uplex.de/uplex-varnish/libvmod-re2
$Event event
$ABI vrt
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