Skip to content

Commit f9cd7fc

Browse files
committed
regex_revalidate c++ and lifecycle message reload and print
1 parent 01bd0f8 commit f9cd7fc

11 files changed

Lines changed: 1233 additions & 655 deletions

File tree

doc/admin-guide/plugins/regex_revalidate.en.rst

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,36 +40,34 @@ regular expression against your origin URLs permits. Thus, individual cache
4040
objects may have rules created for them, or entire path prefixes, or even any
4141
cache objects with a particular file extension.
4242

43-
Installation
44-
============
45-
46-
To make this plugin available, you must enable experimental plugins when
47-
building |TS|::
48-
49-
./configure --enable-experimental-plugins
50-
5143
Configuration
5244
=============
45+
.. program:: regex_revalidate.so
5346

54-
This plugin is enabled via the :file:`plugin.config` configuration file, with
55-
two required arguments: the path to a rules file, and the path to a log file::
47+
``Regex Revalidate`` is a global plugin and is configured via :file:`plugin.config`.
48+
.. option:: --config <path to revalidate rules> (also -c)
5649

57-
regex_revalidate.so -c <path to rules> -l <path to log>
50+
(`required`) - specifies the file which contains the revalidation rules.
51+
The rule configuration file format is described below in
52+
`Revalidation Rules`_. These rules are always reloaded when
53+
``traffic_ctl config reload`` is invoked.
5854

59-
The rule configuration file format is described below in `Revalidation Rules`_.
55+
.. option:: --log <path to log> (also -l)
6056

61-
By default The plugin regularly (every 60 seconds) checks its rules configuration
62-
file for changes and it will also check for changes when ``traffic_ctl config reload``
63-
is run. If the file has been modified since its last scan, the contents
64-
are read and the in-memory rules list is updated. Thus, new rules may be added and
65-
existing ones modified without requiring a service restart.
57+
(`optional`) - specifies path to rule logging. This log is written to
58+
after rule changes and contains the current active ruleset. If missing
59+
no log file is generated.
6660

67-
The configuration parameter `--disable-timed-updates` or `-d` may be used to configure
68-
the plugin to disable timed config file change checks. With timed checks disabled,
69-
config file changes are checked are only when ``traffic_ctl config reload`` is run.::
61+
.. option:: --disable-timed-reload (also -d)
7062

71-
regex_revalidate.so -d -c <path to rules> -l <path to log>
63+
(`optional`) - default plugin behaviour is to check the revalidate
64+
rules file for changes every 60 seconds. This option disables the
65+
checking.
7266

67+
``traffic_ctl`` <command>
68+
* ``traffic_ctl config reload`` - triggers a reload of the rules file. If there are no changes then the loaded rules are discarded.
69+
* ``traffic_ctl plugin msg regex_revalidate config_reload`` - triggers a reload of the rules file apart from a full config reload.
70+
* ``traffic_ctl plugin msg regex_revalidate config_print`` - writes the current active ruleset to :file:`traffic.out`
7371

7472
Revalidation Rules
7573
==================
@@ -111,11 +109,11 @@ the fact that the plugin uses :c:data:`TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK`.
111109
Removing Rules
112110
--------------
113111

114-
While new rules are added dynamically (the configuration file is checked every
115-
60 seconds for changes), rule lines removed from the configuration file do not
116-
currently lead to that rule being removed from the running plugin. In these
117-
cases, if the rule must be taken out of service, a service restart may be
118-
necessary.
112+
While new rules are added dynamically (the configuration file is checked
113+
every 60 seconds for changes), rule lines removed from the configuration
114+
file do not currently lead to that rule being removed from the running
115+
plugin. To take these rules out of service the rule should be assigned a
116+
new time in the past which will cause it to be pruned during reload phase.
119117

120118
Examples
121119
========

plugins/regex_revalidate/Makefile.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@
1515
# limitations under the License.
1616

1717
pkglib_LTLIBRARIES += regex_revalidate/regex_revalidate.la
18-
regex_revalidate_regex_revalidate_la_SOURCES = regex_revalidate/regex_revalidate.c
18+
regex_revalidate_regex_revalidate_la_SOURCES = regex_revalidate/regex_revalidate.cc regex_revalidate/regex.cc

plugins/regex_revalidate/regex.cc

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/** @file
2+
3+
PCRE support wrapper.
4+
5+
@section license License
6+
7+
Licensed to the Apache Software Foundation (ASF) under one
8+
or more contributor license agreements. See the NOTICE file
9+
distributed with this work for additional information
10+
regarding copyright ownership. The ASF licenses this file
11+
to you under the Apache License, Version 2.0 (the
12+
"License"); you may not use this file except in compliance
13+
with the License. You may obtain a copy of the License at
14+
15+
http://www.apache.org/licenses/LICENSE-2.0
16+
17+
Unless required by applicable law or agreed to in writing, software
18+
distributed under the License is distributed on an "AS IS" BASIS,
19+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20+
See the License for the specific language governing permissions and
21+
limitations under the License.
22+
*/
23+
24+
#include "regex.h"
25+
26+
#ifdef PCRE_CONFIG_JIT
27+
#include <pthread.h>
28+
29+
struct RegexThreadKey {
30+
RegexThreadKey() { pthread_key_create(&this->key, reinterpret_cast<void (*)(void *)>(&pcre_jit_stack_free)); }
31+
pthread_key_t key;
32+
};
33+
34+
static RegexThreadKey k;
35+
36+
static pcre_jit_stack *
37+
get_jit_stack(void *)
38+
{
39+
pcre_jit_stack *jit_stack;
40+
41+
if ((jit_stack = static_cast<pcre_jit_stack *>(pthread_getspecific(k.key))) == nullptr) {
42+
jit_stack = pcre_jit_stack_alloc(8192, 1024 * 1024); // 1 page min and 1MB max
43+
pthread_setspecific(k.key, (void *)jit_stack);
44+
}
45+
46+
return jit_stack;
47+
}
48+
#endif
49+
50+
bool
51+
Regex::compile(const char *pattern, const unsigned flags)
52+
{
53+
const char *error;
54+
int erroffset;
55+
int options = 0;
56+
int study_opts = 0;
57+
58+
if (nullptr != this->regex) {
59+
return false;
60+
}
61+
62+
if (flags & CASE_INSENSITIVE) {
63+
options |= PCRE_CASELESS;
64+
}
65+
66+
if (flags & ANCHORED) {
67+
options |= PCRE_ANCHORED;
68+
}
69+
70+
this->regex = pcre_compile(pattern, options, &error, &erroffset, nullptr);
71+
if (error) {
72+
this->regex = nullptr;
73+
return false;
74+
}
75+
76+
#ifdef PCRE_CONFIG_JIT
77+
study_opts |= PCRE_STUDY_JIT_COMPILE;
78+
#endif
79+
80+
this->regex_extra = pcre_study(this->regex, study_opts, &error);
81+
82+
#ifdef PCRE_CONFIG_JIT
83+
if (nullptr != this->regex_extra) {
84+
pcre_assign_jit_stack(this->regex_extra, &get_jit_stack, nullptr);
85+
}
86+
#endif
87+
88+
return true;
89+
}
90+
91+
bool
92+
Regex::matches(std::string_view const &src) const
93+
{
94+
return 0 <= exec(src, nullptr, 0);
95+
}
96+
97+
int
98+
Regex::exec(std::string_view const &src, int *ovector, int const ovecsize) const
99+
{
100+
return pcre_exec(this->regex, this->regex_extra, src.data(), src.size(), 0, 0, ovector, ovecsize);
101+
}
102+
103+
Regex::~Regex()
104+
{
105+
if (regex_extra) {
106+
#ifdef PCRE_CONFIG_JIT
107+
pcre_free_study(regex_extra);
108+
#else
109+
pcre_free(regex_extra);
110+
#endif
111+
}
112+
if (regex) {
113+
pcre_free(regex);
114+
}
115+
}

plugins/regex_revalidate/regex.h

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/** @file
2+
3+
Wrapper to make PCRE handling easier.
4+
5+
@section license License
6+
7+
Licensed to the Apache Software Foundation (ASF) under one
8+
or more contributor license agreements. See the NOTICE file
9+
distributed with this work for additional information
10+
regarding copyright ownership. The ASF licenses this file
11+
to you under the Apache License, Version 2.0 (the
12+
"License"); you may not use this file except in compliance
13+
with the License. You may obtain a copy of the License at
14+
15+
http://www.apache.org/licenses/LICENSE-2.0
16+
17+
Unless required by applicable law or agreed to in writing, software
18+
distributed under the License is distributed on an "AS IS" BASIS,
19+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20+
See the License for the specific language governing permissions and
21+
limitations under the License.
22+
*/
23+
24+
#pragma once
25+
26+
#include <pcre.h>
27+
#include <algorithm>
28+
#include <string_view>
29+
30+
class Regex
31+
{
32+
public:
33+
enum Flag {
34+
CASE_INSENSITIVE = 0x0001, // default is case sensitive
35+
UNANCHORED = 0x0002, // default (for DFA) is to anchor at the first matching position
36+
ANCHORED = 0x0004, // default (for Regex) is unanchored
37+
};
38+
39+
Regex() = default;
40+
Regex(Regex &&that);
41+
Regex &operator=(Regex &&that);
42+
43+
bool compile(const char *pattern, const unsigned flags = 0);
44+
45+
// check if valid regex
46+
bool is_valid() const;
47+
48+
// check for simple match
49+
bool matches(std::string_view const &src) const;
50+
51+
// match returning substring positions.
52+
int exec(std::string_view const &src, int *ovector, int const ovecsize) const;
53+
54+
~Regex();
55+
56+
private:
57+
pcre *regex = nullptr;
58+
pcre_extra *regex_extra = nullptr;
59+
};
60+
61+
inline Regex::Regex(Regex &&that)
62+
{
63+
std::swap(regex, that.regex);
64+
std::swap(regex_extra, that.regex_extra);
65+
}
66+
67+
inline Regex &
68+
Regex::operator=(Regex &&that)
69+
{
70+
if (&that != this) {
71+
std::swap(regex, that.regex);
72+
std::swap(regex_extra, that.regex_extra);
73+
}
74+
return *this;
75+
}
76+
77+
inline bool
78+
Regex::is_valid() const
79+
{
80+
return nullptr != regex;
81+
}

0 commit comments

Comments
 (0)