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
4aaec2ff
Commit
4aaec2ff
authored
Feb 22, 2021
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add the .check_call() method.
parent
d6d30486
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
340 additions
and
41 deletions
+340
-41
README.rst
README.rst
+15
-0
associate.c
src/associate.c
+57
-29
match.c
src/match.c
+5
-5
subroutine.vtc
src/tests/subroutine.vtc
+249
-6
vmod_selector.h
src/vmod_selector.h
+8
-1
vmod_selector.vcc
src/vmod_selector.vcc
+6
-0
No files found.
README.rst
View file @
4aaec2ff
...
...
@@ -1072,6 +1072,21 @@ SUB xset.subroutine(INT n, STRING element, ENUM select)
XXX ...
.. _xset.check_call():
BOOL xset.check_call(INT n, STRING element, ENUM select)
--------------------------------------------------------
::
BOOL xset.check_call(
INT n=0,
STRING element=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST} select=UNIQUE
)
XXX ...
.. _selector.version():
STRING version()
...
...
src/associate.c
View file @
4aaec2ff
...
...
@@ -31,11 +31,11 @@
static
unsigned
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
)
const
char
*
const
restrict
method
,
int
fail
)
{
if
(
selects
==
VENUM
(
EXACT
))
{
if
(
match
->
exact
==
UINT_MAX
)
VFAIL
(
ctx
,
"%s.%s(select=EXACT): "
VFAIL
_OR_NOTICE
(
ctx
,
fail
,
"%s.%s(select=EXACT): "
"no element matched exactly"
,
obj
,
method
);
return
match
->
exact
;
}
...
...
@@ -45,8 +45,9 @@ select(VRT_CTX, const struct match_data * const restrict match,
switch
(
selects
[
0
])
{
case
'U'
:
assert
(
selects
==
VENUM
(
UNIQUE
));
VFAIL
(
ctx
,
"%s.%s(select=UNIQUE): %d elements were matched"
,
obj
,
method
,
match
->
n
);
VFAIL_OR_NOTICE
(
ctx
,
fail
,
"%s.%s(select=UNIQUE): %d elements were matched"
,
obj
,
method
,
match
->
n
);
return
(
UINT_MAX
);
case
'L'
:
if
(
selects
==
VENUM
(
LAST
))
...
...
@@ -81,7 +82,7 @@ vmod_set_which(VRT_CTX, struct vmod_selector_set *set, VCL_ENUM selects,
return
(
UINT_MAX
);
}
match
=
get_existing_match_data
(
ctx
,
set
,
"which"
);
match
=
get_existing_match_data
(
ctx
,
set
,
"which"
,
1
);
if
(
element
!=
NULL
)
{
CHECK_OBJ_NOTNULL
(
match
,
MATCH_DATA_MAGIC
);
assert
(
match
->
n
==
1
);
...
...
@@ -89,35 +90,38 @@ vmod_set_which(VRT_CTX, struct vmod_selector_set *set, VCL_ENUM selects,
}
if
(
match
==
NULL
||
match
->
n
==
0
)
return
(
0
);
return
(
select
(
ctx
,
match
,
set
->
vcl_name
,
selects
,
"which"
)
+
1
);
return
(
select
(
ctx
,
match
,
set
->
vcl_name
,
selects
,
"which"
,
1
)
+
1
);
}
static
unsigned
get_idx
(
VRT_CTX
,
VCL_INT
n
,
const
struct
vmod_selector_set
*
const
restrict
set
,
const
char
*
const
restrict
method
,
VCL_STRING
const
restrict
element
,
VCL_ENUM
const
restrict
selects
)
VCL_ENUM
const
restrict
selects
,
int
fail
)
{
struct
match_data
*
match
;
if
(
n
>
0
)
{
if
(
n
>
set
->
nmembers
)
{
VFAIL
(
ctx
,
"%s.%s(%ld): set has %d elements"
,
set
->
vcl_name
,
method
,
n
,
set
->
nmembers
);
VFAIL_OR_NOTICE
(
ctx
,
fail
,
"%s.%s(%ld): set has %d elements"
,
set
->
vcl_name
,
method
,
n
,
set
->
nmembers
);
return
(
UINT_MAX
);
}
return
(
n
-
1
);
}
if
(
element
!=
NULL
)
if
(
!
vmod_set_match
(
ctx
,
TRUST_ME
(
set
),
element
))
{
VFAIL
(
ctx
,
"%s.%s(element=
\"
%s
\"
): no such element"
,
set
->
vcl_name
,
method
,
element
);
VFAIL_OR_NOTICE
(
ctx
,
fail
,
"%s.%s(element=
\"
%s
\"
): no such element"
,
set
->
vcl_name
,
method
,
element
);
return
(
UINT_MAX
);
}
match
=
get_existing_match_data
(
ctx
,
set
,
method
);
match
=
get_existing_match_data
(
ctx
,
set
,
method
,
fail
);
if
(
match
==
NULL
||
match
->
n
==
0
)
return
(
UINT_MAX
);
return
(
select
(
ctx
,
match
,
set
->
vcl_name
,
selects
,
method
));
return
(
select
(
ctx
,
match
,
set
->
vcl_name
,
selects
,
method
,
fail
));
}
VCL_STRING
...
...
@@ -129,7 +133,7 @@ vmod_set_element(VRT_CTX, struct vmod_selector_set *set, VCL_INT n,
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"element"
,
NULL
,
selects
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"element"
,
NULL
,
selects
,
1
);
if
(
idx
==
UINT_MAX
)
return
(
NULL
);
return
(
set
->
members
[
idx
]);
...
...
@@ -139,11 +143,12 @@ static inline int
check_added
(
VRT_CTX
,
const
struct
vmod_selector_set
*
const
restrict
set
,
unsigned
idx
,
enum
bitmap_e
bitmap
,
const
char
*
const
restrict
method
,
const
char
*
const
restrict
type
)
const
char
*
const
restrict
type
,
int
fail
)
{
if
(
!
is_added
(
set
,
idx
,
bitmap
))
{
VFAIL
(
ctx
,
"%s.%s(): %s not added for element %u"
,
set
->
vcl_name
,
method
,
type
,
idx
+
1
);
VFAIL_OR_NOTICE
(
ctx
,
fail
,
"%s.%s(): %s not added for element %u"
,
set
->
vcl_name
,
method
,
type
,
idx
+
1
);
return
(
0
);
}
return
(
1
);
...
...
@@ -159,10 +164,10 @@ vmod_set_backend(VRT_CTX, struct vmod_selector_set *set, VCL_INT n,
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"backend"
,
element
,
selects
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"backend"
,
element
,
selects
,
1
);
if
(
idx
==
UINT_MAX
)
return
(
NULL
);
if
(
!
check_added
(
ctx
,
set
,
idx
,
BACKEND
,
"backend"
,
"backend"
))
if
(
!
check_added
(
ctx
,
set
,
idx
,
BACKEND
,
"backend"
,
"backend"
,
1
))
return
(
NULL
);
b
=
set
->
table
[
idx
]
->
backend
;
...
...
@@ -180,10 +185,10 @@ vmod_set_string(VRT_CTX, struct vmod_selector_set * set, VCL_INT n,
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"string"
,
element
,
selects
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"string"
,
element
,
selects
,
1
);
if
(
idx
==
UINT_MAX
)
return
(
NULL
);
if
(
!
check_added
(
ctx
,
set
,
idx
,
STRING
,
"string"
,
"string"
))
if
(
!
check_added
(
ctx
,
set
,
idx
,
STRING
,
"string"
,
"string"
,
1
))
return
(
NULL
);
s
=
set
->
table
[
idx
]
->
string
;
...
...
@@ -200,10 +205,10 @@ vmod_set_integer(VRT_CTX, struct vmod_selector_set * set, VCL_INT n,
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"integer"
,
element
,
selects
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"integer"
,
element
,
selects
,
1
);
if
(
idx
==
UINT_MAX
)
return
(
0
);
if
(
!
check_added
(
ctx
,
set
,
idx
,
INTEGER
,
"integer"
,
"integer"
))
if
(
!
check_added
(
ctx
,
set
,
idx
,
INTEGER
,
"integer"
,
"integer"
,
1
))
return
(
0
);
return
(
set
->
table
[
idx
]
->
integer
);
...
...
@@ -220,10 +225,10 @@ get_re(VRT_CTX, const struct vmod_selector_set * const restrict set,
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
idx
=
get_idx
(
ctx
,
n
,
set
,
method
,
element
,
selects
);
idx
=
get_idx
(
ctx
,
n
,
set
,
method
,
element
,
selects
,
1
);
if
(
idx
==
UINT_MAX
)
return
(
NULL
);
if
(
!
check_added
(
ctx
,
set
,
idx
,
REGEX
,
method
,
"regex"
))
if
(
!
check_added
(
ctx
,
set
,
idx
,
REGEX
,
method
,
"regex"
,
1
))
return
(
NULL
);
re
=
set
->
table
[
idx
]
->
re
;
...
...
@@ -265,10 +270,10 @@ vmod_set_bool(VRT_CTX, struct VPFX(selector_set) *set, VCL_INT n,
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"bool"
,
element
,
selects
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"bool"
,
element
,
selects
,
1
);
if
(
idx
==
UINT_MAX
)
return
(
0
);
if
(
!
check_added
(
ctx
,
set
,
idx
,
BOOLEAN
,
"bool"
,
"boolean"
))
if
(
!
check_added
(
ctx
,
set
,
idx
,
BOOLEAN
,
"bool"
,
"boolean"
,
1
))
return
(
0
);
return
(
set
->
table
[
idx
]
->
bool
);
...
...
@@ -283,11 +288,34 @@ vmod_set_subroutine(VRT_CTX, struct VPFX(selector_set) *set, VCL_INT n,
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"subroutine"
,
element
,
selects
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"subroutine"
,
element
,
selects
,
1
);
if
(
idx
==
UINT_MAX
)
return
(
NULL
);
if
(
!
check_added
(
ctx
,
set
,
idx
,
SUB
,
"subroutine"
,
"subroutine"
))
if
(
!
check_added
(
ctx
,
set
,
idx
,
SUB
,
"subroutine"
,
"subroutine"
,
1
))
return
(
NULL
);
return
(
set
->
table
[
idx
]
->
sub
);
}
VCL_BOOL
vmod_set_check_call
(
VRT_CTX
,
struct
VPFX
(
selector_set
)
*
set
,
VCL_INT
n
,
VCL_STRING
element
,
VCL_ENUM
selects
)
{
unsigned
idx
;
VCL_STRING
err
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
idx
=
get_idx
(
ctx
,
n
,
set
,
"check_call"
,
element
,
selects
,
0
);
if
(
idx
==
UINT_MAX
)
return
(
0
);
if
(
!
check_added
(
ctx
,
set
,
idx
,
SUB
,
"check_call"
,
"subroutine"
,
0
))
return
(
0
);
if
((
err
=
VRT_check_call
(
ctx
,
set
->
table
[
idx
]
->
sub
))
!=
NULL
)
{
VNOTICE
(
ctx
,
"%s"
,
err
);
return
(
0
);
}
return
(
1
);
}
src/match.c
View file @
4aaec2ff
...
...
@@ -183,7 +183,7 @@ vmod_set_hasprefix(VRT_CTX, struct vmod_selector_set *set, VCL_STRING subject)
struct
match_data
*
get_existing_match_data
(
VRT_CTX
,
const
struct
vmod_selector_set
*
const
restrict
set
,
const
char
*
const
restrict
method
)
const
char
*
const
restrict
method
,
int
fail
)
{
struct
vmod_priv
*
task
;
struct
match_data
*
match
;
...
...
@@ -191,8 +191,8 @@ get_existing_match_data(VRT_CTX,
task
=
VRT_priv_task
(
ctx
,
set
);
AN
(
task
);
if
(
task
->
priv
==
NULL
)
{
VFAIL
(
ctx
,
"%s.%s() called without prior match"
,
set
->
vcl_name
,
method
);
VFAIL
_OR_NOTICE
(
ctx
,
fail
,
"%s.%s() called without prior match"
,
set
->
vcl_name
,
method
);
return
(
NULL
);
}
WS_Assert_Allocated
(
ctx
->
ws
,
task
->
priv
,
sizeof
(
*
match
));
...
...
@@ -208,7 +208,7 @@ vmod_set_nmatches(VRT_CTX, struct vmod_selector_set *set)
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
match
=
get_existing_match_data
(
ctx
,
set
,
"nmatches"
);
match
=
get_existing_match_data
(
ctx
,
set
,
"nmatches"
,
1
);
if
(
match
==
NULL
)
return
(
0
);
return
(
match
->
n
);
...
...
@@ -229,7 +229,7 @@ vmod_set_matched(VRT_CTX, struct VPFX(selector_set) *set, VCL_INT idx,
return
(
0
);
}
match
=
get_existing_match_data
(
ctx
,
set
,
"matched"
);
match
=
get_existing_match_data
(
ctx
,
set
,
"matched"
,
1
);
if
(
match
==
NULL
||
match
->
n
==
0
)
return
(
0
);
...
...
src/tests/subroutine.vtc
View file @
4aaec2ff
This diff is collapsed.
Click to expand it.
src/vmod_selector.h
View file @
4aaec2ff
...
...
@@ -45,6 +45,13 @@
#define VNOTICE(ctx, fmt, ...) \
VSLb((ctx)->vsl, SLT_Notice, "vmod_selector: " fmt, __VA_ARGS__)
#define VFAIL_OR_NOTICE(ctx, fail, fmt, ...) do { \
if (fail) \
VFAIL((ctx), fmt, __VA_ARGS__); \
else \
VNOTICE((ctx), fmt, __VA_ARGS__); \
} while(0)
struct
entry
{
unsigned
magic
;
#define VMOD_SELECTOR_ENTRY_MAGIC 0x733dbe63
...
...
@@ -101,4 +108,4 @@ is_added(const struct vmod_selector_set *set, unsigned idx,
struct
match_data
*
get_existing_match_data
(
const
struct
vrt_ctx
*
ctx
,
const
struct
vmod_selector_set
*
const
restrict
set
,
const
char
*
const
restrict
method
);
const
char
*
const
restrict
method
,
int
fail
);
src/vmod_selector.vcc
View file @
4aaec2ff
...
...
@@ -937,6 +937,12 @@ $Method SUB .subroutine(INT n=0, STRING element=0,
XXX ...
$Method BOOL .check_call(INT n=0, STRING element=0,
ENUM {UNIQUE, EXACT, FIRST, LAST, SHORTEST, LONGEST}
select=UNIQUE)
XXX ...
$Function STRING version()
Return the version string for this VMOD.
...
...
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