Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/common/http/match_delegate/config.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <memory>
4
5
#include "envoy/extensions/common/matching/v3/extension_matcher.pb.validate.h"
6
#include "envoy/extensions/filters/common/matcher/action/v3/skip_action.pb.h"
7
#include "envoy/matcher/matcher.h"
8
#include "envoy/server/filter_config.h"
9
10
#include "source/common/http/matching/data_impl.h"
11
#include "source/common/matcher/matcher.h"
12
#include "source/extensions/filters/http/common/factory_base.h"
13
14
namespace Envoy {
15
namespace Common {
16
namespace Http {
17
namespace MatchDelegate {
18
19
class SkipAction : public Matcher::ActionBase<
20
                       envoy::extensions::filters::common::matcher::action::v3::SkipFilter> {};
21
22
class DelegatingStreamFilter : public Logger::Loggable<Logger::Id::http>,
23
                               public Envoy::Http::StreamFilter {
24
public:
25
  using MatchDataUpdateFunc = std::function<void(Envoy::Http::Matching::HttpMatchingDataImpl&)>;
26
27
  class FilterMatchState {
28
  public:
29
    FilterMatchState(Matcher::MatchTreeSharedPtr<Envoy::Http::HttpMatchingData> match_tree)
30
498
        : match_tree_(std::move(match_tree)), has_match_tree_(match_tree_ != nullptr) {}
31
32
    void evaluateMatchTree(MatchDataUpdateFunc data_update_func);
33
2.07k
    bool skipFilter() const { return skip_filter_; }
34
892
    void onStreamInfo(const StreamInfo::StreamInfo& stream_info) {
35
892
      if (matching_data_ == nullptr) {
36
498
        matching_data_ = std::make_shared<Envoy::Http::Matching::HttpMatchingDataImpl>(stream_info);
37
498
      }
38
892
    }
39
40
    // The matcher from the per route config, if available, will override the matcher from the
41
    // filter config.
42
0
    void setMatchTree(Matcher::MatchTreeSharedPtr<Envoy::Http::HttpMatchingData> match_tree) {
43
0
      match_tree_ = std::move(match_tree);
44
0
      has_match_tree_ = match_tree_ != nullptr;
45
0
    }
46
47
498
    void setBaseFilter(Envoy::Http::StreamFilterBase* base_filter) { base_filter_ = base_filter; }
48
49
  private:
50
    Matcher::MatchTreeSharedPtr<Envoy::Http::HttpMatchingData> match_tree_;
51
    bool has_match_tree_{};
52
    Envoy::Http::StreamFilterBase* base_filter_{};
53
54
    Envoy::Http::Matching::HttpMatchingDataImplSharedPtr matching_data_;
55
    bool match_tree_evaluated_{};
56
    bool skip_filter_{};
57
  };
58
59
  DelegatingStreamFilter(Matcher::MatchTreeSharedPtr<Envoy::Http::HttpMatchingData> match_tree,
60
                         Envoy::Http::StreamDecoderFilterSharedPtr decoder_filter,
61
                         Envoy::Http::StreamEncoderFilterSharedPtr encoder_filter);
62
63
  // Envoy::Http::StreamFilterBase
64
0
  void onStreamComplete() override { base_filter_->onStreamComplete(); }
65
892
  void onDestroy() override { base_filter_->onDestroy(); }
66
0
  void onMatchCallback(const Matcher::Action& action) override {
67
0
    base_filter_->onMatchCallback(action);
68
0
  }
69
0
  Envoy::Http::LocalErrorStatus onLocalReply(const LocalReplyData& data) override {
70
0
    return base_filter_->onLocalReply(data);
71
0
  }
72
73
  // Envoy::Http::StreamDecoderFilter
74
  Envoy::Http::FilterHeadersStatus decodeHeaders(Envoy::Http::RequestHeaderMap& headers,
75
                                                 bool end_stream) override;
76
  Envoy::Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override;
77
  Envoy::Http::FilterTrailersStatus
78
  decodeTrailers(Envoy::Http::RequestTrailerMap& trailers) override;
79
80
  Envoy::Http::FilterMetadataStatus decodeMetadata(Envoy::Http::MetadataMap& metadata_map) override;
81
  void decodeComplete() override;
82
  void setDecoderFilterCallbacks(Envoy::Http::StreamDecoderFilterCallbacks& callbacks) override;
83
84
  // Envoy::Http::StreamEncoderFilter
85
  Envoy::Http::Filter1xxHeadersStatus
86
  encode1xxHeaders(Envoy::Http::ResponseHeaderMap& headers) override;
87
  Envoy::Http::FilterHeadersStatus encodeHeaders(Envoy::Http::ResponseHeaderMap& headers,
88
                                                 bool end_stream) override;
89
  Envoy::Http::FilterDataStatus encodeData(Buffer::Instance& data, bool end_stream) override;
90
  Envoy::Http::FilterTrailersStatus
91
  encodeTrailers(Envoy::Http::ResponseTrailerMap& trailers) override;
92
  Envoy::Http::FilterMetadataStatus encodeMetadata(Envoy::Http::MetadataMap& metadata_map) override;
93
  void encodeComplete() override;
94
  void setEncoderFilterCallbacks(Envoy::Http::StreamEncoderFilterCallbacks& callbacks) override;
95
96
private:
97
  FilterMatchState match_state_;
98
99
  Envoy::Http::StreamDecoderFilterSharedPtr decoder_filter_;
100
  Envoy::Http::StreamEncoderFilterSharedPtr encoder_filter_;
101
  Envoy::Http::StreamDecoderFilterCallbacks* decoder_callbacks_{};
102
  Envoy::Http::StreamEncoderFilterCallbacks* encoder_callbacks_{};
103
  Envoy::Http::StreamFilterBase* base_filter_{};
104
};
105
106
class MatchDelegateConfig
107
    : public Extensions::HttpFilters::Common::FactoryBase<
108
          envoy::extensions::common::matching::v3::ExtensionWithMatcher,
109
          envoy::extensions::common::matching::v3::ExtensionWithMatcherPerRoute> {
110
public:
111
  // TODO(wbpcode): move this filter to 'source/extensions/filters/http'.
112
110
  MatchDelegateConfig() : FactoryBase("envoy.filters.http.match_delegate") {}
113
114
private:
115
  Envoy::Http::FilterFactoryCb createFilterFactoryFromProtoTyped(
116
      const envoy::extensions::common::matching::v3::ExtensionWithMatcher& proto_config,
117
      const std::string&, Server::Configuration::FactoryContext& context) override;
118
119
  Router::RouteSpecificFilterConfigConstSharedPtr createRouteSpecificFilterConfigTyped(
120
      const envoy::extensions::common::matching::v3::ExtensionWithMatcherPerRoute& proto_config,
121
      Server::Configuration::ServerFactoryContext& context,
122
      ProtobufMessage::ValidationVisitor& validation) override;
123
};
124
125
class FilterConfigPerRoute : public Router::RouteSpecificFilterConfig {
126
public:
127
  FilterConfigPerRoute(
128
      const envoy::extensions::common::matching::v3::ExtensionWithMatcherPerRoute& proto_config,
129
      Server::Configuration::ServerFactoryContext& server_context)
130
871
      : match_tree_(createFilterMatchTree(proto_config, server_context)) {}
131
132
0
  const Matcher::MatchTreeSharedPtr<Envoy::Http::HttpMatchingData>& matchTree() const {
133
0
    return match_tree_;
134
0
  }
135
136
private:
137
  Matcher::MatchTreeSharedPtr<Envoy::Http::HttpMatchingData> createFilterMatchTree(
138
      const envoy::extensions::common::matching::v3::ExtensionWithMatcherPerRoute& proto_config,
139
      Server::Configuration::ServerFactoryContext& server_context);
140
  Matcher::MatchTreeSharedPtr<Envoy::Http::HttpMatchingData> match_tree_;
141
};
142
143
DECLARE_FACTORY(MatchDelegateConfig);
144
145
namespace Factory {
146
DECLARE_FACTORY(SkipActionFactory);
147
} // namespace Factory
148
149
} // namespace MatchDelegate
150
} // namespace Http
151
} // namespace Common
152
} // namespace Envoy