Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
libvmod-re2
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-re2
Commits
fca1f559
Commit
fca1f559
authored
Mar 25, 2016
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
first version of the set object
parent
e2113d0d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
576 additions
and
1 deletion
+576
-1
README.rst
README.rst
+34
-0
Makefile.am
src/Makefile.am
+5
-1
set.vtc
src/tests/set.vtc
+150
-0
vmod_re2.c
src/vmod_re2.c
+129
-0
vmod_re2.vcc
src/vmod_re2.vcc
+12
-0
vre2set.cpp
src/vre2/vre2set.cpp
+165
-0
vre2set.h
src/vre2/vre2set.h
+81
-0
No files found.
README.rst
View file @
fca1f559
...
...
@@ -34,6 +34,10 @@ CONTENTS
* STRING regex.backref(INT, STRING)
* BOOL regex.match(STRING)
* STRING regex.namedref(STRING, STRING)
* Object set
* VOID set.add(STRING)
* VOID set.compile()
* BOOL set.match(STRING)
* STRING version()
.. _obj_regex:
...
...
@@ -66,6 +70,36 @@ STRING regex.namedref(STRING, STRING)
Prototype
STRING regex.namedref(STRING name, STRING fallback)
.. _obj_set:
Object set
==========
.. _func_set.add:
VOID set.add(STRING)
--------------------
Prototype
VOID set.add(STRING)
.. _func_set.compile:
VOID set.compile()
------------------
Prototype
VOID set.compile()
.. _func_set.match:
BOOL set.match(STRING)
----------------------
Prototype
BOOL set.match(STRING)
.. _func_match:
BOOL match(PRIV_TASK, STRING, STRING, BOOL, BOOL, BOOL, INT, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL, BOOL)
...
...
src/Makefile.am
View file @
fca1f559
...
...
@@ -12,7 +12,9 @@ libvmod_re2_la_LDFLAGS = -module -export-dynamic -avoid-version -shared
libvmod_re2_la_SOURCES
=
\
vmod_re2.c
\
vre2/vre2.h
\
vre2/vre2.cpp
vre2/vre2.cpp
\
vre2/vre2set.h
\
vre2/vre2set.cpp
nodist_libvmod_re2_la_SOURCES
=
\
vcc_if.c
\
...
...
@@ -28,6 +30,8 @@ vcc_if.c: vcc_if.h
vre2/vre2.cpp
:
vre2/vre2.h
vre2/vre2set.cpp
:
vre2/vre2set.h
vcc_if.h vmod_re2.man.rst
:
@VMODTOOL@ $(top_srcdir)/src/vmod_re2.vcc
@
VMODTOOL@
$(top_srcdir)
/src/vmod_re2.vcc
...
...
src/tests/set.vtc
0 → 100644
View file @
fca1f559
# looks like -*- vcl -*-
varnishtest "set objects"
# tests from re2 re2/testing/set_test.cc
varnish v1 -vcl {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new unanchored = re2.set();
unanchored.add("foo");
unanchored.add("bar");
unanchored.compile();
new unanchored_factored = re2.set();
unanchored_factored.add("foo");
unanchored_factored.add("foobar");
unanchored_factored.compile();
new unanchored_dollar = re2.set();
unanchored_dollar.add("foo$");
unanchored_dollar.compile();
new anchored = re2.set(anchor=both);
anchored.add("foo");
anchored.add("bar");
anchored.compile();
new empty_unanchored = re2.set();
empty_unanchored.compile();
new empty_anchored = re2.set(anchor=both);
empty_anchored.compile();
}
sub vcl_recv {
return(synth(200));
}
sub vcl_synth {
if (unanchored.match("foobar")) {
set resp.http.unanchored1 = "match";
}
if (unanchored.match("fooba")) {
set resp.http.unanchored2 = "match";
}
if (unanchored.match("oobar")) {
set resp.http.unanchored3 = "match";
}
if (unanchored_factored.match("foobar")) {
set resp.http.unanchored_factored1 = "match";
}
if (unanchored_factored.match("obarfoobaroo")) {
set resp.http.unanchored_factored2 = "match";
}
if (unanchored_factored.match("fooba")) {
set resp.http.unanchored_factored3 = "match";
}
if (unanchored_factored.match("oobar")) {
set resp.http.unanchored_factored4 = "match";
}
if (unanchored_dollar.match("foo")) {
set resp.http.unanchored_dollar1 = "match";
}
if (anchored.match("foobar")) {
set resp.http.anchored1 = "match";
}
if (anchored.match("fooba")) {
set resp.http.anchored2 = "match";
}
if (anchored.match("oobar")) {
set resp.http.anchored3 = "match";
}
if (anchored.match("foo")) {
set resp.http.anchored4 = "match";
}
if (anchored.match("bar")) {
set resp.http.anchored5 = "match";
}
if (empty_unanchored.match("")) {
set resp.http.empty_unanchored1 = "match";
}
if (empty_unanchored.match("foobar")) {
set resp.http.empty_unanchored2 = "match";
}
if (empty_anchored.match("")) {
set resp.http.empty_anchored1 = "match";
}
if (empty_anchored.match("foobar")) {
set resp.http.empty_anchored2 = "match";
}
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.unanchored1 == "match"
expect resp.http.unanchored2 == "match"
expect resp.http.unanchored3 == "match"
expect resp.http.unanchored_factored1 == "match"
expect resp.http.unanchored_factored2 == "match"
expect resp.http.unanchored_factored3 == "match"
expect resp.http.unanchored_factored4 == <undef>
expect resp.http.unanchored_dollar1 == "match"
expect resp.http.anchored1 == <undef>
expect resp.http.anchored2 == <undef>
expect resp.http.anchored3 == <undef>
expect resp.http.anchored4 == "match"
expect resp.http.anchored5 == "match"
expect resp.http.empty_unanchored1 == <undef>
expect resp.http.empty_unanchored2 == <undef>
expect resp.http.empty_anchored1 == <undef>
expect resp.http.empty_anchored2 == <undef>
} -run
varnish v1 -errvcl {vmod re2 error: unanchored.add("("): missing ): (} {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new unanchored = re2.set();
unanchored.add("foo");
unanchored.add("(");
unanchored.add("bar");
unanchored.compile();
}
}
varnish v1 -errvcl {vmod re2 error: anchored.add("("): missing ): (} {
import re2 from "${vmod_topbuild}/src/.libs/libvmod_re2.so";
backend b { .host = "${bad_ip}"; }
sub vcl_init {
new anchored = re2.set(anchor=both);
anchored.add("foo");
anchored.add("(");
anchored.add("bar");
anchored.compile();
}
}
src/vmod_re2.c
View file @
fca1f559
...
...
@@ -41,6 +41,7 @@
#include "vcc_if.h"
#include "vre2/vre2.h"
#include "vre2/vre2set.h"
#define VERR(ctx, fmt, ...) \
errmsg((ctx), "vmod re2 error: " fmt, __VA_ARGS__)
...
...
@@ -55,6 +56,13 @@ struct vmod_re2_regex {
unsigned
never_capture
;
};
struct
vmod_re2_set
{
unsigned
magic
;
#define VMOD_RE2_SET_MAGIC 0xf6d7b15a
vre2set
*
set
;
char
*
vcl_name
;
};
typedef
struct
task_match_t
{
unsigned
magic
;
#define TASK_MATCH_MAGIC 0xa4b93c57
...
...
@@ -234,6 +242,8 @@ event(VRT_CTX, struct vmod_priv *priv, enum vcl_event_e e)
return
0
;
}
/* Object regex */
VCL_VOID
vmod_regex__init
(
const
struct
vrt_ctx
*
ctx
,
struct
vmod_re2_regex
**
rep
,
const
char
*
vcl_name
,
VCL_STRING
pattern
,
VCL_BOOL
utf8
,
...
...
@@ -368,6 +378,125 @@ vmod_regex_namedref(VRT_CTX, struct vmod_re2_regex *re, VCL_STRING name,
#undef ERR_PREFIX
/* Object set */
VCL_VOID
vmod_set__init
(
VRT_CTX
,
struct
vmod_re2_set
**
setp
,
const
char
*
vcl_name
,
VCL_ENUM
anchor
,
VCL_BOOL
utf8
,
VCL_BOOL
posix_syntax
,
VCL_BOOL
longest_match
,
VCL_INT
max_mem
,
VCL_BOOL
literal
,
VCL_BOOL
never_nl
,
VCL_BOOL
dot_nl
,
VCL_BOOL
case_sensitive
,
VCL_BOOL
perl_classes
,
VCL_BOOL
word_boundary
,
VCL_BOOL
one_line
)
{
struct
vmod_re2_set
*
set
;
anchor_e
anchor_e
;
const
char
*
err
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
AN
(
setp
);
AZ
(
*
setp
);
AN
(
vcl_name
);
AN
(
anchor
);
ALLOC_OBJ
(
set
,
VMOD_RE2_SET_MAGIC
);
AN
(
set
);
*
setp
=
set
;
if
(
strcmp
(
anchor
,
"none"
)
==
0
)
anchor_e
=
NONE
;
else
if
(
strcmp
(
anchor
,
"start"
)
==
0
)
anchor_e
=
START
;
else
if
(
strcmp
(
anchor
,
"both"
)
==
0
)
anchor_e
=
BOTH
;
else
WRONG
(
"illegal anchor"
);
if
((
err
=
vre2set_init
(
&
set
->
set
,
anchor_e
,
utf8
,
posix_syntax
,
longest_match
,
max_mem
,
literal
,
never_nl
,
dot_nl
,
case_sensitive
,
perl_classes
,
word_boundary
,
one_line
))
!=
NULL
)
{
VERR
(
ctx
,
"new %s = re2.set(): %s"
,
vcl_name
,
err
);
return
;
}
set
->
vcl_name
=
strdup
(
vcl_name
);
}
VCL_VOID
vmod_set__fini
(
struct
vmod_re2_set
**
setp
)
{
struct
vmod_re2_set
*
set
;
set
=
*
setp
;
*
setp
=
NULL
;
CHECK_OBJ_NOTNULL
(
set
,
VMOD_RE2_SET_MAGIC
);
vre2set_fini
(
&
set
->
set
);
if
(
set
->
vcl_name
!=
NULL
)
free
(
set
->
vcl_name
);
FREE_OBJ
(
set
);
}
#define ERR_PREFIX "%s.add(\"%s\"): "
VCL_VOID
vmod_set_add
(
VRT_CTX
,
struct
vmod_re2_set
*
set
,
VCL_STRING
pattern
)
{
const
char
*
err
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_RE2_SET_MAGIC
);
/* XXX: check if compiled */
if
((
err
=
vre2set_add
(
set
->
set
,
pattern
))
!=
NULL
)
{
VERR
(
ctx
,
ERR_PREFIX
"%s"
,
set
->
vcl_name
,
pattern
,
err
);
return
;
}
}
#undef ERR_PREFIX
#define ERR_PREFIX "%s.compile(\"%s\"): "
VCL_VOID
vmod_set_compile
(
VRT_CTX
,
struct
vmod_re2_set
*
set
)
{
const
char
*
err
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_RE2_SET_MAGIC
);
/* XXX: check if compiled */
if
((
err
=
vre2set_compile
(
set
->
set
))
!=
NULL
)
{
VERR
(
ctx
,
ERR_PREFIX
"%s"
,
set
->
vcl_name
,
err
);
return
;
}
}
#undef ERR_PREFIX
#define ERR_PREFIX "%s.match(\"%s\"): "
VCL_BOOL
vmod_set_match
(
VRT_CTX
,
struct
vmod_re2_set
*
set
,
VCL_STRING
subject
)
{
int
match
=
0
;
const
char
*
err
;
CHECK_OBJ_NOTNULL
(
ctx
,
VRT_CTX_MAGIC
);
CHECK_OBJ_NOTNULL
(
set
,
VMOD_RE2_SET_MAGIC
);
if
(
subject
==
NULL
)
subject
=
""
;
/* XXX: check if compiled */
if
((
err
=
vre2set_match
(
set
->
set
,
subject
,
&
match
))
!=
NULL
)
{
VERR
(
ctx
,
ERR_PREFIX
"%s"
,
set
->
vcl_name
,
subject
,
err
);
return
0
;
}
return
match
;
}
#undef ERR_PREFIX
/* Regex function interface */
#define ERR_PREFIX "re2.match(pattern=\"%s\", text=\"%s\"): "
VCL_BOOL
...
...
src/vmod_re2.vcc
View file @
fca1f559
...
...
@@ -24,6 +24,18 @@ $Method STRING .backref(INT ref, STRING fallback = "**BACKREF METHOD FAILED**")
$Method STRING .namedref(STRING name,
STRING fallback = "**NAMEDREF METHOD FAILED**")
$Object set(ENUM { none, start, both } anchor="none", BOOL utf8=0,
BOOL posix_syntax=0, BOOL longest_match=0, INT max_mem=8388608,
BOOL literal=0, BOOL never_nl=0, BOOL dot_nl=0,
BOOL case_sensitive=1, BOOL perl_classes=0, BOOL word_boundary=0,
BOOL one_line=0)
$Method VOID .add(STRING)
$Method VOID .compile()
$Method BOOL .match(STRING)
$Function BOOL match(PRIV_TASK, STRING pattern, STRING subject, BOOL utf8=0,
BOOL posix_syntax=0, BOOL longest_match=0,
INT max_mem=8388608, BOOL literal=0, BOOL never_nl=0,
...
...
src/vre2/vre2set.cpp
0 → 100644
View file @
fca1f559
/*-
* Copyright (c) 2016 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 "vre2set.h"
#define CATCHALL \
catch (const runtime_error& err) { \
return err.what(); \
} \
catch (const exception& ex) { \
return ex.what(); \
} \
catch (...) { \
return "Unknown error"; \
}
using
namespace
std
;
vre2set
::
vre2set
(
RE2
::
Options
*
const
opt
,
const
RE2
::
Anchor
anchor
)
{
set_
=
new
RE2
::
Set
(
*
opt
,
anchor
);
}
vre2set
::~
vre2set
()
{
if
(
set_
)
{
delete
set_
;
set_
=
NULL
;
}
}
inline
int
vre2set
::
add
(
const
char
*
pattern
,
string
*
error
)
const
{
return
set_
->
Add
(
pattern
,
error
);
}
inline
bool
vre2set
::
compile
()
const
{
return
set_
->
Compile
();
}
inline
bool
vre2set
::
match
(
const
char
*
subject
)
const
{
return
set_
->
Match
(
subject
,
NULL
);
}
const
char
*
vre2set_init
(
vre2set
**
setp
,
anchor_e
anchor
,
unsigned
utf8
,
unsigned
posix_syntax
,
unsigned
longest_match
,
long
max_mem
,
unsigned
literal
,
unsigned
never_nl
,
unsigned
dot_nl
,
unsigned
case_sensitive
,
unsigned
perl_classes
,
unsigned
word_boundary
,
unsigned
one_line
)
{
try
{
RE2
::
Options
opt
;
RE2
::
Anchor
re2_anchor
;
switch
(
anchor
)
{
case
NONE
:
re2_anchor
=
RE2
::
UNANCHORED
;
break
;
case
START
:
re2_anchor
=
RE2
::
ANCHOR_START
;
break
;
case
BOTH
:
re2_anchor
=
RE2
::
ANCHOR_BOTH
;
break
;
default
:
throw
runtime_error
(
"illegal anchor"
);
}
opt
.
set_log_errors
(
false
);
opt
.
set_never_capture
(
true
);
if
(
utf8
)
opt
.
set_encoding
(
RE2
::
Options
::
EncodingUTF8
);
else
opt
.
set_encoding
(
RE2
::
Options
::
EncodingLatin1
);
opt
.
set_posix_syntax
(
posix_syntax
);
opt
.
set_longest_match
(
longest_match
);
opt
.
set_max_mem
(
max_mem
);
opt
.
set_literal
(
literal
);
opt
.
set_never_nl
(
never_nl
);
opt
.
set_dot_nl
(
dot_nl
);
opt
.
set_case_sensitive
(
case_sensitive
);
opt
.
set_perl_classes
(
perl_classes
);
opt
.
set_word_boundary
(
word_boundary
);
opt
.
set_one_line
(
one_line
);
*
setp
=
new
vre2set
(
&
opt
,
re2_anchor
);
return
NULL
;
}
CATCHALL
}
const
char
*
vre2set_add
(
vre2set
*
set
,
const
char
*
const
pattern
)
{
try
{
string
err
;
if
(
set
->
add
(
pattern
,
&
err
)
==
-
1
)
throw
runtime_error
(
err
);
return
NULL
;
}
CATCHALL
}
const
char
*
vre2set_compile
(
vre2set
*
set
)
{
try
{
if
(
!
set
->
compile
())
throw
runtime_error
(
"compile failed"
);
return
NULL
;
}
CATCHALL
}
const
char
*
vre2set_match
(
vre2set
*
set
,
const
char
*
const
subject
,
int
*
const
match
)
{
try
{
*
match
=
set
->
match
(
subject
);
return
NULL
;
}
CATCHALL
}
const
char
*
vre2set_fini
(
vre2set
**
set
)
{
try
{
delete
*
set
;
return
NULL
;
}
CATCHALL
}
src/vre2/vre2set.h
0 → 100644
View file @
fca1f559
/*-
* Copyright (c) 2016 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.
*
*/
#ifndef _VRE2SET_H
#define _VRE2SET_H
#ifdef __cplusplus
#include <re2/re2.h>
#include <re2/set.h>
using
namespace
re2
;
class
vre2set
{
private
:
RE2
::
Set
*
set_
;
public
:
vre2set
(
RE2
::
Options
*
const
opt
,
const
RE2
::
Anchor
anchor
);
virtual
~
vre2set
();
int
add
(
const
char
*
pattern
,
string
*
error
)
const
;
bool
compile
()
const
;
bool
match
(
const
char
*
subject
)
const
;
};
#else
typedef
struct
vre2set
vre2set
;
#endif
typedef
enum
{
NONE
,
START
,
BOTH
}
anchor_e
;
#ifdef __cplusplus
extern
"C"
{
#endif
const
char
*
vre2set_init
(
vre2set
**
set
,
anchor_e
anchor
,
unsigned
utf8
,
unsigned
posix_syntax
,
unsigned
longest_match
,
long
max_mem
,
unsigned
literal
,
unsigned
never_nl
,
unsigned
dot_nl
,
unsigned
case_sensitive
,
unsigned
perl_classes
,
unsigned
word_boundary
,
unsigned
one_line
);
const
char
*
vre2set_fini
(
vre2set
**
vre2
);
const
char
*
vre2set_add
(
vre2set
*
set
,
const
char
*
pattern
);
const
char
*
vre2set_compile
(
vre2set
*
set
);
const
char
*
vre2set_match
(
vre2set
*
set
,
const
char
*
subject
,
int
*
const
match
);
#ifdef __cplusplus
}
#endif
#endif
/* _VRE2SET_H */
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