• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 #ifndef GRPC_SRC_CORE_LIB_MATCHERS_MATCHERS_H
16 #define GRPC_SRC_CORE_LIB_MATCHERS_MATCHERS_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <stdint.h>
21 
22 #include <memory>
23 #include <string>
24 
25 #include "absl/status/statusor.h"
26 #include "absl/strings/string_view.h"
27 #include "absl/types/optional.h"
28 #include "re2/re2.h"
29 
30 namespace grpc_core {
31 
32 class StringMatcher {
33  public:
34   enum class Type {
35     kExact,      // value stored in string_matcher_ field
36     kPrefix,     // value stored in string_matcher_ field
37     kSuffix,     // value stored in string_matcher_ field
38     kSafeRegex,  // pattern stored in regex_matcher_ field
39     kContains,   // value stored in string_matcher_ field
40   };
41 
42   // Creates StringMatcher instance. Returns error status on failure.
43   // Note: case_sensitive is ignored for type kSafeRegex.
44   static absl::StatusOr<StringMatcher> Create(Type type,
45                                               absl::string_view matcher,
46                                               bool case_sensitive = true);
47 
48   StringMatcher() = default;
49   StringMatcher(const StringMatcher& other);
50   StringMatcher& operator=(const StringMatcher& other);
51   StringMatcher(StringMatcher&& other) noexcept;
52   StringMatcher& operator=(StringMatcher&& other) noexcept;
53   bool operator==(const StringMatcher& other) const;
54 
55   bool Match(absl::string_view value) const;
56 
57   std::string ToString() const;
58 
type()59   Type type() const { return type_; }
60 
61   // Valid for kExact, kPrefix, kSuffix and kContains.
string_matcher()62   const std::string& string_matcher() const { return string_matcher_; }
63 
64   // Valid for kSafeRegex.
regex_matcher()65   RE2* regex_matcher() const { return regex_matcher_.get(); }
66 
case_sensitive()67   bool case_sensitive() const { return case_sensitive_; }
68 
69  private:
70   StringMatcher(Type type, absl::string_view matcher, bool case_sensitive);
71   explicit StringMatcher(std::unique_ptr<RE2> regex_matcher);
72 
73   Type type_ = Type::kExact;
74   std::string string_matcher_;
75   std::unique_ptr<RE2> regex_matcher_;
76   bool case_sensitive_ = true;
77 };
78 
79 class HeaderMatcher {
80  public:
81   enum class Type {
82     kExact,      // value stored in StringMatcher field
83     kPrefix,     // value stored in StringMatcher field
84     kSuffix,     // value stored in StringMatcher field
85     kSafeRegex,  // value stored in StringMatcher field
86     kContains,   // value stored in StringMatcher field
87     kRange,      // uses range_start and range_end fields
88     kPresent,    // uses present_match field
89   };
90 
91   // Make sure that the first five HeaderMatcher::Type enum values match up to
92   // the corresponding StringMatcher::Type enum values, so that it's safe to
93   // convert by casting when delegating to StringMatcher.
94   static_assert(static_cast<StringMatcher::Type>(Type::kExact) ==
95                     StringMatcher::Type::kExact,
96                 "");
97   static_assert(static_cast<StringMatcher::Type>(Type::kPrefix) ==
98                     StringMatcher::Type::kPrefix,
99                 "");
100   static_assert(static_cast<StringMatcher::Type>(Type::kSuffix) ==
101                     StringMatcher::Type::kSuffix,
102                 "");
103   static_assert(static_cast<StringMatcher::Type>(Type::kSafeRegex) ==
104                     StringMatcher::Type::kSafeRegex,
105                 "");
106   static_assert(static_cast<StringMatcher::Type>(Type::kContains) ==
107                     StringMatcher::Type::kContains,
108                 "");
109 
110   // Creates HeaderMatcher instance. Returns error status on failure.
111   static absl::StatusOr<HeaderMatcher> Create(absl::string_view name, Type type,
112                                               absl::string_view matcher,
113                                               int64_t range_start = 0,
114                                               int64_t range_end = 0,
115                                               bool present_match = false,
116                                               bool invert_match = false,
117                                               bool case_sensitive = true);
118 
119   HeaderMatcher() = default;
120   HeaderMatcher(const HeaderMatcher& other);
121   HeaderMatcher& operator=(const HeaderMatcher& other);
122   HeaderMatcher(HeaderMatcher&& other) noexcept;
123   HeaderMatcher& operator=(HeaderMatcher&& other) noexcept;
124   bool operator==(const HeaderMatcher& other) const;
125 
name()126   const std::string& name() const { return name_; }
127 
type()128   Type type() const { return type_; }
129 
130   // Valid for kExact, kPrefix, kSuffix and kContains.
string_matcher()131   const std::string& string_matcher() const {
132     return matcher_.string_matcher();
133   }
134 
135   // Valid for kSafeRegex.
regex_matcher()136   RE2* regex_matcher() const { return matcher_.regex_matcher(); }
137 
138   bool Match(const absl::optional<absl::string_view>& value) const;
139 
140   std::string ToString() const;
141 
142  private:
143   // For StringMatcher.
144   HeaderMatcher(absl::string_view name, Type type, StringMatcher matcher,
145                 bool invert_match);
146   // For RangeMatcher.
147   HeaderMatcher(absl::string_view name, int64_t range_start, int64_t range_end,
148                 bool invert_match);
149   // For PresentMatcher.
150   HeaderMatcher(absl::string_view name, bool present_match, bool invert_match);
151 
152   std::string name_;
153   Type type_ = Type::kExact;
154   StringMatcher matcher_;
155   int64_t range_start_;
156   int64_t range_end_;
157   bool present_match_;
158   bool invert_match_ = false;
159 };
160 
161 }  // namespace grpc_core
162 
163 #endif  // GRPC_SRC_CORE_LIB_MATCHERS_MATCHERS_H
164