LCOV - code coverage report
Current view: top level - source/common/http/matching - inputs.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 13 76 17.1 %
Date: 2024-01-05 06:35:25 Functions: 18 46 39.1 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "envoy/http/filter.h"
       4             : #include "envoy/matcher/matcher.h"
       5             : #include "envoy/server/factory_context.h"
       6             : #include "envoy/type/matcher/v3/http_inputs.pb.h"
       7             : #include "envoy/type/matcher/v3/http_inputs.pb.validate.h"
       8             : 
       9             : #include "source/common/http/header_utility.h"
      10             : #include "source/common/http/utility.h"
      11             : 
      12             : namespace Envoy {
      13             : namespace Http {
      14             : namespace Matching {
      15             : /**
      16             :  * Common base class for all the header/trailer DataInputs.
      17             :  */
      18             : template <class HeaderType>
      19             : class HttpHeadersDataInputBase : public Matcher::DataInput<HttpMatchingData> {
      20             : public:
      21           0 :   explicit HttpHeadersDataInputBase(const std::string& name) : name_(name) {}
      22             : 
      23             :   virtual OptRef<const HeaderType> headerMap(const HttpMatchingData& data) const PURE;
      24             : 
      25           0 :   Matcher::DataInputGetResult get(const HttpMatchingData& data) const override {
      26           0 :     const OptRef<const HeaderType> maybe_headers = headerMap(data);
      27             : 
      28           0 :     if (!maybe_headers) {
      29           0 :       return {Matcher::DataInputGetResult::DataAvailability::NotAvailable, absl::monostate()};
      30           0 :     }
      31             : 
      32           0 :     auto header_string = HeaderUtility::getAllOfHeaderAsString(*maybe_headers, name_, ",");
      33             : 
      34           0 :     if (header_string.result()) {
      35           0 :       return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable,
      36           0 :               std::string(header_string.result().value())};
      37           0 :     }
      38             : 
      39           0 :     return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()};
      40           0 :   }
      41             : 
      42             : private:
      43             :   const LowerCaseString name_;
      44             : };
      45             : 
      46             : /**
      47             :  * Common base class for all the header/trailer DataInputsFactory.
      48             :  */
      49             : template <class DataInputType, class ProtoType>
      50             : class HttpHeadersDataInputFactoryBase : public Matcher::DataInputFactory<HttpMatchingData> {
      51             : public:
      52         224 :   explicit HttpHeadersDataInputFactoryBase(const std::string& name) : name_(name) {}
      53             : 
      54         760 :   std::string name() const override { return "envoy.matching.inputs." + name_; }
      55             : 
      56             :   Matcher::DataInputFactoryCb<HttpMatchingData>
      57             :   createDataInputFactoryCb(const Protobuf::Message& config,
      58           0 :                            ProtobufMessage::ValidationVisitor& validation_visitor) override {
      59           0 :     const auto& typed_config =
      60           0 :         MessageUtil::downcastAndValidate<const ProtoType&>(config, validation_visitor);
      61             : 
      62           0 :     return [header_name = typed_config.header_name()] {
      63           0 :       return std::make_unique<DataInputType>(header_name);
      64           0 :     };
      65           0 :   };
      66          48 :   ProtobufTypes::MessagePtr createEmptyConfigProto() override {
      67          48 :     return std::make_unique<ProtoType>();
      68          48 :   }
      69             : 
      70             : private:
      71             :   const std::string name_;
      72             : };
      73             : 
      74             : class HttpRequestHeadersDataInput : public HttpHeadersDataInputBase<RequestHeaderMap> {
      75             : public:
      76           0 :   explicit HttpRequestHeadersDataInput(const std::string& name) : HttpHeadersDataInputBase(name) {}
      77             : 
      78           0 :   OptRef<const RequestHeaderMap> headerMap(const HttpMatchingData& data) const override {
      79           0 :     return data.requestHeaders();
      80           0 :   }
      81             : };
      82             : 
      83             : class HttpRequestHeadersDataInputFactory
      84             :     : public HttpHeadersDataInputFactoryBase<
      85             :           HttpRequestHeadersDataInput, envoy::type::matcher::v3::HttpRequestHeaderMatchInput> {
      86             : public:
      87          56 :   HttpRequestHeadersDataInputFactory() : HttpHeadersDataInputFactoryBase("request_headers") {}
      88             : };
      89             : 
      90             : DECLARE_FACTORY(HttpRequestHeadersDataInputFactory);
      91             : 
      92             : class HttpResponseHeadersDataInput : public HttpHeadersDataInputBase<ResponseHeaderMap> {
      93             : public:
      94           0 :   explicit HttpResponseHeadersDataInput(const std::string& name) : HttpHeadersDataInputBase(name) {}
      95             : 
      96           0 :   OptRef<const ResponseHeaderMap> headerMap(const HttpMatchingData& data) const override {
      97           0 :     return data.responseHeaders();
      98           0 :   }
      99             : };
     100             : 
     101             : class HttpResponseHeadersDataInputFactory
     102             :     : public HttpHeadersDataInputFactoryBase<
     103             :           HttpResponseHeadersDataInput, envoy::type::matcher::v3::HttpResponseHeaderMatchInput> {
     104             : public:
     105          56 :   HttpResponseHeadersDataInputFactory() : HttpHeadersDataInputFactoryBase("response_headers") {}
     106             : };
     107             : 
     108             : DECLARE_FACTORY(HttpResponseHeadersDataInputFactory);
     109             : 
     110             : class HttpRequestTrailersDataInput : public HttpHeadersDataInputBase<RequestTrailerMap> {
     111             : public:
     112           0 :   explicit HttpRequestTrailersDataInput(const std::string& name) : HttpHeadersDataInputBase(name) {}
     113             : 
     114           0 :   OptRef<const RequestTrailerMap> headerMap(const HttpMatchingData& data) const override {
     115           0 :     return data.requestTrailers();
     116           0 :   }
     117             : };
     118             : 
     119             : class HttpRequestTrailersDataInputFactory
     120             :     : public HttpHeadersDataInputFactoryBase<
     121             :           HttpRequestTrailersDataInput, envoy::type::matcher::v3::HttpRequestTrailerMatchInput> {
     122             : public:
     123          56 :   HttpRequestTrailersDataInputFactory() : HttpHeadersDataInputFactoryBase("request_trailers") {}
     124             : };
     125             : 
     126             : DECLARE_FACTORY(HttpRequestTrailersDataInputFactory);
     127             : 
     128             : class HttpResponseTrailersDataInput : public HttpHeadersDataInputBase<ResponseTrailerMap> {
     129             : public:
     130             :   explicit HttpResponseTrailersDataInput(const std::string& name)
     131           0 :       : HttpHeadersDataInputBase(name) {}
     132             : 
     133           0 :   OptRef<const ResponseTrailerMap> headerMap(const HttpMatchingData& data) const override {
     134           0 :     return data.responseTrailers();
     135           0 :   }
     136             : };
     137             : 
     138             : class HttpResponseTrailersDataInputFactory
     139             :     : public HttpHeadersDataInputFactoryBase<
     140             :           HttpResponseTrailersDataInput, envoy::type::matcher::v3::HttpResponseTrailerMatchInput> {
     141             : public:
     142          56 :   HttpResponseTrailersDataInputFactory() : HttpHeadersDataInputFactoryBase("response_trailers") {}
     143             : };
     144             : 
     145             : DECLARE_FACTORY(HttpResponseTrailersDataInputFactory);
     146             : 
     147             : class HttpRequestQueryParamsDataInput : public Matcher::DataInput<HttpMatchingData> {
     148             : public:
     149             :   explicit HttpRequestQueryParamsDataInput(const std::string& query_param)
     150           0 :       : query_param_(query_param) {}
     151             : 
     152           0 :   Matcher::DataInputGetResult get(const HttpMatchingData& data) const override {
     153           0 :     const auto maybe_headers = data.requestHeaders();
     154             : 
     155           0 :     if (!maybe_headers) {
     156           0 :       return {Matcher::DataInputGetResult::DataAvailability::NotAvailable, absl::monostate()};
     157           0 :     }
     158             : 
     159           0 :     const auto ret = maybe_headers->Path();
     160           0 :     if (!ret) {
     161           0 :       return {Matcher::DataInputGetResult::DataAvailability::NotAvailable, absl::monostate()};
     162           0 :     }
     163             : 
     164           0 :     auto params =
     165           0 :         Http::Utility::QueryParamsMulti::parseAndDecodeQueryString(ret->value().getStringView());
     166             : 
     167           0 :     auto ItParam = params.getFirstValue(query_param_);
     168           0 :     if (!ItParam.has_value()) {
     169           0 :       return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()};
     170           0 :     }
     171           0 :     return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable,
     172           0 :             std::move(ItParam.value())};
     173           0 :   }
     174             : 
     175             : private:
     176             :   const std::string query_param_;
     177             : };
     178             : 
     179             : class HttpRequestQueryParamsDataInputFactory : public Matcher::DataInputFactory<HttpMatchingData> {
     180             : public:
     181         190 :   std::string name() const override { return "query_params"; }
     182             : 
     183             :   Matcher::DataInputFactoryCb<HttpMatchingData>
     184             :   createDataInputFactoryCb(const Protobuf::Message& config,
     185           0 :                            ProtobufMessage::ValidationVisitor& validation_visitor) override {
     186           0 :     const auto& typed_config = MessageUtil::downcastAndValidate<
     187           0 :         const envoy::type::matcher::v3::HttpRequestQueryParamMatchInput&>(config,
     188           0 :                                                                           validation_visitor);
     189             : 
     190           0 :     return [query_param = typed_config.query_param()] {
     191           0 :       return std::make_unique<HttpRequestQueryParamsDataInput>(query_param);
     192           0 :     };
     193           0 :   };
     194          12 :   ProtobufTypes::MessagePtr createEmptyConfigProto() override {
     195          12 :     return std::make_unique<envoy::type::matcher::v3::HttpRequestQueryParamMatchInput>();
     196          12 :   }
     197             : };
     198             : 
     199             : DECLARE_FACTORY(HttpRequestQueryParamsDataInputFactory);
     200             : 
     201             : } // namespace Matching
     202             : } // namespace Http
     203             : } // namespace Envoy

Generated by: LCOV version 1.15