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
...
@@ -38,7 +38,7 @@ SYNOPSIS
# Match properties
# Match properties
INT <obj>.nmatches()
INT <obj>.nmatches()
BOOL <obj>.matched([INT n] [, ENUM select])
BOOL <obj>.matched([INT n] [,
STRING element] [,
ENUM select])
INT <obj>.which([ENUM select])
INT <obj>.which([ENUM select])
# Retrieving objects after match
# Retrieving objects after match
...
@@ -618,59 +618,74 @@ Example::
...
@@ -618,59 +618,74 @@ Example::
.. _xset.matched():
.. _xset.matched():
BOOL xset.matched(INT n, ENUM select)
BOOL xset.matched(INT n,
STRING element,
ENUM select)
-------------------------------------
-------------------------------------
----------------
::
::
BOOL xset.matched(
BOOL xset.matched(
INT n=0,
INT n=0,
STRING element=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
)
After a successful ``.match()`` or ``.hasprefix()`` call for the same
After a successful ``.match()`` or ``.hasprefix()`` call for the same
set object in the same task scope, return ``true`` if the element
set object in the same task scope, return ``true`` if the element
indicated by the ``n``
and ``select`` parameters was matched, according to
indicated by the ``n``
, ``element`` and ``select`` parameters was
the rules described above.
matched, according to
the rules described above.
For example if ``n`` > 0, ``.matched(n)`` returns ``true`` if and only
For example if ``n`` > 0, ``.matched(n)`` returns ``true`` if and only
if the ``n``-th element matched. The numbering corresponds to the
if the ``n``-th element matched. The numbering corresponds to the
order of ``.add()`` invocations in ``vcl_init`` (starting from 1). The
order of ``.add()`` invocations in ``vcl_init`` (starting from 1). The
``select`` parameter is ignored in this case.
``select`` and ``element`` parameters are ignored in this case.
If ``n`` <= 0, the set element is determined by the ``select`` enum.
If ``n`` <= 0 and ``element`` is set, then ``.matched()`` returns
In that case, ``.matched()`` returns ``true`` if and only if the
``true`` if and only if the string specified by ``element`` was
element indicated by the enum was matched by the previous successful
matched in the previous successful ``.match()`` or ``.hasprefix()``
match operation. These distinctions are only relevant if the previous
call. If ``element`` is not in the set, then ``.matched()`` does not
operation was ``.hasprefix()``, and more than one string was matched
invoke VCL failure (this is a deviation from the general rules for
due to overlapping prefixes. ``.matched()`` returns ``true`` for all
``element``), but ``.matched()`` always returns ``false`` in that
values of ``select`` if the previous successful operation was
case. Thus ``.matched()`` can always used with ``element`` to safely
``.match()``. ``n`` defaults to 0, so the ``n`` parameter can be left
check if a string was previously matched, regardless of whether the
out if the use of ``select`` is intended.
string is in the set.
If ``n`` <= 0 and ``select`` is ``UNIQUE`` or ``EXACT``, then
``n`` defaults to 0, so the ``n`` parameter can be left out if
``.matched()`` returns ``true`` if the enum's criteria are met;
``element`` is set.
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 ``n`` <= 0 and ``element`` is unset, the set element is determined
if either of these two enums are specified, but their criteria are not
by the ``select`` enum. In that case, ``.matched()`` returns ``true``
met.
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
The other enum values (``FIRST``, ``LAST``, ``SHORTEST`` and
``LONGEST``) are included for consistency with the other methods, but
``LONGEST``) are included for consistency with the other methods, but
they don't make a relevant distinction. If the prior invocation of
they don't make a relevant distinction. If the prior invocation of
``.match()`` or ``.hasprefix()`` was successful (returned ``true``),
``.match()`` or ``.hasprefix()`` was successful (returned ``true``),
then ``.matched()`` returns ``true`` for each of these, since there is
then ``.matched()`` returns ``true`` for each of these, since there is
always an element that meets the criteria. If the prior invocation was
always an element that meets the criteria.
unsuccessful, ``.matched()`` always returns ``false`` for each of the
four enums.
``.matched()`` always returns ``false`` if the most recent
``.matched()`` always returns ``false`` if the most recent
``.match()`` or ``.hasprefix()`` call returned ``false``.
``.match()`` or ``.hasprefix()`` call returned ``false``.
``.matched()`` invokes VCL failure if:
``.matched()`` invokes VCL failure if:
* The
parameter is out of range -- greater than the number of elements
* The
``n`` parameter is out of range -- greater than the number of
in the set.
elements
in the set.
* There was no prior invocation of ``.match()`` or ``.hasprefix()`` in
* There was no prior invocation of ``.match()`` or ``.hasprefix()`` in
the same task scope.
the same task scope.
...
@@ -689,6 +704,12 @@ Example::
...
@@ -689,6 +704,12 @@ Example::
}
}
}
}
if (url_prefixes.hasprefix(bereq.url)) {
if (urls.matched(element="/foo/")) {
call do_if_foo_was_matched;
}
}
.. _xset.which():
.. _xset.which():
INT xset.which(ENUM select)
INT xset.which(ENUM select)
...
@@ -1059,10 +1080,10 @@ failure is invoked. VCL failure has the same results as if
...
@@ -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
VCL failure is meant to "fail fast" on conditions that cannot be
correct, or when resource limitations such as workspace exhaustion
correct, or when resource limitations such as workspace exhaustion
prevent further processing. Depending on your use case, you may be
prevent further processing. Depending on your use case, you may be
able to use the VMOD's methods without
risk of failure. For example,
able to use the VMOD's methods without
additional checking and with no
if it is known that none of the strings in a set have common prefixes,
risk of failure. For example, if it is known that none of the strings
then methods with ``select=UNIQUE`` can be used safely after calling
in a set have common prefixes, then methods with ``select=UNIQUE`` can
``.hasprefix()``.
be used safely after calling
``.hasprefix()``.
If you need to check against possible failure conditions:
If you need to check against possible failure conditions:
...
@@ -1075,6 +1096,12 @@ 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
ensure that VCL load fails if a set unintentionally has strings
with common prefixes.
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
See `LIMITATIONS`_ for considerations if you encounter conditions such
as workspace exhaustion.
as workspace exhaustion.
...
...
src/tests/match.vtc
View file @
61dfec02
...
@@ -837,12 +837,16 @@ varnish v1 -vcl {
...
@@ -837,12 +837,16 @@ varnish v1 -vcl {
set resp.http.Matched-Last = s.matched(select=LAST);
set resp.http.Matched-Last = s.matched(select=LAST);
set resp.http.Matched-Shortest = s.matched(select=SHORTEST);
set resp.http.Matched-Shortest = s.matched(select=SHORTEST);
set resp.http.Matched-Longest = s.matched(select=LONGEST);
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-Match = s.hasprefix("baz");
set resp.http.Non-Matched-First = s.matched(select=FIRST);
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-Last = s.matched(select=LAST);
set resp.http.Non-Matched-Shortest = s.matched(select=SHORTEST);
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-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);
return (deliver);
}
}
...
@@ -857,11 +861,15 @@ client c1 {
...
@@ -857,11 +861,15 @@ client c1 {
expect resp.http.Matched-Last == "true"
expect resp.http.Matched-Last == "true"
expect resp.http.Matched-Shortest == "true"
expect resp.http.Matched-Shortest == "true"
expect resp.http.Matched-Longest == "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-Match == "false"
expect resp.http.Non-Matched-First == "false"
expect resp.http.Non-Matched-First == "false"
expect resp.http.Non-Matched-Last == "false"
expect resp.http.Non-Matched-Last == "false"
expect resp.http.Non-Matched-Shortest == "false"
expect resp.http.Non-Matched-Shortest == "false"
expect resp.http.Non-Matched-Longest == "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"
txreq -hdr "Range-Error: oops"
rxresp
rxresp
...
...
src/vmod_selector.c
View file @
61dfec02
...
@@ -606,7 +606,7 @@ vmod_set_nmatches(VRT_CTX, struct vmod_selector_set *set)
...
@@ -606,7 +606,7 @@ vmod_set_nmatches(VRT_CTX, struct vmod_selector_set *set)
VCL_BOOL
VCL_BOOL
vmod_set_matched
(
VRT_CTX
,
struct
VPFX
(
selector_set
)
*
set
,
VCL_INT
idx
,
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
;
struct
match_data
*
match
;
...
@@ -636,6 +636,14 @@ vmod_set_matched(VRT_CTX, struct VPFX(selector_set) *set, VCL_INT idx,
...
@@ -636,6 +636,14 @@ vmod_set_matched(VRT_CTX, struct VPFX(selector_set) *set, VCL_INT idx,
return
(
0
);
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
))
if
(
selects
==
VENUM
(
UNIQUE
))
return
(
match
->
n
==
1
);
return
(
match
->
n
==
1
);
if
(
selects
==
VENUM
(
EXACT
))
if
(
selects
==
VENUM
(
EXACT
))
...
...
src/vmod_selector.vcc
View file @
61dfec02
...
@@ -34,7 +34,7 @@ SYNOPSIS
...
@@ -34,7 +34,7 @@ SYNOPSIS
# Match properties
# Match properties
INT <obj>.nmatches()
INT <obj>.nmatches()
BOOL <obj>.matched([INT n] [, ENUM select])
BOOL <obj>.matched([INT n] [,
STRING element] [,
ENUM select])
INT <obj>.which([ENUM select])
INT <obj>.which([ENUM select])
# Retrieving objects after match
# Retrieving objects after match
...
@@ -575,53 +575,67 @@ Example::
...
@@ -575,53 +575,67 @@ Example::
set bereq.backend = myset.backend(select=UNIQUE);
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}
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
select=UNIQUE)
After a successful ``.match()`` or ``.hasprefix()`` call for the same
After a successful ``.match()`` or ``.hasprefix()`` call for the same
set object in the same task scope, return ``true`` if the element
set object in the same task scope, return ``true`` if the element
indicated by the ``n``
and ``select`` parameters was matched, according to
indicated by the ``n``
, ``element`` and ``select`` parameters was
the rules described above.
matched, according to
the rules described above.
For example if ``n`` > 0, ``.matched(n)`` returns ``true`` if and only
For example if ``n`` > 0, ``.matched(n)`` returns ``true`` if and only
if the ``n``-th element matched. The numbering corresponds to the
if the ``n``-th element matched. The numbering corresponds to the
order of ``.add()`` invocations in ``vcl_init`` (starting from 1). The
order of ``.add()`` invocations in ``vcl_init`` (starting from 1). The
``select`` parameter is ignored in this case.
``select`` and ``element`` parameters are ignored in this case.
If ``n`` <= 0, the set element is determined by the ``select`` enum.
If ``n`` <= 0 and ``element`` is set, then ``.matched()`` returns
In that case, ``.matched()`` returns ``true`` if and only if the
``true`` if and only if the string specified by ``element`` was
element indicated by the enum was matched by the previous successful
matched in the previous successful ``.match()`` or ``.hasprefix()``
match operation. These distinctions are only relevant if the previous
call. If ``element`` is not in the set, then ``.matched()`` does not
operation was ``.hasprefix()``, and more than one string was matched
invoke VCL failure (this is a deviation from the general rules for
due to overlapping prefixes. ``.matched()`` returns ``true`` for all
``element``), but ``.matched()`` always returns ``false`` in that
values of ``select`` if the previous successful operation was
case. Thus ``.matched()`` can always used with ``element`` to safely
``.match()``. ``n`` defaults to 0, so the ``n`` parameter can be left
check if a string was previously matched, regardless of whether the
out if the use of ``select`` is intended.
string is in the set.
If ``n`` <= 0 and ``select`` is ``UNIQUE`` or ``EXACT``, then
``n`` defaults to 0, so the ``n`` parameter can be left out if
``.matched()`` returns ``true`` if the enum's criteria are met;
``element`` is set.
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 ``n`` <= 0 and ``element`` is unset, the set element is determined
if either of these two enums are specified, but their criteria are not
by the ``select`` enum. In that case, ``.matched()`` returns ``true``
met.
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
The other enum values (``FIRST``, ``LAST``, ``SHORTEST`` and
``LONGEST``) are included for consistency with the other methods, but
``LONGEST``) are included for consistency with the other methods, but
they don't make a relevant distinction. If the prior invocation of
they don't make a relevant distinction. If the prior invocation of
``.match()`` or ``.hasprefix()`` was successful (returned ``true``),
``.match()`` or ``.hasprefix()`` was successful (returned ``true``),
then ``.matched()`` returns ``true`` for each of these, since there is
then ``.matched()`` returns ``true`` for each of these, since there is
always an element that meets the criteria. If the prior invocation was
always an element that meets the criteria.
unsuccessful, ``.matched()`` always returns ``false`` for each of the
four enums.
``.matched()`` always returns ``false`` if the most recent
``.matched()`` always returns ``false`` if the most recent
``.match()`` or ``.hasprefix()`` call returned ``false``.
``.match()`` or ``.hasprefix()`` call returned ``false``.
``.matched()`` invokes VCL failure if:
``.matched()`` invokes VCL failure if:
* The
parameter is out of range -- greater than the number of elements
* The
``n`` parameter is out of range -- greater than the number of
in the set.
elements
in the set.
* There was no prior invocation of ``.match()`` or ``.hasprefix()`` in
* There was no prior invocation of ``.match()`` or ``.hasprefix()`` in
the same task scope.
the same task scope.
...
@@ -640,6 +654,12 @@ Example::
...
@@ -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}
$Method INT .which(ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
select=UNIQUE)
...
@@ -943,10 +963,10 @@ failure is invoked. VCL failure has the same results as if
...
@@ -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
VCL failure is meant to "fail fast" on conditions that cannot be
correct, or when resource limitations such as workspace exhaustion
correct, or when resource limitations such as workspace exhaustion
prevent further processing. Depending on your use case, you may be
prevent further processing. Depending on your use case, you may be
able to use the VMOD's methods without
risk of failure. For example,
able to use the VMOD's methods without
additional checking and with no
if it is known that none of the strings in a set have common prefixes,
risk of failure. For example, if it is known that none of the strings
then methods with ``select=UNIQUE`` can be used safely after calling
in a set have common prefixes, then methods with ``select=UNIQUE`` can
``.hasprefix()``.
be used safely after calling
``.hasprefix()``.
If you need to check against possible failure conditions:
If you need to check against possible failure conditions:
...
@@ -959,6 +979,12 @@ 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
ensure that VCL load fails if a set unintentionally has strings
with common prefixes.
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
See `LIMITATIONS`_ for considerations if you encounter conditions such
as workspace exhaustion.
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