Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvmod-selector
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
uplex-varnish
libvmod-selector
Commits
61dfec02
Commit
61dfec02
authored
Oct 16, 2020
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add the element parameter to .matched().
parent
44080166
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
133 additions
and
64 deletions
+133
-64
README.rst
README.rst
+59
-32
match.vtc
src/tests/match.vtc
+8
-0
vmod_selector.c
src/vmod_selector.c
+9
-1
vmod_selector.vcc
src/vmod_selector.vcc
+57
-31
No files found.
README.rst
View file @
61dfec02
...
...
@@ -38,7 +38,7 @@ SYNOPSIS
# Match properties
INT <obj>.nmatches()
BOOL <obj>.matched([INT n] [, ENUM select])
BOOL <obj>.matched([INT n] [,
STRING element] [,
ENUM select])
INT <obj>.which([ENUM select])
# Retrieving objects after match
...
...
@@ -618,59 +618,74 @@ Example::
.. _xset.matched():
BOOL xset.matched(INT n, ENUM select)
-------------------------------------
BOOL xset.matched(INT n,
STRING element,
ENUM select)
-------------------------------------
----------------
::
BOOL xset.matched(
INT n=0,
STRING element=0,
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 ``true`` if the element
indicated by the ``n``
and ``select`` parameters was matched, according to
the rules described above.
indicated by the ``n``
, ``element`` and ``select`` parameters was
matched, according to
the rules described above.
For example if ``n`` > 0, ``.matched(n)`` returns ``true`` if and only
if the ``n``-th element matched. The numbering corresponds to the
order of ``.add()`` invocations in ``vcl_init`` (starting from 1). The
``select`` parameter is ignored in this case.
If ``n`` <= 0, the set element is determined by the ``select`` enum.
In that case, ``.matched()`` returns ``true`` if and only if the
element indicated by the enum was matched by the previous successful
match operation. These distinctions are only relevant if the previous
operation was ``.hasprefix()``, and more than one string was matched
due to overlapping prefixes. ``.matched()`` returns ``true`` for all
values of ``select`` if the previous successful operation was
``.match()``. ``n`` defaults to 0, so the ``n`` parameter can be left
out if the use of ``select`` is intended.
If ``n`` <= 0 and ``select`` is ``UNIQUE`` or ``EXACT``, then
``.matched()`` returns ``true`` if the enum's criteria are met;
otherwise it returns ``false``, and does not fail. This can be used as
a safeguard for the methods described below, which invoke VCL failure
if either of these two enums are specified, but their criteria are not
met.
``select`` and ``element`` parameters are ignored in this case.
If ``n`` <= 0 and ``element`` is set, then ``.matched()`` returns
``true`` if and only if the string specified by ``element`` was
matched in the previous successful ``.match()`` or ``.hasprefix()``
call. If ``element`` is not in the set, then ``.matched()`` does not
invoke VCL failure (this is a deviation from the general rules for
``element``), but ``.matched()`` always returns ``false`` in that
case. Thus ``.matched()`` can always used with ``element`` to safely
check if a string was previously matched, regardless of whether the
string is in the set.
``n`` defaults to 0, so the ``n`` parameter can be left out if
``element`` is set.
If ``n`` <= 0 and ``element`` is unset, the set element is determined
by the ``select`` enum. In that case, ``.matched()`` returns ``true``
if and only if the element indicated by the enum was matched by the
previous successful match operation. These distinctions are only
relevant if the previous operation was ``.hasprefix()``, and more than
one string was matched due to overlapping prefixes. ``.matched()``
returns ``true`` for all values of ``select`` if the previous
successful operation was ``.match()``.
``n`` defaults to 0 and ``element`` is unset by default, so the ``n``
and ``element`` parameters can be left out if the use of ``select`` is
intended.
If ``n`` <= 0, ``element`` is unset, and ``select`` is ``UNIQUE`` or
``EXACT``, then ``.matched()`` returns ``true`` if the enum's criteria
are met; otherwise it returns ``false``, and does not fail. This can
be used as a safeguard for the methods described below, which invoke
VCL failure if either of these two enums are specified, but their
criteria are not met.
The other enum values (``FIRST``, ``LAST``, ``SHORTEST`` and
``LONGEST``) are included for consistency with the other methods, but
they don't make a relevant distinction. If the prior invocation of
``.match()`` or ``.hasprefix()`` was successful (returned ``true``),
then ``.matched()`` returns ``true`` for each of these, since there is
always an element that meets the criteria. If the prior invocation was
unsuccessful, ``.matched()`` always returns ``false`` for each of the
four enums.
always an element that meets the criteria.
``.matched()`` always returns ``false`` if the most recent
``.match()`` or ``.hasprefix()`` call returned ``false``.
``.matched()`` invokes VCL failure if:
* The
parameter is out of range -- greater than the number of elements
in the set.
* The
``n`` parameter is out of range -- greater than the number of
elements
in the set.
* There was no prior invocation of ``.match()`` or ``.hasprefix()`` in
the same task scope.
...
...
@@ -689,6 +704,12 @@ Example::
}
}
if (url_prefixes.hasprefix(bereq.url)) {
if (urls.matched(element="/foo/")) {
call do_if_foo_was_matched;
}
}
.. _xset.which():
INT xset.which(ENUM select)
...
...
@@ -1059,10 +1080,10 @@ failure is invoked. VCL failure has the same results as if
VCL failure is meant to "fail fast" on conditions that cannot be
correct, or when resource limitations such as workspace exhaustion
prevent further processing. Depending on your use case, you may be
able to use the VMOD's methods without
risk of failure. For example,
if it is known that none of the strings in a set have common prefixes,
then methods with ``select=UNIQUE`` can be used safely after calling
``.hasprefix()``.
able to use the VMOD's methods without
additional checking and with no
risk of failure. For example, if it is known that none of the strings
in a set have common prefixes, then methods with ``select=UNIQUE`` can
be used safely after calling
``.hasprefix()``.
If you need to check against possible failure conditions:
...
...
@@ -1075,6 +1096,12 @@ If you need to check against possible failure conditions:
ensure that VCL load fails if a set unintentionally has strings
with common prefixes.
* In most cases, a method invokes VCL failure if the value of the
``element`` parameter is not in the set. But ``element`` can be used
safely with any string in ``.matched()`` to check if a string
matched previously -- ``.matched()`` returns ``false`` if the
``element`` is not in the set.
See `LIMITATIONS`_ for considerations if you encounter conditions such
as workspace exhaustion.
...
...
src/tests/match.vtc
View file @
61dfec02
...
...
@@ -837,12 +837,16 @@ varnish v1 -vcl {
set resp.http.Matched-Last = s.matched(select=LAST);
set resp.http.Matched-Shortest = s.matched(select=SHORTEST);
set resp.http.Matched-Longest = s.matched(select=LONGEST);
set resp.http.Matched-Foo = s.matched(element="foo");
set resp.http.Matched-Baz = s.matched(element="baz");
set resp.http.Non-Match = s.hasprefix("baz");
set resp.http.Non-Matched-First = s.matched(select=FIRST);
set resp.http.Non-Matched-Last = s.matched(select=LAST);
set resp.http.Non-Matched-Shortest = s.matched(select=SHORTEST);
set resp.http.Non-Matched-Longest = s.matched(select=LONGEST);
set resp.http.Non-Matched-Foo = s.matched(element="foo");
set resp.http.Non-Matched-Baz = s.matched(element="baz");
return (deliver);
}
...
...
@@ -857,11 +861,15 @@ client c1 {
expect resp.http.Matched-Last == "true"
expect resp.http.Matched-Shortest == "true"
expect resp.http.Matched-Longest == "true"
expect resp.http.Matched-Foo == "true"
expect resp.http.Matched-Baz == "false"
expect resp.http.Non-Match == "false"
expect resp.http.Non-Matched-First == "false"
expect resp.http.Non-Matched-Last == "false"
expect resp.http.Non-Matched-Shortest == "false"
expect resp.http.Non-Matched-Longest == "false"
expect resp.http.Non-Matched-Foo == "false"
expect resp.http.Non-Matched-Baz == "false"
txreq -hdr "Range-Error: oops"
rxresp
...
...
src/vmod_selector.c
View file @
61dfec02
...
...
@@ -606,7 +606,7 @@ vmod_set_nmatches(VRT_CTX, struct vmod_selector_set *set)
VCL_BOOL
vmod_set_matched
(
VRT_CTX
,
struct
VPFX
(
selector_set
)
*
set
,
VCL_INT
idx
,
VCL_ENUM
selects
)
VCL_
STRING
element
,
VCL_
ENUM
selects
)
{
struct
match_data
*
match
;
...
...
@@ -636,6 +636,14 @@ vmod_set_matched(VRT_CTX, struct VPFX(selector_set) *set, VCL_INT idx,
return
(
0
);
}
if
(
element
!=
NULL
)
{
for
(
unsigned
i
=
0
;
i
<
match
->
n
;
i
++
)
if
(
strcmp
(
set
->
members
[
match
->
indices
[
i
]],
element
)
==
0
)
return
(
1
);
return
(
0
);
}
if
(
selects
==
VENUM
(
UNIQUE
))
return
(
match
->
n
==
1
);
if
(
selects
==
VENUM
(
EXACT
))
...
...
src/vmod_selector.vcc
View file @
61dfec02
...
...
@@ -34,7 +34,7 @@ SYNOPSIS
# Match properties
INT <obj>.nmatches()
BOOL <obj>.matched([INT n] [, ENUM select])
BOOL <obj>.matched([INT n] [,
STRING element] [,
ENUM select])
INT <obj>.which([ENUM select])
# Retrieving objects after match
...
...
@@ -575,53 +575,67 @@ Example::
set bereq.backend = myset.backend(select=UNIQUE);
}
$Method BOOL .matched(INT n=0,
$Method BOOL .matched(INT n=0,
STRING element=0,
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 ``true`` if the element
indicated by the ``n``
and ``select`` parameters was matched, according to
the rules described above.
indicated by the ``n``
, ``element`` and ``select`` parameters was
matched, according to
the rules described above.
For example if ``n`` > 0, ``.matched(n)`` returns ``true`` if and only
if the ``n``-th element matched. The numbering corresponds to the
order of ``.add()`` invocations in ``vcl_init`` (starting from 1). The
``select`` parameter is ignored in this case.
If ``n`` <= 0, the set element is determined by the ``select`` enum.
In that case, ``.matched()`` returns ``true`` if and only if the
element indicated by the enum was matched by the previous successful
match operation. These distinctions are only relevant if the previous
operation was ``.hasprefix()``, and more than one string was matched
due to overlapping prefixes. ``.matched()`` returns ``true`` for all
values of ``select`` if the previous successful operation was
``.match()``. ``n`` defaults to 0, so the ``n`` parameter can be left
out if the use of ``select`` is intended.
If ``n`` <= 0 and ``select`` is ``UNIQUE`` or ``EXACT``, then
``.matched()`` returns ``true`` if the enum's criteria are met;
otherwise it returns ``false``, and does not fail. This can be used as
a safeguard for the methods described below, which invoke VCL failure
if either of these two enums are specified, but their criteria are not
met.
``select`` and ``element`` parameters are ignored in this case.
If ``n`` <= 0 and ``element`` is set, then ``.matched()`` returns
``true`` if and only if the string specified by ``element`` was
matched in the previous successful ``.match()`` or ``.hasprefix()``
call. If ``element`` is not in the set, then ``.matched()`` does not
invoke VCL failure (this is a deviation from the general rules for
``element``), but ``.matched()`` always returns ``false`` in that
case. Thus ``.matched()`` can always used with ``element`` to safely
check if a string was previously matched, regardless of whether the
string is in the set.
``n`` defaults to 0, so the ``n`` parameter can be left out if
``element`` is set.
If ``n`` <= 0 and ``element`` is unset, the set element is determined
by the ``select`` enum. In that case, ``.matched()`` returns ``true``
if and only if the element indicated by the enum was matched by the
previous successful match operation. These distinctions are only
relevant if the previous operation was ``.hasprefix()``, and more than
one string was matched due to overlapping prefixes. ``.matched()``
returns ``true`` for all values of ``select`` if the previous
successful operation was ``.match()``.
``n`` defaults to 0 and ``element`` is unset by default, so the ``n``
and ``element`` parameters can be left out if the use of ``select`` is
intended.
If ``n`` <= 0, ``element`` is unset, and ``select`` is ``UNIQUE`` or
``EXACT``, then ``.matched()`` returns ``true`` if the enum's criteria
are met; otherwise it returns ``false``, and does not fail. This can
be used as a safeguard for the methods described below, which invoke
VCL failure if either of these two enums are specified, but their
criteria are not met.
The other enum values (``FIRST``, ``LAST``, ``SHORTEST`` and
``LONGEST``) are included for consistency with the other methods, but
they don't make a relevant distinction. If the prior invocation of
``.match()`` or ``.hasprefix()`` was successful (returned ``true``),
then ``.matched()`` returns ``true`` for each of these, since there is
always an element that meets the criteria. If the prior invocation was
unsuccessful, ``.matched()`` always returns ``false`` for each of the
four enums.
always an element that meets the criteria.
``.matched()`` always returns ``false`` if the most recent
``.match()`` or ``.hasprefix()`` call returned ``false``.
``.matched()`` invokes VCL failure if:
* The
parameter is out of range -- greater than the number of elements
in the set.
* The
``n`` parameter is out of range -- greater than the number of
elements
in the set.
* There was no prior invocation of ``.match()`` or ``.hasprefix()`` in
the same task scope.
...
...
@@ -640,6 +654,12 @@ Example::
}
}
if (url_prefixes.hasprefix(bereq.url)) {
if (urls.matched(element="/foo/")) {
call do_if_foo_was_matched;
}
}
$Method INT .which(ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
...
...
@@ -943,10 +963,10 @@ failure is invoked. VCL failure has the same results as if
VCL failure is meant to "fail fast" on conditions that cannot be
correct, or when resource limitations such as workspace exhaustion
prevent further processing. Depending on your use case, you may be
able to use the VMOD's methods without
risk of failure. For example,
if it is known that none of the strings in a set have common prefixes,
then methods with ``select=UNIQUE`` can be used safely after calling
``.hasprefix()``.
able to use the VMOD's methods without
additional checking and with no
risk of failure. For example, if it is known that none of the strings
in a set have common prefixes, then methods with ``select=UNIQUE`` can
be used safely after calling
``.hasprefix()``.
If you need to check against possible failure conditions:
...
...
@@ -959,6 +979,12 @@ If you need to check against possible failure conditions:
ensure that VCL load fails if a set unintentionally has strings
with common prefixes.
* In most cases, a method invokes VCL failure if the value of the
``element`` parameter is not in the set. But ``element`` can be used
safely with any string in ``.matched()`` to check if a string
matched previously -- ``.matched()`` returns ``false`` if the
``element`` is not in the set.
See `LIMITATIONS`_ for considerations if you encounter conditions such
as workspace exhaustion.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment