2626
2727#include " ts/experimental.h"
2828
29+ Config::~Config ()
30+ {
31+ if (nullptr != m_regex_extra) {
32+ #ifndef PCRE_STUDY_JIT_COMPILE
33+ pcre_free (m_regex_extra);
34+ #else
35+ pcre_free_study (m_regex_extra);
36+ #endif
37+ }
38+ if (nullptr != m_regex) {
39+ pcre_free (m_regex);
40+ }
41+ }
42+
2943int64_t
3044Config::bytesFrom (char const *const valstr)
3145{
@@ -94,18 +108,20 @@ Config::fromArgs(int const argc, char const *const argv[])
94108 // standard parsing
95109 constexpr struct option longopts[] = {
96110 {const_cast <char *>(" blockbytes" ), required_argument, nullptr , ' b' },
97- {const_cast <char *>(" blockbytes-test" ), required_argument, nullptr , ' t' },
98- {const_cast <char *>(" remap-host" ), required_argument, nullptr , ' r' },
99- {const_cast <char *>(" pace-errorlog" ), required_argument, nullptr , ' p' },
100111 {const_cast <char *>(" disable-errorlog" ), no_argument, nullptr , ' d' },
112+ {const_cast <char *>(" exclude-regex" ), required_argument, nullptr , ' e' },
113+ {const_cast <char *>(" include-regex" ), required_argument, nullptr , ' i' },
101114 {const_cast <char *>(" throttle" ), no_argument, nullptr , ' o' },
115+ {const_cast <char *>(" pace-errorlog" ), required_argument, nullptr , ' p' },
116+ {const_cast <char *>(" remap-host" ), required_argument, nullptr , ' r' },
117+ {const_cast <char *>(" blockbytes-test" ), required_argument, nullptr , ' t' },
102118 {nullptr , 0 , nullptr , 0 },
103119 };
104120
105121 // getopt assumes args start at '1' so this hack is needed
106122 char *const *argvp = (const_cast <char *const *>(argv) - 1 );
107123 for (;;) {
108- int const opt = getopt_long (argc + 1 , argvp, " b:t:r:p:do " , longopts, nullptr );
124+ int const opt = getopt_long (argc + 1 , argvp, " b:de:i:op:r:t: " , longopts, nullptr );
109125 if (-1 == opt) {
110126 break ;
111127 }
@@ -122,6 +138,61 @@ Config::fromArgs(int const argc, char const *const argv[])
122138 ERROR_LOG (" Invalid blockbytes: %s" , optarg);
123139 }
124140 } break ;
141+ case ' d' : {
142+ m_paceerrsecs = -1 ;
143+ } break ;
144+ case ' e' : {
145+ if (None != m_regex_type) {
146+ ERROR_LOG (" Regex already specified!" );
147+ break ;
148+ }
149+
150+ const char *errptr;
151+ int erroffset;
152+ m_regexstr = optarg;
153+ m_regex = pcre_compile (m_regexstr.c_str (), 0 , &errptr, &erroffset, NULL );
154+ if (nullptr == m_regex) {
155+ ERROR_LOG (" Invalid regex: '%s'" , m_regexstr.c_str ());
156+ } else {
157+ m_regex_type = Exclude;
158+ m_regex_extra = pcre_study (m_regex, 0 , &errptr);
159+ DEBUG_LOG (" Using regex for url exclude: '%s'" , m_regexstr.c_str ());
160+ }
161+ } break ;
162+ case ' i' : {
163+ if (None != m_regex_type) {
164+ ERROR_LOG (" Regex already specified!" );
165+ break ;
166+ }
167+
168+ const char *errptr;
169+ int erroffset;
170+ m_regexstr = optarg;
171+ m_regex = pcre_compile (m_regexstr.c_str (), 0 , &errptr, &erroffset, NULL );
172+ if (nullptr == m_regex) {
173+ ERROR_LOG (" Invalid regex: '%s'" , m_regexstr.c_str ());
174+ } else {
175+ m_regex_type = Include;
176+ m_regex_extra = pcre_study (m_regex, 0 , &errptr);
177+ DEBUG_LOG (" Using regex for url include: '%s'" , m_regexstr.c_str ());
178+ }
179+ } break ;
180+ case ' o' : {
181+ m_throttle = true ;
182+ DEBUG_LOG (" Enabling internal block throttling" );
183+ } break ;
184+ case ' p' : {
185+ int const secsread = atoi (optarg);
186+ if (0 < secsread) {
187+ m_paceerrsecs = std::min (secsread, 60 );
188+ } else {
189+ ERROR_LOG (" Ignoring pace-errlog argument" );
190+ }
191+ } break ;
192+ case ' r' : {
193+ m_remaphost = optarg;
194+ DEBUG_LOG (" Using loopback remap host override: %s" , m_remaphost.c_str ());
195+ } break ;
125196 case ' t' : {
126197 if (0 == blockbytes) {
127198 int64_t const bytesread = bytesFrom (optarg);
@@ -135,25 +206,6 @@ Config::fromArgs(int const argc, char const *const argv[])
135206 DEBUG_LOG (" Skipping blockbytes-test in favor of blockbytes" );
136207 }
137208 } break ;
138- case ' r' :
139- m_remaphost = optarg;
140- DEBUG_LOG (" Using loopback remap host override: %s" , m_remaphost.c_str ());
141- break ;
142- case ' p' : {
143- int const secsread = atoi (optarg);
144- if (0 < secsread) {
145- m_paceerrsecs = std::min (secsread, 60 );
146- } else {
147- ERROR_LOG (" Ignoring pace-errlog argument" );
148- }
149- } break ;
150- case ' d' :
151- m_paceerrsecs = -1 ;
152- break ;
153- case ' o' :
154- m_throttle = true ;
155- DEBUG_LOG (" Enabling internal block throttling" );
156- break ;
157209 default :
158210 break ;
159211 }
@@ -204,3 +256,26 @@ Config::canLogError()
204256
205257 return true ;
206258}
259+
260+ bool
261+ Config::matchesRegex (char const *const url, int const urllen) const
262+ {
263+ bool matches = true ;
264+
265+ switch (m_regex_type) {
266+ case Exclude: {
267+ if (0 <= pcre_exec (m_regex, m_regex_extra, url, urllen, 0 , 0 , NULL , 0 )) {
268+ matches = false ;
269+ }
270+ } break ;
271+ case Include: {
272+ if (pcre_exec (m_regex, m_regex_extra, url, urllen, 0 , 0 , NULL , 0 ) < 0 ) {
273+ matches = false ;
274+ }
275+ } break ;
276+ default :
277+ break ;
278+ }
279+
280+ return matches;
281+ }
0 commit comments