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