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