1
#pragma once
2

            
3
#include "envoy/extensions/matching/http/dynamic_modules/v3/dynamic_modules.pb.h"
4
#include "envoy/extensions/matching/http/dynamic_modules/v3/dynamic_modules.pb.validate.h"
5
#include "envoy/http/filter.h"
6
#include "envoy/matcher/matcher.h"
7

            
8
namespace Envoy {
9
namespace Extensions {
10
namespace Matching {
11
namespace Http {
12
namespace DynamicModules {
13

            
14
/**
15
 * Dynamic module matcher specific matching data. This wraps the HTTP matching context
16
 * (request/response headers and trailers) so that the dynamic module can access them
17
 * via ABI callbacks during match evaluation.
18
 */
19
class DynamicModuleMatchData : public ::Envoy::Matcher::CustomMatchData {
20
public:
21
  const ::Envoy::Http::RequestHeaderMap* request_headers_{};
22
  const ::Envoy::Http::ResponseHeaderMap* response_headers_{};
23
  const ::Envoy::Http::ResponseTrailerMap* response_trailers_{};
24
};
25

            
26
/**
27
 * Data input that extracts HTTP request and response data from the matching context
28
 * and wraps it as DynamicModuleMatchData for consumption by the dynamic module matcher.
29
 */
30
class HttpDynamicModuleDataInput
31
    : public ::Envoy::Matcher::DataInput<::Envoy::Http::HttpMatchingData> {
32
public:
33
8
  HttpDynamicModuleDataInput() = default;
34

            
35
  ::Envoy::Matcher::DataInputGetResult
36
6
  get(const ::Envoy::Http::HttpMatchingData& data) const override {
37
6
    auto match_data = std::make_shared<DynamicModuleMatchData>();
38
6
    match_data->request_headers_ = data.requestHeaders().ptr();
39
6
    match_data->response_headers_ = data.responseHeaders().ptr();
40
6
    match_data->response_trailers_ = data.responseTrailers().ptr();
41
6
    return ::Envoy::Matcher::DataInputGetResult::CreateCustom(std::move(match_data));
42
6
  }
43

            
44
5
  absl::string_view dataInputType() const override { return "dynamic_module_data_input"; }
45
};
46

            
47
class HttpDynamicModuleDataInputFactory
48
    : public ::Envoy::Matcher::DataInputFactory<::Envoy::Http::HttpMatchingData> {
49
public:
50
11
  HttpDynamicModuleDataInputFactory() = default;
51
13
  std::string name() const override { return "envoy.matching.inputs.dynamic_module_data_input"; }
52

            
53
  ::Envoy::Matcher::DataInputFactoryCb<::Envoy::Http::HttpMatchingData>
54
4
  createDataInputFactoryCb(const Protobuf::Message&, ProtobufMessage::ValidationVisitor&) override {
55
4
    return [] { return std::make_unique<HttpDynamicModuleDataInput>(); };
56
4
  }
57

            
58
6
  ProtobufTypes::MessagePtr createEmptyConfigProto() override {
59
6
    return std::make_unique<
60
6
        envoy::extensions::matching::http::dynamic_modules::v3::HttpDynamicModuleMatchInput>();
61
6
  }
62
};
63

            
64
DECLARE_FACTORY(HttpDynamicModuleDataInputFactory);
65

            
66
} // namespace DynamicModules
67
} // namespace Http
68
} // namespace Matching
69
} // namespace Extensions
70
} // namespace Envoy