matchers/matchers.cc
Go to the documentation of this file.
1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
16 
18 
19 #include <utility>
20 
21 #include "absl/memory/memory.h"
22 #include "absl/status/status.h"
23 #include "absl/strings/ascii.h"
24 #include "absl/strings/match.h"
25 #include "absl/strings/numbers.h"
26 #include "absl/strings/str_format.h"
27 
28 namespace grpc_core {
29 
30 //
31 // StringMatcher
32 //
33 
35  absl::string_view matcher,
36  bool case_sensitive) {
37  if (type == Type::kSafeRegex) {
38  auto regex_matcher = absl::make_unique<RE2>(std::string(matcher));
39  if (!regex_matcher->ok()) {
41  "Invalid regex string specified in matcher.");
42  }
44  } else {
45  return StringMatcher(type, matcher, case_sensitive);
46  }
47 }
48 
50  bool case_sensitive)
51  : type_(type), string_matcher_(matcher), case_sensitive_(case_sensitive) {}
52 
53 StringMatcher::StringMatcher(std::unique_ptr<RE2> regex_matcher)
54  : type_(Type::kSafeRegex), regex_matcher_(std::move(regex_matcher)) {}
55 
57  : type_(other.type_), case_sensitive_(other.case_sensitive_) {
58  if (type_ == Type::kSafeRegex) {
59  regex_matcher_ = absl::make_unique<RE2>(other.regex_matcher_->pattern());
60  } else {
62  }
63 }
64 
66  type_ = other.type_;
67  if (type_ == Type::kSafeRegex) {
68  regex_matcher_ = absl::make_unique<RE2>(other.regex_matcher_->pattern());
69  } else {
71  }
73  return *this;
74 }
75 
77  : type_(other.type_), case_sensitive_(other.case_sensitive_) {
78  if (type_ == Type::kSafeRegex) {
79  regex_matcher_ = std::move(other.regex_matcher_);
80  } else {
81  string_matcher_ = std::move(other.string_matcher_);
82  }
83 }
84 
86  type_ = other.type_;
87  if (type_ == Type::kSafeRegex) {
88  regex_matcher_ = std::move(other.regex_matcher_);
89  } else {
90  string_matcher_ = std::move(other.string_matcher_);
91  }
92  case_sensitive_ = other.case_sensitive_;
93  return *this;
94 }
95 
96 bool StringMatcher::operator==(const StringMatcher& other) const {
97  if (type_ != other.type_ || case_sensitive_ != other.case_sensitive_) {
98  return false;
99  }
100  if (type_ == Type::kSafeRegex) {
101  return regex_matcher_->pattern() == other.regex_matcher_->pattern();
102  } else {
103  return string_matcher_ == other.string_matcher_;
104  }
105 }
106 
108  switch (type_) {
109  case Type::kExact:
113  return case_sensitive_
120  return case_sensitive_
125  return RE2::FullMatch(std::string(value), *regex_matcher_);
126  default:
127  return false;
128  }
129 }
130 
132  switch (type_) {
133  case Type::kExact:
134  return absl::StrFormat("StringMatcher{exact=%s%s}", string_matcher_,
135  case_sensitive_ ? "" : ", case_sensitive=false");
136  case Type::kPrefix:
137  return absl::StrFormat("StringMatcher{prefix=%s%s}", string_matcher_,
138  case_sensitive_ ? "" : ", case_sensitive=false");
139  case Type::kSuffix:
140  return absl::StrFormat("StringMatcher{suffix=%s%s}", string_matcher_,
141  case_sensitive_ ? "" : ", case_sensitive=false");
142  case Type::kContains:
143  return absl::StrFormat("StringMatcher{contains=%s%s}", string_matcher_,
144  case_sensitive_ ? "" : ", case_sensitive=false");
145  case Type::kSafeRegex:
146  return absl::StrFormat("StringMatcher{safe_regex=%s}",
147  regex_matcher_->pattern());
148  default:
149  return "";
150  }
151 }
152 
153 //
154 // HeaderMatcher
155 //
156 
159  int64_t range_start, int64_t range_end, bool present_match,
160  bool invert_match) {
161  if (static_cast<int>(type) < 5) {
162  // Only for EXACT, PREFIX, SUFFIX, SAFE_REGEX and CONTAINS.
164  StringMatcher::Create(static_cast<StringMatcher::Type>(type), matcher,
165  /*case_sensitive=*/true);
166  if (!string_matcher.ok()) {
167  return string_matcher.status();
168  }
169  return HeaderMatcher(name, type, std::move(string_matcher.value()),
170  invert_match);
171  } else if (type == Type::kRange) {
172  if (range_start > range_end) {
174  "Invalid range specifier specified: end cannot be smaller than "
175  "start.");
176  }
177  return HeaderMatcher(name, range_start, range_end, invert_match);
178  } else {
179  return HeaderMatcher(name, present_match, invert_match);
180  }
181 }
182 
184  StringMatcher string_matcher, bool invert_match)
185  : name_(name),
186  type_(type),
187  matcher_(std::move(string_matcher)),
188  invert_match_(invert_match) {}
189 
191  int64_t range_end, bool invert_match)
192  : name_(name),
193  type_(Type::kRange),
194  range_start_(range_start),
195  range_end_(range_end),
196  invert_match_(invert_match) {}
197 
199  bool invert_match)
200  : name_(name),
201  type_(Type::kPresent),
202  present_match_(present_match),
203  invert_match_(invert_match) {}
204 
206  : name_(other.name_),
207  type_(other.type_),
208  invert_match_(other.invert_match_) {
209  switch (type_) {
210  case Type::kRange:
211  range_start_ = other.range_start_;
212  range_end_ = other.range_end_;
213  break;
214  case Type::kPresent:
216  break;
217  default:
218  matcher_ = other.matcher_;
219  }
220 }
221 
223  name_ = other.name_;
224  type_ = other.type_;
226  switch (type_) {
227  case Type::kRange:
228  range_start_ = other.range_start_;
229  range_end_ = other.range_end_;
230  break;
231  case Type::kPresent:
233  break;
234  default:
235  matcher_ = other.matcher_;
236  }
237  return *this;
238 }
239 
241  : name_(std::move(other.name_)),
242  type_(other.type_),
243  invert_match_(other.invert_match_) {
244  switch (type_) {
245  case Type::kRange:
246  range_start_ = other.range_start_;
247  range_end_ = other.range_end_;
248  break;
249  case Type::kPresent:
250  present_match_ = other.present_match_;
251  break;
252  default:
253  matcher_ = std::move(other.matcher_);
254  }
255 }
256 
258  name_ = std::move(other.name_);
259  type_ = other.type_;
260  invert_match_ = other.invert_match_;
261  switch (type_) {
262  case Type::kRange:
263  range_start_ = other.range_start_;
264  range_end_ = other.range_end_;
265  break;
266  case Type::kPresent:
267  present_match_ = other.present_match_;
268  break;
269  default:
270  matcher_ = std::move(other.matcher_);
271  }
272  return *this;
273 }
274 
275 bool HeaderMatcher::operator==(const HeaderMatcher& other) const {
276  if (name_ != other.name_) return false;
277  if (type_ != other.type_) return false;
278  if (invert_match_ != other.invert_match_) return false;
279  switch (type_) {
280  case Type::kRange:
281  return range_start_ == other.range_start_ &&
282  range_end_ == other.range_end_;
283  case Type::kPresent:
284  return present_match_ == other.present_match_;
285  default:
286  return matcher_ == other.matcher_;
287  }
288 }
289 
292  bool match;
293  if (type_ == Type::kPresent) {
294  match = value.has_value() == present_match_;
295  } else if (!value.has_value()) {
296  // All other types fail to match if field is not present.
297  return false;
298  } else if (type_ == Type::kRange) {
299  int64_t int_value;
300  match = absl::SimpleAtoi(value.value(), &int_value) &&
301  int_value >= range_start_ && int_value < range_end_;
302  } else {
303  match = matcher_.Match(value.value());
304  }
305  return match != invert_match_;
306 }
307 
309  switch (type_) {
310  case Type::kRange:
311  return absl::StrFormat("HeaderMatcher{%s %srange=[%d, %d]}", name_,
312  invert_match_ ? "not " : "", range_start_,
313  range_end_);
314  case Type::kPresent:
315  return absl::StrFormat("HeaderMatcher{%s %spresent=%s}", name_,
316  invert_match_ ? "not " : "",
317  present_match_ ? "true" : "false");
318  case Type::kExact:
319  case Type::kPrefix:
320  case Type::kSuffix:
321  case Type::kSafeRegex:
322  case Type::kContains:
323  return absl::StrFormat("HeaderMatcher{%s %s%s}", name_,
324  invert_match_ ? "not " : "", matcher_.ToString());
325  default:
326  return "";
327  }
328 }
329 
330 } // namespace grpc_core
grpc_core::HeaderMatcher::Type::kSuffix
@ kSuffix
grpc_core::HeaderMatcher::Type::kContains
@ kContains
absl::InvalidArgumentError
Status InvalidArgumentError(absl::string_view message)
Definition: third_party/abseil-cpp/absl/status/status.cc:351
grpc_core::StringMatcher::operator==
bool operator==(const StringMatcher &other) const
Definition: matchers/matchers.cc:96
grpc_core::HeaderMatcher::type_
Type type_
Definition: matchers/matchers.h:152
grpc_core::HeaderMatcher::type
Type type() const
Definition: matchers/matchers.h:127
grpc_core::HeaderMatcher::Match
bool Match(const absl::optional< absl::string_view > &value) const
Definition: matchers/matchers.cc:290
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
grpc_core::HeaderMatcher::Type::kExact
@ kExact
grpc_core::HeaderMatcher::operator==
bool operator==(const HeaderMatcher &other) const
Definition: matchers/matchers.cc:275
grpc_core
Definition: call_metric_recorder.h:31
match
unsigned char match[65280+2]
Definition: bloaty/third_party/zlib/examples/gun.c:165
grpc_core::HeaderMatcher::range_end_
int64_t range_end_
Definition: matchers/matchers.h:155
absl::StartsWithIgnoreCase
bool StartsWithIgnoreCase(absl::string_view text, absl::string_view prefix) noexcept
Definition: abseil-cpp/absl/strings/match.cc:30
absl::StartsWith
bool StartsWith(absl::string_view text, absl::string_view prefix) noexcept
Definition: third_party/abseil-cpp/absl/strings/match.h:58
absl::string_view
Definition: abseil-cpp/absl/strings/string_view.h:167
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
type_
std::string type_
Definition: client_channel_stress_test.cc:212
range_end
uint32_t range_end
Definition: xds_resolver.cc:330
grpc_core::StringMatcher::Create
static absl::StatusOr< StringMatcher > Create(Type type, absl::string_view matcher, bool case_sensitive=true)
Definition: matchers/matchers.cc:34
setup.name
name
Definition: setup.py:542
name_
const std::string name_
Definition: priority.cc:233
grpc_core::HeaderMatcher::Type::kPresent
@ kPresent
grpc_core::HeaderMatcher
Definition: matchers/matchers.h:79
absl::AsciiStrToLower
void AsciiStrToLower(std::string *s)
Definition: abseil-cpp/absl/strings/ascii.cc:158
grpc_core::StringMatcher::case_sensitive_
bool case_sensitive_
Definition: matchers/matchers.h:76
grpc_core::StringMatcher::Type::kSuffix
@ kSuffix
grpc_core::StringMatcher::StringMatcher
StringMatcher()=default
absl::SimpleAtoi
ABSL_NAMESPACE_BEGIN ABSL_MUST_USE_RESULT bool SimpleAtoi(absl::string_view str, int_type *out)
Definition: abseil-cpp/absl/strings/numbers.h:271
grpc_core::StringMatcher::type
Type type() const
Definition: matchers/matchers.h:59
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
grpc_core::HeaderMatcher::range_start_
int64_t range_start_
Definition: matchers/matchers.h:154
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
Type
Definition: bloaty/third_party/protobuf/src/google/protobuf/type.pb.h:182
grpc_core::StringMatcher::ToString
std::string ToString() const
Definition: matchers/matchers.cc:131
grpc_core::StringMatcher::regex_matcher_
std::unique_ptr< RE2 > regex_matcher_
Definition: matchers/matchers.h:75
matchers.h
absl::optional< absl::string_view >
absl::EqualsIgnoreCase
ABSL_NAMESPACE_BEGIN bool EqualsIgnoreCase(absl::string_view piece1, absl::string_view piece2) noexcept
Definition: abseil-cpp/absl/strings/match.cc:22
grpc_core::StringMatcher::Type
Type
Definition: matchers/matchers.h:34
absl::StrContains
ABSL_NAMESPACE_BEGIN bool StrContains(absl::string_view haystack, absl::string_view needle) noexcept
Definition: third_party/abseil-cpp/absl/strings/match.h:46
grpc_core::HeaderMatcher::matcher_
StringMatcher matcher_
Definition: matchers/matchers.h:153
grpc_core::StringMatcher::Match
bool Match(absl::string_view value) const
Definition: matchers/matchers.cc:107
grpc_core::HeaderMatcher::Type::kPrefix
@ kPrefix
grpc_core::StringMatcher
Definition: matchers/matchers.h:32
value
const char * value
Definition: hpack_parser_table.cc:165
absl::EndsWithIgnoreCase
bool EndsWithIgnoreCase(absl::string_view text, absl::string_view suffix) noexcept
Definition: abseil-cpp/absl/strings/match.cc:36
grpc_core::HeaderMatcher::ToString
std::string ToString() const
Definition: matchers/matchers.cc:308
grpc_core::HeaderMatcher::invert_match_
bool invert_match_
Definition: matchers/matchers.h:157
grpc_core::HeaderMatcher::Type::kSafeRegex
@ kSafeRegex
grpc_core::HeaderMatcher::string_matcher
const std::string & string_matcher() const
Definition: matchers/matchers.h:130
grpc_core::HeaderMatcher::Create
static absl::StatusOr< HeaderMatcher > Create(absl::string_view name, Type type, absl::string_view matcher, int64_t range_start=0, int64_t range_end=0, bool present_match=false, bool invert_match=false)
Definition: matchers/matchers.cc:157
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
grpc_core::StringMatcher::operator=
StringMatcher & operator=(const StringMatcher &other)
Definition: matchers/matchers.cc:65
grpc_core::StringMatcher::Type::kExact
@ kExact
grpc_core::StringMatcher::Type::kSafeRegex
@ kSafeRegex
grpc_core::HeaderMatcher::name
const std::string & name() const
Definition: matchers/matchers.h:125
grpc_core::HeaderMatcher::name_
std::string name_
Definition: matchers/matchers.h:151
grpc_core::HeaderMatcher::Type::kRange
@ kRange
absl::StatusOr
Definition: abseil-cpp/absl/status/statusor.h:187
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
grpc_core::StringMatcher::Type::kContains
@ kContains
grpc_core::StringMatcher::case_sensitive
bool case_sensitive() const
Definition: matchers/matchers.h:67
grpc_core::StringMatcher::Type::kPrefix
@ kPrefix
grpc_core::StringMatcher::type_
Type type_
Definition: matchers/matchers.h:73
grpc_core::HeaderMatcher::present_match_
bool present_match_
Definition: matchers/matchers.h:156
grpc_core::StringMatcher::string_matcher_
std::string string_matcher_
Definition: matchers/matchers.h:74
grpc_core::HeaderMatcher::HeaderMatcher
HeaderMatcher()=default
absl::EndsWith
bool EndsWith(absl::string_view text, absl::string_view suffix) noexcept
Definition: third_party/abseil-cpp/absl/strings/match.h:68
grpc_core::StringMatcher::regex_matcher
RE2 * regex_matcher() const
Definition: matchers/matchers.h:65
grpc_core::HeaderMatcher::operator=
HeaderMatcher & operator=(const HeaderMatcher &other)
Definition: matchers/matchers.cc:222
port_platform.h


grpc
Author(s):
autogenerated on Fri May 16 2025 02:59:22