/proc/self/cwd/source/common/router/router_ratelimit.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <cstdint> |
4 | | #include <memory> |
5 | | #include <string> |
6 | | #include <vector> |
7 | | |
8 | | #include "envoy/config/core/v3/base.pb.h" |
9 | | #include "envoy/config/route/v3/route_components.pb.h" |
10 | | #include "envoy/ratelimit/ratelimit.h" |
11 | | #include "envoy/router/router.h" |
12 | | #include "envoy/router/router_ratelimit.h" |
13 | | |
14 | | #include "source/common/config/metadata.h" |
15 | | #include "source/common/http/header_utility.h" |
16 | | #include "source/common/network/cidr_range.h" |
17 | | #include "source/common/protobuf/utility.h" |
18 | | #include "source/common/router/config_utility.h" |
19 | | |
20 | | #include "absl/types/optional.h" |
21 | | |
22 | | namespace Envoy { |
23 | | namespace Router { |
24 | | |
25 | | /** |
26 | | * Populate rate limit override from dynamic metadata. |
27 | | */ |
28 | | class DynamicMetadataRateLimitOverride : public RateLimitOverrideAction { |
29 | | public: |
30 | | DynamicMetadataRateLimitOverride( |
31 | | const envoy::config::route::v3::RateLimit::Override::DynamicMetadata& config) |
32 | 858 | : metadata_key_(config.metadata_key()) {} |
33 | | |
34 | | // Router::RateLimitOverrideAction |
35 | | bool populateOverride(RateLimit::Descriptor& descriptor, |
36 | | const envoy::config::core::v3::Metadata* metadata) const override; |
37 | | |
38 | | private: |
39 | | const Envoy::Config::MetadataKey metadata_key_; |
40 | | }; |
41 | | |
42 | | /** |
43 | | * Action for source cluster rate limiting. |
44 | | */ |
45 | | class SourceClusterAction : public RateLimit::DescriptorProducer { |
46 | | public: |
47 | | // Ratelimit::DescriptorProducer |
48 | | bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry, |
49 | | const std::string& local_service_cluster, |
50 | | const Http::RequestHeaderMap& headers, |
51 | | const StreamInfo::StreamInfo& info) const override; |
52 | | }; |
53 | | |
54 | | /** |
55 | | * Action for destination cluster rate limiting. |
56 | | */ |
57 | | class DestinationClusterAction : public RateLimit::DescriptorProducer { |
58 | | public: |
59 | | // Ratelimit::DescriptorProducer |
60 | | bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry, |
61 | | const std::string& local_service_cluster, |
62 | | const Http::RequestHeaderMap& headers, |
63 | | const StreamInfo::StreamInfo& info) const override; |
64 | | }; |
65 | | |
66 | | /** |
67 | | * Action for request headers rate limiting. |
68 | | */ |
69 | | class RequestHeadersAction : public RateLimit::DescriptorProducer { |
70 | | public: |
71 | | RequestHeadersAction(const envoy::config::route::v3::RateLimit::Action::RequestHeaders& action) |
72 | | : header_name_(action.header_name()), descriptor_key_(action.descriptor_key()), |
73 | 2.29k | skip_if_absent_(action.skip_if_absent()) {} |
74 | | |
75 | | // Ratelimit::DescriptorProducer |
76 | | bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry, |
77 | | const std::string& local_service_cluster, |
78 | | const Http::RequestHeaderMap& headers, |
79 | | const StreamInfo::StreamInfo& info) const override; |
80 | | |
81 | | private: |
82 | | const Http::LowerCaseString header_name_; |
83 | | const std::string descriptor_key_; |
84 | | const bool skip_if_absent_; |
85 | | }; |
86 | | |
87 | | /** |
88 | | * Action for remote address rate limiting. |
89 | | */ |
90 | | class RemoteAddressAction : public RateLimit::DescriptorProducer { |
91 | | public: |
92 | | // Ratelimit::DescriptorProducer |
93 | | bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry, |
94 | | const std::string& local_service_cluster, |
95 | | const Http::RequestHeaderMap& headers, |
96 | | const StreamInfo::StreamInfo& info) const override; |
97 | | }; |
98 | | |
99 | | /** |
100 | | * Action for masked remote address rate limiting. |
101 | | */ |
102 | | class MaskedRemoteAddressAction : public RateLimit::DescriptorProducer { |
103 | | public: |
104 | | MaskedRemoteAddressAction( |
105 | | const envoy::config::route::v3::RateLimit::Action::MaskedRemoteAddress& action) |
106 | | : v4_prefix_mask_len_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(action, v4_prefix_mask_len, 32)), |
107 | 8.26k | v6_prefix_mask_len_(PROTOBUF_GET_WRAPPED_OR_DEFAULT(action, v6_prefix_mask_len, 128)) {} |
108 | | |
109 | | // Ratelimit::DescriptorProducer |
110 | | bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry, |
111 | | const std::string& local_service_cluster, |
112 | | const Http::RequestHeaderMap& headers, |
113 | | const StreamInfo::StreamInfo& info) const override; |
114 | | |
115 | | private: |
116 | | const uint32_t v4_prefix_mask_len_; |
117 | | const uint32_t v6_prefix_mask_len_; |
118 | | }; |
119 | | |
120 | | /** |
121 | | * Action for generic key rate limiting. |
122 | | */ |
123 | | class GenericKeyAction : public RateLimit::DescriptorProducer { |
124 | | public: |
125 | | GenericKeyAction(const envoy::config::route::v3::RateLimit::Action::GenericKey& action) |
126 | | : descriptor_value_(action.descriptor_value()), |
127 | | descriptor_key_(!action.descriptor_key().empty() ? action.descriptor_key() |
128 | 9.13k | : "generic_key") {} |
129 | | |
130 | | // Ratelimit::DescriptorProducer |
131 | | bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry, |
132 | | const std::string& local_service_cluster, |
133 | | const Http::RequestHeaderMap& headers, |
134 | | const StreamInfo::StreamInfo& info) const override; |
135 | | |
136 | | private: |
137 | | const std::string descriptor_value_; |
138 | | const std::string descriptor_key_; |
139 | | }; |
140 | | |
141 | | /** |
142 | | * Action for metadata rate limiting. |
143 | | */ |
144 | | class MetaDataAction : public RateLimit::DescriptorProducer { |
145 | | public: |
146 | | MetaDataAction(const envoy::config::route::v3::RateLimit::Action::MetaData& action); |
147 | | // for maintaining backward compatibility with the deprecated DynamicMetaData action |
148 | | MetaDataAction(const envoy::config::route::v3::RateLimit::Action::DynamicMetaData& action); |
149 | | // Ratelimit::DescriptorProducer |
150 | | bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry, |
151 | | const std::string& local_service_cluster, |
152 | | const Http::RequestHeaderMap& headers, |
153 | | const StreamInfo::StreamInfo& info) const override; |
154 | | |
155 | | private: |
156 | | const Envoy::Config::MetadataKey metadata_key_; |
157 | | const std::string descriptor_key_; |
158 | | const std::string default_value_; |
159 | | const envoy::config::route::v3::RateLimit::Action::MetaData::Source source_; |
160 | | const bool skip_if_absent_; |
161 | | }; |
162 | | |
163 | | /** |
164 | | * Action for header value match rate limiting. |
165 | | */ |
166 | | class HeaderValueMatchAction : public RateLimit::DescriptorProducer { |
167 | | public: |
168 | | HeaderValueMatchAction( |
169 | | const envoy::config::route::v3::RateLimit::Action::HeaderValueMatch& action); |
170 | | |
171 | | // Ratelimit::DescriptorProducer |
172 | | bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry, |
173 | | const std::string& local_service_cluster, |
174 | | const Http::RequestHeaderMap& headers, |
175 | | const StreamInfo::StreamInfo& info) const override; |
176 | | |
177 | | private: |
178 | | const std::string descriptor_value_; |
179 | | const std::string descriptor_key_; |
180 | | const bool expect_match_; |
181 | | const std::vector<Http::HeaderUtility::HeaderDataPtr> action_headers_; |
182 | | }; |
183 | | |
184 | | /** |
185 | | * Action for query parameter value match rate limiting. |
186 | | */ |
187 | | class QueryParameterValueMatchAction : public RateLimit::DescriptorProducer { |
188 | | public: |
189 | | QueryParameterValueMatchAction( |
190 | | const envoy::config::route::v3::RateLimit::Action::QueryParameterValueMatch& action); |
191 | | |
192 | | // Ratelimit::DescriptorProducer |
193 | | bool populateDescriptor(RateLimit::DescriptorEntry& descriptor_entry, |
194 | | const std::string& local_service_cluster, |
195 | | const Http::RequestHeaderMap& headers, |
196 | | const StreamInfo::StreamInfo& info) const override; |
197 | | |
198 | | std::vector<ConfigUtility::QueryParameterMatcherPtr> buildQueryParameterMatcherVector( |
199 | | const envoy::config::route::v3::RateLimit::Action::QueryParameterValueMatch& action); |
200 | | |
201 | | private: |
202 | | const std::string descriptor_value_; |
203 | | const std::string descriptor_key_; |
204 | | const bool expect_match_; |
205 | | const std::vector<ConfigUtility::QueryParameterMatcherPtr> action_query_parameters_; |
206 | | }; |
207 | | |
208 | | /* |
209 | | * Implementation of RateLimitPolicyEntry that holds the action for the configuration. |
210 | | */ |
211 | | class RateLimitPolicyEntryImpl : public RateLimitPolicyEntry { |
212 | | public: |
213 | | RateLimitPolicyEntryImpl(const envoy::config::route::v3::RateLimit& config, |
214 | | Server::Configuration::CommonFactoryContext& context); |
215 | | |
216 | | // Router::RateLimitPolicyEntry |
217 | 19.1k | uint64_t stage() const override { return stage_; } |
218 | 0 | const std::string& disableKey() const override { return disable_key_; } |
219 | | void populateDescriptors(std::vector<Envoy::RateLimit::Descriptor>& descriptors, |
220 | | const std::string& local_service_cluster, const Http::RequestHeaderMap&, |
221 | | const StreamInfo::StreamInfo& info) const override; |
222 | | void populateLocalDescriptors(std::vector<Envoy::RateLimit::LocalDescriptor>& descriptors, |
223 | | const std::string& local_service_cluster, |
224 | | const Http::RequestHeaderMap&, |
225 | | const StreamInfo::StreamInfo& info) const override; |
226 | | |
227 | | private: |
228 | | const std::string disable_key_; |
229 | | uint64_t stage_; |
230 | | std::vector<RateLimit::DescriptorProducerPtr> actions_; |
231 | | absl::optional<RateLimitOverrideActionPtr> limit_override_ = absl::nullopt; |
232 | | }; |
233 | | |
234 | | /** |
235 | | * Implementation of RateLimitPolicy that reads from the JSON route config. |
236 | | */ |
237 | | class RateLimitPolicyImpl : public RateLimitPolicy { |
238 | | public: |
239 | | RateLimitPolicyImpl(); |
240 | | RateLimitPolicyImpl( |
241 | | const Protobuf::RepeatedPtrField<envoy::config::route::v3::RateLimit>& rate_limits, |
242 | | Server::Configuration::CommonFactoryContext& context); |
243 | | |
244 | | // Router::RateLimitPolicy |
245 | | const std::vector<std::reference_wrapper<const RateLimitPolicyEntry>>& |
246 | | getApplicableRateLimit(uint64_t stage = 0) const override; |
247 | 0 | bool empty() const override { return rate_limit_entries_.empty(); } |
248 | | |
249 | | private: |
250 | | std::vector<std::unique_ptr<RateLimitPolicyEntry>> rate_limit_entries_; |
251 | | std::vector<std::vector<std::reference_wrapper<const RateLimitPolicyEntry>>> |
252 | | rate_limit_entries_reference_; |
253 | | // The maximum stage number supported. This value should match the maximum stage number in |
254 | | // Json::Schema::HTTP_RATE_LIMITS_CONFIGURATION_SCHEMA and |
255 | | // Json::Schema::RATE_LIMIT_HTTP_FILTER_SCHEMA from common/json/config_schemas.cc. |
256 | | static const uint64_t MAX_STAGE_NUMBER; |
257 | | }; |
258 | | using DefaultRateLimitPolicy = ConstSingleton<RateLimitPolicyImpl>; |
259 | | |
260 | | } // namespace Router |
261 | | } // namespace Envoy |