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
43541478
Commit
43541478
authored
Feb 02, 2021
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move the functions for matching into a separate source.
parent
30885ed8
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
270 additions
and
236 deletions
+270
-236
Makefile.am
src/Makefile.am
+2
-1
match.c
src/match.c
+262
-0
vmod_selector.c
src/vmod_selector.c
+0
-235
vmod_selector.h
src/vmod_selector.h
+6
-0
No files found.
src/Makefile.am
View file @
43541478
...
...
@@ -8,6 +8,7 @@ vmod_LTLIBRARIES = libvmod_selector.la
libvmod_selector_la_SOURCES
=
\
vmod_selector.c
\
vmod_selector.h
\
match.c
\
associate.c
\
qp.h
\
qp.c
\
...
...
@@ -28,7 +29,7 @@ dist_man_MANS = vmod_selector.3
vmod_selector.h
:
qp.h
vmod_selector.c associate.c
:
vmod_selector.h
vmod_selector.c
match.c
associate.c
:
vmod_selector.h
vmod_selector.c qp.c
:
qp.h popcnt_compat.h
...
...
src/match.c
0 → 100644
View file @
43541478
/*-
* Copyright (c) 2021 UPLEX Nils Goroll Systemoptimierung
* All rights reserved
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "vmod_selector.h"
#include <ctype.h>
#include "ph.h"
static
struct
match_data
*
get_match_data
(
VRT_CTX
,
struct
vmod_selector_set
*
set
,
const
char
*
method
)
{
struct
vmod_priv
*
task
;
struct
match_data
*
match
;
task
=
VRT_priv_task
(
ctx
,
set
);
AN
(
task
);
if
(
task
->
priv
==
NULL
)
{
if
((
task
->
priv
=
WS_Alloc
(
ctx
->
ws
,
sizeof
(
*
match
)))
==
NULL
)
{
VERRNOMEM
(
ctx
,
"Allocating match data in %s.%s()"
,
set
->
vcl_name
,
method
);
return
(
NULL
);
}
task
->
len
=
sizeof
(
*
match
);
AZ
(
task
->
methods
);
match
=
(
struct
match_data
*
)
task
->
priv
;
match
->
magic
=
MATCH_DATA_MAGIC
;
}
else
{
WS_Assert_Allocated
(
ctx
->
ws
,
task
->
priv
,
sizeof
(
*
match
));
CAST_OBJ
(
match
,
task
->
priv
,
MATCH_DATA_MAGIC
);
}
return
match
;
}
VCL_BOOL
vmod_set_match
(
VRT_CTX
,
struct
vmod_selector_set
*
set
,
VCL_STRING
subject
)
{
unsigned
idx
;
struct
match_data
*
match
;
char
**
members
;
const
char
*
subj
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
if
(
set
->
nmembers
==
0
)
{
VFAIL
(
ctx
,
"%s.match(): no entries were added"
,
set
->
vcl_name
);
return
(
0
);
}
if
(
set
->
hash
==
NULL
)
{
VFAIL
(
ctx
,
"%s.match(): set was not compiled"
,
set
->
vcl_name
);
return
(
0
);
}
if
(
subject
==
NULL
)
{
VNOTICE
(
ctx
,
"%s.match(): subject string is NULL"
,
set
->
vcl_name
);
return
(
0
);
}
members
=
set
->
members
;
subj
=
subject
;
if
(
!
set
->
case_sensitive
)
{
char
*
copy
;
if
((
copy
=
WS_Copy
(
ctx
->
ws
,
subject
,
-
1
))
==
NULL
)
{
VERRNOMEM
(
ctx
,
"%s.match(): copying subject for "
"case-insensitive match"
,
set
->
vcl_name
);
return
(
0
);
}
for
(
char
*
c
=
copy
;
*
c
;
c
++
)
*
c
=
tolower
(
*
c
);
subj
=
copy
;
members
=
set
->
lomembers
;
}
AN
(
members
);
match
=
get_match_data
(
ctx
,
set
,
"match"
);
if
((
idx
=
PH_Lookup
(
set
->
hash
,
members
,
subj
))
==
UINT_MAX
)
{
match
->
n
=
0
;
return
(
0
);
}
if
((
match
->
indices
=
WS_Alloc
(
ctx
->
ws
,
sizeof
(
unsigned
)))
==
NULL
)
{
VERRNOMEM
(
ctx
,
"Reserving space for index in "
"%s.match(
\"
%.40s
\"
)"
,
set
->
vcl_name
,
subject
);
return
(
0
);
}
*
match
->
indices
=
idx
;
match
->
n
=
1
;
match
->
exact
=
idx
;
return
(
1
);
}
VCL_BOOL
vmod_set_hasprefix
(
VRT_CTX
,
struct
vmod_selector_set
*
set
,
VCL_STRING
subject
)
{
struct
match_data
*
match
;
char
**
members
;
const
char
*
subj
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
if
(
set
->
nmembers
==
0
)
{
VFAIL
(
ctx
,
"%s.hasprefix(): no entries were added"
,
set
->
vcl_name
);
return
(
0
);
}
if
(
set
->
origo
==
NULL
)
{
VFAIL
(
ctx
,
"%s.hasprefix(): set was not compiled"
,
set
->
vcl_name
);
return
(
0
);
}
if
(
subject
==
NULL
)
{
VNOTICE
(
ctx
,
"%s.hasprefix(): subject string is NULL"
,
set
->
vcl_name
);
return
(
0
);
}
members
=
set
->
members
;
subj
=
subject
;
if
(
!
set
->
case_sensitive
)
{
char
*
copy
;
if
((
copy
=
WS_Copy
(
ctx
->
ws
,
subject
,
-
1
))
==
NULL
)
{
VERRNOMEM
(
ctx
,
"%s.hasprefix(): copying subject for "
"case-insensitive match"
,
set
->
vcl_name
);
return
(
0
);
}
for
(
char
*
c
=
copy
;
*
c
;
c
++
)
*
c
=
tolower
(
*
c
);
subj
=
copy
;
members
=
set
->
lomembers
;
}
AN
(
members
);
match
=
get_match_data
(
ctx
,
set
,
"hasprefix"
);
if
((
match
->
limit
=
WS_ReserveLumps
(
ctx
->
ws
,
sizeof
(
unsigned
)))
==
0
)
{
VERRNOMEM
(
ctx
,
"Reserving index array in "
"%s.hasprefix(
\"
%.40s
\"
)"
,
set
->
vcl_name
,
subject
);
WS_Release
(
ctx
->
ws
,
0
);
return
(
0
);
}
match
->
indices
=
(
unsigned
*
)
WS_Reservation
(
ctx
->
ws
);
if
(
QP_Prefixes
(
set
->
origo
,
members
,
subj
,
match
)
!=
0
)
{
VERRNOMEM
(
ctx
,
"Adding indices in %s.hasprefix(
\"
%.40s
\"
)"
,
set
->
vcl_name
,
subject
);
WS_Release
(
ctx
->
ws
,
0
);
return
(
0
);
}
WS_Release
(
ctx
->
ws
,
match
->
n
*
sizeof
(
unsigned
));
return
(
match
->
n
>
0
);
}
struct
match_data
*
get_existing_match_data
(
VRT_CTX
,
const
struct
vmod_selector_set
*
const
restrict
set
,
const
char
*
const
restrict
method
)
{
struct
vmod_priv
*
task
;
struct
match_data
*
match
;
task
=
VRT_priv_task
(
ctx
,
set
);
AN
(
task
);
if
(
task
->
priv
==
NULL
)
{
VFAIL
(
ctx
,
"%s.%s() called without prior match"
,
set
->
vcl_name
,
method
);
return
(
NULL
);
}
WS_Assert_Allocated
(
ctx
->
ws
,
task
->
priv
,
sizeof
(
*
match
));
CAST_OBJ
(
match
,
task
->
priv
,
MATCH_DATA_MAGIC
);
return
match
;
}
VCL_INT
vmod_set_nmatches
(
VRT_CTX
,
struct
vmod_selector_set
*
set
)
{
struct
match_data
*
match
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
match
=
get_existing_match_data
(
ctx
,
set
,
"nmatches"
);
if
(
match
==
NULL
)
return
(
0
);
return
(
match
->
n
);
}
VCL_BOOL
vmod_set_matched
(
VRT_CTX
,
struct
VPFX
(
selector_set
)
*
set
,
VCL_INT
idx
,
VCL_STRING
element
,
VCL_ENUM
selects
)
{
struct
match_data
*
match
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
if
(
idx
>
set
->
nmembers
)
{
VFAIL
(
ctx
,
"%s.matched(%ld) out of range (%d members)"
,
set
->
vcl_name
,
idx
,
set
->
nmembers
);
return
(
0
);
}
match
=
get_existing_match_data
(
ctx
,
set
,
"matched"
);
if
(
match
==
NULL
||
match
->
n
==
0
)
return
(
0
);
AN
(
match
->
indices
);
WS_Assert_Allocated
(
ctx
->
ws
,
match
->
indices
,
match
->
n
*
sizeof
(
unsigned
));
if
(
idx
>
0
)
{
/* XXX search algorithm? */
idx
--
;
for
(
unsigned
i
=
0
;
i
<
match
->
n
;
i
++
)
if
(
match
->
indices
[
i
]
==
idx
)
return
(
1
);
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
))
return
(
match
->
exact
!=
UINT_MAX
);
return
(
1
);
}
src/vmod_selector.c
View file @
43541478
...
...
@@ -41,12 +41,6 @@
#include "ph.h"
#include "VSC_selector.h"
#define VERRNOMEM(ctx, fmt, ...) \
VFAIL((ctx), "out of space: " fmt, __VA_ARGS__)
#define VNOTICE(ctx, fmt, ...) \
VSLb((ctx)->vsl, SLT_Notice, "vmod_selector: " fmt, __VA_ARGS__)
struct
vsc_entry
{
unsigned
magic
;
#define VMOD_SELECTOR_VSC_MAGIC 0x4b99b64a
...
...
@@ -558,235 +552,6 @@ vmod_set_compile(VRT_CTX, struct VPFX(selector_set) *set)
compile
(
ctx
,
set
,
".compile()"
);
}
static
struct
match_data
*
get_match_data
(
VRT_CTX
,
struct
vmod_selector_set
*
set
,
const
char
*
method
)
{
struct
vmod_priv
*
task
;
struct
match_data
*
match
;
task
=
VRT_priv_task
(
ctx
,
set
);
AN
(
task
);
if
(
task
->
priv
==
NULL
)
{
if
((
task
->
priv
=
WS_Alloc
(
ctx
->
ws
,
sizeof
(
*
match
)))
==
NULL
)
{
VERRNOMEM
(
ctx
,
"Allocating match data in %s.%s()"
,
set
->
vcl_name
,
method
);
return
(
NULL
);
}
task
->
len
=
sizeof
(
*
match
);
AZ
(
task
->
methods
);
match
=
(
struct
match_data
*
)
task
->
priv
;
match
->
magic
=
MATCH_DATA_MAGIC
;
}
else
{
WS_Assert_Allocated
(
ctx
->
ws
,
task
->
priv
,
sizeof
(
*
match
));
CAST_OBJ
(
match
,
task
->
priv
,
MATCH_DATA_MAGIC
);
}
return
match
;
}
VCL_BOOL
vmod_set_match
(
VRT_CTX
,
struct
vmod_selector_set
*
set
,
VCL_STRING
subject
)
{
unsigned
idx
;
struct
match_data
*
match
;
char
**
members
;
const
char
*
subj
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
if
(
set
->
nmembers
==
0
)
{
VFAIL
(
ctx
,
"%s.match(): no entries were added"
,
set
->
vcl_name
);
return
(
0
);
}
if
(
set
->
hash
==
NULL
)
{
VFAIL
(
ctx
,
"%s.match(): set was not compiled"
,
set
->
vcl_name
);
return
(
0
);
}
if
(
subject
==
NULL
)
{
VNOTICE
(
ctx
,
"%s.match(): subject string is NULL"
,
set
->
vcl_name
);
return
(
0
);
}
members
=
set
->
members
;
subj
=
subject
;
if
(
!
set
->
case_sensitive
)
{
char
*
copy
;
if
((
copy
=
WS_Copy
(
ctx
->
ws
,
subject
,
-
1
))
==
NULL
)
{
VERRNOMEM
(
ctx
,
"%s.match(): copying subject for "
"case-insensitive match"
,
set
->
vcl_name
);
return
(
0
);
}
for
(
char
*
c
=
copy
;
*
c
;
c
++
)
*
c
=
tolower
(
*
c
);
subj
=
copy
;
members
=
set
->
lomembers
;
}
AN
(
members
);
match
=
get_match_data
(
ctx
,
set
,
"match"
);
if
((
idx
=
PH_Lookup
(
set
->
hash
,
members
,
subj
))
==
UINT_MAX
)
{
match
->
n
=
0
;
return
(
0
);
}
if
((
match
->
indices
=
WS_Alloc
(
ctx
->
ws
,
sizeof
(
unsigned
)))
==
NULL
)
{
VERRNOMEM
(
ctx
,
"Reserving space for index in "
"%s.match(
\"
%.40s
\"
)"
,
set
->
vcl_name
,
subject
);
return
(
0
);
}
*
match
->
indices
=
idx
;
match
->
n
=
1
;
match
->
exact
=
idx
;
return
(
1
);
}
VCL_BOOL
vmod_set_hasprefix
(
VRT_CTX
,
struct
vmod_selector_set
*
set
,
VCL_STRING
subject
)
{
struct
match_data
*
match
;
char
**
members
;
const
char
*
subj
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
if
(
set
->
nmembers
==
0
)
{
VFAIL
(
ctx
,
"%s.hasprefix(): no entries were added"
,
set
->
vcl_name
);
return
(
0
);
}
if
(
set
->
origo
==
NULL
)
{
VFAIL
(
ctx
,
"%s.hasprefix(): set was not compiled"
,
set
->
vcl_name
);
return
(
0
);
}
if
(
subject
==
NULL
)
{
VNOTICE
(
ctx
,
"%s.hasprefix(): subject string is NULL"
,
set
->
vcl_name
);
return
(
0
);
}
members
=
set
->
members
;
subj
=
subject
;
if
(
!
set
->
case_sensitive
)
{
char
*
copy
;
if
((
copy
=
WS_Copy
(
ctx
->
ws
,
subject
,
-
1
))
==
NULL
)
{
VERRNOMEM
(
ctx
,
"%s.hasprefix(): copying subject for "
"case-insensitive match"
,
set
->
vcl_name
);
return
(
0
);
}
for
(
char
*
c
=
copy
;
*
c
;
c
++
)
*
c
=
tolower
(
*
c
);
subj
=
copy
;
members
=
set
->
lomembers
;
}
AN
(
members
);
match
=
get_match_data
(
ctx
,
set
,
"hasprefix"
);
if
((
match
->
limit
=
WS_ReserveLumps
(
ctx
->
ws
,
sizeof
(
unsigned
)))
==
0
)
{
VERRNOMEM
(
ctx
,
"Reserving index array in "
"%s.hasprefix(
\"
%.40s
\"
)"
,
set
->
vcl_name
,
subject
);
WS_Release
(
ctx
->
ws
,
0
);
return
(
0
);
}
match
->
indices
=
(
unsigned
*
)
WS_Reservation
(
ctx
->
ws
);
if
(
QP_Prefixes
(
set
->
origo
,
members
,
subj
,
match
)
!=
0
)
{
VERRNOMEM
(
ctx
,
"Adding indices in %s.hasprefix(
\"
%.40s
\"
)"
,
set
->
vcl_name
,
subject
);
WS_Release
(
ctx
->
ws
,
0
);
return
(
0
);
}
WS_Release
(
ctx
->
ws
,
match
->
n
*
sizeof
(
unsigned
));
return
(
match
->
n
>
0
);
}
struct
match_data
*
get_existing_match_data
(
VRT_CTX
,
const
struct
vmod_selector_set
*
const
restrict
set
,
const
char
*
const
restrict
method
)
{
struct
vmod_priv
*
task
;
struct
match_data
*
match
;
task
=
VRT_priv_task
(
ctx
,
set
);
AN
(
task
);
if
(
task
->
priv
==
NULL
)
{
VFAIL
(
ctx
,
"%s.%s() called without prior match"
,
set
->
vcl_name
,
method
);
return
(
NULL
);
}
WS_Assert_Allocated
(
ctx
->
ws
,
task
->
priv
,
sizeof
(
*
match
));
CAST_OBJ
(
match
,
task
->
priv
,
MATCH_DATA_MAGIC
);
return
match
;
}
VCL_INT
vmod_set_nmatches
(
VRT_CTX
,
struct
vmod_selector_set
*
set
)
{
struct
match_data
*
match
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
match
=
get_existing_match_data
(
ctx
,
set
,
"nmatches"
);
if
(
match
==
NULL
)
return
(
0
);
return
(
match
->
n
);
}
VCL_BOOL
vmod_set_matched
(
VRT_CTX
,
struct
VPFX
(
selector_set
)
*
set
,
VCL_INT
idx
,
VCL_STRING
element
,
VCL_ENUM
selects
)
{
struct
match_data
*
match
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_SELECTOR_SET_MAGIC
);
if
(
idx
>
set
->
nmembers
)
{
VFAIL
(
ctx
,
"%s.matched(%ld) out of range (%d members)"
,
set
->
vcl_name
,
idx
,
set
->
nmembers
);
return
(
0
);
}
match
=
get_existing_match_data
(
ctx
,
set
,
"matched"
);
if
(
match
==
NULL
||
match
->
n
==
0
)
return
(
0
);
AN
(
match
->
indices
);
WS_Assert_Allocated
(
ctx
->
ws
,
match
->
indices
,
match
->
n
*
sizeof
(
unsigned
));
if
(
idx
>
0
)
{
/* XXX search algorithm? */
idx
--
;
for
(
unsigned
i
=
0
;
i
<
match
->
n
;
i
++
)
if
(
match
->
indices
[
i
]
==
idx
)
return
(
1
);
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
))
return
(
match
->
exact
!=
UINT_MAX
);
return
(
1
);
}
VCL_VOID
vmod_set_create_stats
(
VRT_CTX
,
struct
vmod_selector_set
*
set
,
struct
vmod_priv
*
priv
)
...
...
src/vmod_selector.h
View file @
43541478
...
...
@@ -39,6 +39,12 @@
#define VFAIL(ctx, fmt, ...) \
VRT_fail((ctx), "vmod selector failure: " fmt, __VA_ARGS__)
#define VERRNOMEM(ctx, fmt, ...) \
VFAIL((ctx), "out of space: " fmt, __VA_ARGS__)
#define VNOTICE(ctx, fmt, ...) \
VSLb((ctx)->vsl, SLT_Notice, "vmod_selector: " fmt, __VA_ARGS__)
struct
entry
{
unsigned
magic
;
#define VMOD_SELECTOR_ENTRY_MAGIC 0x733dbe63
...
...
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