Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/matcher/matcher.h" 4 : #include "envoy/server/factory_context.h" 5 : #include "envoy/type/matcher/v3/status_code_input.pb.h" 6 : #include "envoy/type/matcher/v3/status_code_input.pb.validate.h" 7 : 8 : #include "source/common/http/header_utility.h" 9 : #include "source/common/http/utility.h" 10 : 11 : namespace Envoy { 12 : namespace Http { 13 : namespace Matching { 14 : 15 : class HttpResponseStatusCodeInput : public Matcher::DataInput<HttpMatchingData> { 16 : public: 17 0 : HttpResponseStatusCodeInput() = default; 18 0 : ~HttpResponseStatusCodeInput() override = default; 19 : 20 0 : Matcher::DataInputGetResult get(const HttpMatchingData& data) const override { 21 0 : const auto maybe_headers = data.responseHeaders(); 22 : 23 0 : if (!maybe_headers) { 24 0 : return {Matcher::DataInputGetResult::DataAvailability::NotAvailable, absl::monostate()}; 25 0 : } 26 0 : const auto maybe_status = Http::Utility::getResponseStatusOrNullopt(*maybe_headers); 27 : 28 0 : if (maybe_status.has_value()) { 29 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, 30 0 : absl::StrCat(*maybe_status)}; 31 0 : } 32 : 33 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()}; 34 0 : } 35 : }; 36 : 37 : class HttpResponseStatusCodeClassInput : public Matcher::DataInput<HttpMatchingData> { 38 : public: 39 0 : HttpResponseStatusCodeClassInput() = default; 40 0 : ~HttpResponseStatusCodeClassInput() override = default; 41 : 42 0 : Matcher::DataInputGetResult get(const HttpMatchingData& data) const override { 43 0 : const auto maybe_headers = data.responseHeaders(); 44 0 : if (!maybe_headers) { 45 0 : return {Matcher::DataInputGetResult::DataAvailability::NotAvailable, absl::monostate()}; 46 0 : } 47 : 48 0 : const auto maybe_status = Http::Utility::getResponseStatusOrNullopt(*maybe_headers); 49 0 : if (maybe_status.has_value()) { 50 0 : if (*maybe_status >= 100 && *maybe_status < 200) { 51 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, "1xx"}; 52 0 : } 53 0 : if (*maybe_status >= 200 && *maybe_status < 300) { 54 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, "2xx"}; 55 0 : } 56 0 : if (*maybe_status >= 300 && *maybe_status < 400) { 57 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, "3xx"}; 58 0 : } 59 0 : if (*maybe_status >= 400 && *maybe_status < 500) { 60 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, "4xx"}; 61 0 : } 62 0 : if (*maybe_status >= 500 && *maybe_status < 600) { 63 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, "5xx"}; 64 0 : } 65 0 : } 66 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()}; 67 0 : } 68 : }; 69 : 70 : template <class DataInputType, class ProtoType> 71 : class HttpResponseStatusCodeInputFactoryBase : public Matcher::DataInputFactory<HttpMatchingData> { 72 : public: 73 : explicit HttpResponseStatusCodeInputFactoryBase(const std::string& name) 74 6 : : name_("envoy.matching.inputs." + name) {} 75 : 76 78 : std::string name() const override { return name_; } 77 : 78 : Matcher::DataInputFactoryCb<HttpMatchingData> 79 0 : createDataInputFactoryCb(const Protobuf::Message&, ProtobufMessage::ValidationVisitor&) override { 80 : 81 0 : return [] { return std::make_unique<DataInputType>(); }; 82 0 : }; 83 2 : ProtobufTypes::MessagePtr createEmptyConfigProto() override { 84 2 : return std::make_unique<ProtoType>(); 85 2 : } 86 : 87 : private: 88 : const std::string name_; 89 : }; 90 : 91 : class HttpResponseStatusCodeInputFactory 92 : : public HttpResponseStatusCodeInputFactoryBase< 93 : HttpResponseStatusCodeInput, envoy::type::matcher::v3::HttpResponseStatusCodeMatchInput> { 94 : public: 95 : explicit HttpResponseStatusCodeInputFactory() 96 3 : : HttpResponseStatusCodeInputFactoryBase("status_code_input") {} 97 : }; 98 : 99 : class HttpResponseStatusCodeClassInputFactory 100 : : public HttpResponseStatusCodeInputFactoryBase< 101 : HttpResponseStatusCodeClassInput, 102 : envoy::type::matcher::v3::HttpResponseStatusCodeClassMatchInput> { 103 : public: 104 : explicit HttpResponseStatusCodeClassInputFactory() 105 3 : : HttpResponseStatusCodeInputFactoryBase("status_code_class_input") {} 106 : }; 107 : 108 : } // namespace Matching 109 : } // namespace Http 110 : } // namespace Envoy