1
#include "sdk.h"
2

            
3
#include <format>
4
#include <iostream>
5
#include <string_view>
6

            
7
namespace Envoy {
8
namespace DynamicModules {
9

            
10
HttpFilterConfigFactory::~HttpFilterConfigFactory() = default;
11

            
12
HttpFilterFactory::~HttpFilterFactory() = default;
13

            
14
HttpFilter::~HttpFilter() = default;
15

            
16
BodyBuffer::~BodyBuffer() = default;
17

            
18
HeaderMap::~HeaderMap() = default;
19

            
20
HttpCalloutCallback::~HttpCalloutCallback() = default;
21

            
22
HttpStreamCallback::~HttpStreamCallback() = default;
23

            
24
RouteSpecificConfig::~RouteSpecificConfig() = default;
25

            
26
Scheduler::~Scheduler() = default;
27

            
28
DownstreamWatermarkCallbacks::~DownstreamWatermarkCallbacks() = default;
29

            
30
HttpFilterHandle::~HttpFilterHandle() = default;
31

            
32
HttpFilterConfigHandle::~HttpFilterConfigHandle() = default;
33

            
34
namespace Utility {
35

            
36
std::string getBodyContent(BodyBuffer& buffered, BodyBuffer& received, bool is_buffered) {
37
  const size_t total_size = buffered.getSize() + (is_buffered ? 0 : received.getSize());
38
  std::string result;
39
  result.reserve(total_size);
40
  for (const auto& chunk : buffered.getChunks()) {
41
    result.append(chunk.data(), chunk.size());
42
  }
43

            
44
  // If the received body is the same as the buffered body (a previous filter did StopAndBuffer
45
  // and resumed), skip the received body to avoid duplicating data.
46
  if (is_buffered) {
47
    return result;
48
  }
49

            
50
  for (const auto& chunk : received.getChunks()) {
51
    result.append(chunk.data(), chunk.size());
52
  }
53
  return result;
54
}
55

            
56
std::string readWholeRequestBody(HttpFilterHandle& handle) {
57
  return getBodyContent(handle.bufferedRequestBody(), handle.receivedRequestBody(),
58
                        handle.receivedBufferedRequestBody());
59
}
60

            
61
std::string readWholeResponseBody(HttpFilterHandle& handle) {
62
  return getBodyContent(handle.bufferedResponseBody(), handle.receivedResponseBody(),
63
                        handle.receivedBufferedResponseBody());
64
}
65
} // namespace Utility
66

            
67
HttpFilterConfigFactoryRegister::HttpFilterConfigFactoryRegister(std::string_view name,
68
                                                                 HttpFilterConfigFactoryPtr factory)
69
    : name_(name) {
70
  // The register will have longer lifetime than the related factory entry in the registry,
71
  // so it's safe to store the name as string_view in the registry.
72
  auto r = HttpFilterConfigFactoryRegistry::getMutableRegistry().emplace(std::string_view(name_),
73
                                                                         std::move(factory));
74
  if (!r.second) {
75
    std::string error_msg = std::format("Factory with the same name {} already registered", name_);
76
    std::cerr << error_msg << std::endl;
77
    assert((void("Duplicate factory registration"), r.second));
78
  }
79
}
80

            
81
HttpFilterConfigFactoryRegister::~HttpFilterConfigFactoryRegister() {
82
  HttpFilterConfigFactoryRegistry::getMutableRegistry().erase(name_);
83
}
84

            
85
std::map<std::string_view, HttpFilterConfigFactoryPtr>&
86
HttpFilterConfigFactoryRegistry::getMutableRegistry() {
87
  static std::map<std::string_view, HttpFilterConfigFactoryPtr> registry;
88
  return registry;
89
}
90

            
91
const std::map<std::string_view, HttpFilterConfigFactoryPtr>&
92
HttpFilterConfigFactoryRegistry::getRegistry() {
93
  return getMutableRegistry();
94
};
95

            
96
} // namespace DynamicModules
97
} // namespace Envoy