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