1
#pragma once
2

            
3
#include <memory>
4

            
5
#include "envoy/matcher/matcher.h"
6

            
7
#include "source/common/common/logger.h"
8
#include "source/extensions/dynamic_modules/abi/abi.h"
9
#include "source/extensions/dynamic_modules/dynamic_modules.h"
10
#include "source/extensions/matching/http/dynamic_modules/data_input.h"
11

            
12
namespace Envoy {
13
namespace Extensions {
14
namespace Matching {
15
namespace InputMatchers {
16
namespace DynamicModules {
17

            
18
// Type aliases for function pointers resolved from the module.
19
using OnMatcherConfigNewType = decltype(&envoy_dynamic_module_on_matcher_config_new);
20
using OnMatcherConfigDestroyType = decltype(&envoy_dynamic_module_on_matcher_config_destroy);
21
using OnMatcherMatchType = decltype(&envoy_dynamic_module_on_matcher_match);
22

            
23
// Shared ownership of the dynamic module to keep it loaded while any matcher references it.
24
using DynamicModuleSharedPtr = std::shared_ptr<Extensions::DynamicModules::DynamicModule>;
25

            
26
/**
27
 * Context passed to the dynamic module during a match evaluation. The matcher_input_envoy_ptr
28
 * points to this struct, and the module accesses the matching data via ABI callbacks.
29
 *
30
 * This struct is only valid during the envoy_dynamic_module_on_matcher_match callback.
31
 */
32
struct MatchContext {
33
  const ::Envoy::Http::RequestHeaderMap* request_headers{};
34
  const ::Envoy::Http::ResponseHeaderMap* response_headers{};
35
  const ::Envoy::Http::ResponseTrailerMap* response_trailers{};
36
};
37

            
38
/**
39
 * InputMatcher implementation that delegates matching logic to a dynamic module.
40
 * The module is loaded and configured during construction, and match() calls the
41
 * module's event hook on each evaluation.
42
 */
43
class DynamicModuleInputMatcher : public ::Envoy::Matcher::InputMatcher,
44
                                  public Logger::Loggable<Logger::Id::matcher> {
45
public:
46
  DynamicModuleInputMatcher(DynamicModuleSharedPtr module,
47
                            OnMatcherConfigDestroyType on_config_destroy,
48
                            OnMatcherMatchType on_match,
49
                            envoy_dynamic_module_type_matcher_config_module_ptr in_module_config);
50

            
51
  ~DynamicModuleInputMatcher() override;
52

            
53
  ::Envoy::Matcher::MatchResult match(const ::Envoy::Matcher::DataInputGetResult& input) override;
54

            
55
5
  bool supportsDataInputType(absl::string_view data_type) const override {
56
5
    return data_type == "dynamic_module_data_input";
57
5
  }
58

            
59
private:
60
  // Prevent copy/move.
61
  DynamicModuleInputMatcher(const DynamicModuleInputMatcher&) = delete;
62
  DynamicModuleInputMatcher& operator=(const DynamicModuleInputMatcher&) = delete;
63

            
64
  DynamicModuleSharedPtr module_;
65
  OnMatcherConfigDestroyType on_config_destroy_;
66
  OnMatcherMatchType on_match_;
67
  envoy_dynamic_module_type_matcher_config_module_ptr in_module_config_;
68
};
69

            
70
} // namespace DynamicModules
71
} // namespace InputMatchers
72
} // namespace Matching
73
} // namespace Extensions
74
} // namespace Envoy