// Copyright 2021 gRPC authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef GRPC_CORE_LIB_MATCHERS_MATCHERS_H #define GRPC_CORE_LIB_MATCHERS_MATCHERS_H #include #include #include #include #include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "re2/re2.h" namespace grpc_core { class StringMatcher { public: enum class Type { kExact, // value stored in string_matcher_ field kPrefix, // value stored in string_matcher_ field kSuffix, // value stored in string_matcher_ field kSafeRegex, // pattern stored in regex_matcher_ field kContains, // value stored in string_matcher_ field }; // Creates StringMatcher instance. Returns error status on failure. // Note: case_sensitive is ignored for type kSafeRegex. static absl::StatusOr Create(Type type, absl::string_view matcher, bool case_sensitive = true); StringMatcher() = default; StringMatcher(const StringMatcher& other); StringMatcher& operator=(const StringMatcher& other); StringMatcher(StringMatcher&& other) noexcept; StringMatcher& operator=(StringMatcher&& other) noexcept; bool operator==(const StringMatcher& other) const; bool Match(absl::string_view value) const; std::string ToString() const; Type type() const { return type_; } // Valid for kExact, kPrefix, kSuffix and kContains. const std::string& string_matcher() const { return string_matcher_; } // Valid for kSafeRegex. RE2* regex_matcher() const { return regex_matcher_.get(); } bool case_sensitive() const { return case_sensitive_; } private: StringMatcher(Type type, absl::string_view matcher, bool case_sensitive); explicit StringMatcher(std::unique_ptr regex_matcher); Type type_ = Type::kExact; std::string string_matcher_; std::unique_ptr regex_matcher_; bool case_sensitive_ = true; }; class HeaderMatcher { public: enum class Type { kExact, // value stored in StringMatcher field kPrefix, // value stored in StringMatcher field kSuffix, // value stored in StringMatcher field kSafeRegex, // value stored in StringMatcher field kContains, // value stored in StringMatcher field kRange, // uses range_start and range_end fields kPresent, // uses present_match field }; // Make sure that the first five HeaderMatcher::Type enum values match up to // the corresponding StringMatcher::Type enum values, so that it's safe to // convert by casting when delegating to StringMatcher. static_assert(static_cast(Type::kExact) == StringMatcher::Type::kExact, ""); static_assert(static_cast(Type::kPrefix) == StringMatcher::Type::kPrefix, ""); static_assert(static_cast(Type::kSuffix) == StringMatcher::Type::kSuffix, ""); static_assert(static_cast(Type::kSafeRegex) == StringMatcher::Type::kSafeRegex, ""); static_assert(static_cast(Type::kContains) == StringMatcher::Type::kContains, ""); // Creates HeaderMatcher instance. Returns error status on failure. static absl::StatusOr 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); HeaderMatcher() = default; HeaderMatcher(const HeaderMatcher& other); HeaderMatcher& operator=(const HeaderMatcher& other); HeaderMatcher(HeaderMatcher&& other) noexcept; HeaderMatcher& operator=(HeaderMatcher&& other) noexcept; bool operator==(const HeaderMatcher& other) const; const std::string& name() const { return name_; } Type type() const { return type_; } // Valid for kExact, kPrefix, kSuffix and kContains. const std::string& string_matcher() const { return matcher_.string_matcher(); } // Valid for kSafeRegex. RE2* regex_matcher() const { return matcher_.regex_matcher(); } bool Match(const absl::optional& value) const; std::string ToString() const; private: // For StringMatcher. HeaderMatcher(absl::string_view name, Type type, StringMatcher matcher, bool invert_match); // For RangeMatcher. HeaderMatcher(absl::string_view name, int64_t range_start, int64_t range_end, bool invert_match); // For PresentMatcher. HeaderMatcher(absl::string_view name, bool present_match, bool invert_match); std::string name_; Type type_ = Type::kExact; StringMatcher matcher_; int64_t range_start_; int64_t range_end_; bool present_match_; bool invert_match_ = false; }; } // namespace grpc_core #endif /* GRPC_CORE_LIB_MATCHERS_MATCHERS_H */