/proc/self/cwd/source/common/router/config_impl.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <chrono> |
4 | | #include <cstdint> |
5 | | #include <iterator> |
6 | | #include <list> |
7 | | #include <map> |
8 | | #include <memory> |
9 | | #include <regex> |
10 | | #include <string> |
11 | | #include <vector> |
12 | | |
13 | | #include "envoy/config/core/v3/base.pb.h" |
14 | | #include "envoy/config/route/v3/route.pb.h" |
15 | | #include "envoy/config/route/v3/route_components.pb.h" |
16 | | #include "envoy/config/route/v3/route_components.pb.validate.h" |
17 | | #include "envoy/registry/registry.h" |
18 | | #include "envoy/router/cluster_specifier_plugin.h" |
19 | | #include "envoy/router/router.h" |
20 | | #include "envoy/runtime/runtime.h" |
21 | | #include "envoy/server/filter_config.h" |
22 | | #include "envoy/type/v3/percent.pb.h" |
23 | | #include "envoy/upstream/cluster_manager.h" |
24 | | |
25 | | #include "source/common/common/matchers.h" |
26 | | #include "source/common/common/packed_struct.h" |
27 | | #include "source/common/config/metadata.h" |
28 | | #include "source/common/http/hash_policy.h" |
29 | | #include "source/common/http/header_utility.h" |
30 | | #include "source/common/matcher/matcher.h" |
31 | | #include "source/common/router/config_utility.h" |
32 | | #include "source/common/router/header_parser.h" |
33 | | #include "source/common/router/metadatamatchcriteria_impl.h" |
34 | | #include "source/common/router/router_ratelimit.h" |
35 | | #include "source/common/router/tls_context_match_criteria_impl.h" |
36 | | #include "source/common/stats/symbol_table.h" |
37 | | |
38 | | #include "absl/container/node_hash_map.h" |
39 | | #include "absl/types/optional.h" |
40 | | |
41 | | namespace Envoy { |
42 | | namespace Router { |
43 | | |
44 | | using RouteMetadataPack = Envoy::Config::MetadataPack<HttpRouteTypedMetadataFactory>; |
45 | | using RouteMetadataPackPtr = Envoy::Config::MetadataPackPtr<HttpRouteTypedMetadataFactory>; |
46 | | using DefaultRouteMetadataPack = ConstSingleton<RouteMetadataPack>; |
47 | | |
48 | | /** |
49 | | * Original port from the authority header. |
50 | | */ |
51 | | class OriginalConnectPort : public StreamInfo::FilterState::Object { |
52 | | public: |
53 | 0 | explicit OriginalConnectPort(uint32_t port) : port_(port) {} |
54 | 0 | const uint32_t& value() const { return port_; } |
55 | | static const std::string& key(); |
56 | | |
57 | | private: |
58 | | const uint32_t port_; |
59 | | }; |
60 | | |
61 | | /** |
62 | | * Base interface for something that matches a header. |
63 | | */ |
64 | | class Matchable { |
65 | | public: |
66 | 85.0k | virtual ~Matchable() = default; |
67 | | |
68 | | /** |
69 | | * See if this object matches the incoming headers. |
70 | | * @param headers supplies the headers to match. |
71 | | * @param random_value supplies the random seed to use if a runtime choice is required. This |
72 | | * allows stable choices between calls if desired. |
73 | | * @return true if input headers match this object. |
74 | | */ |
75 | | virtual RouteConstSharedPtr matches(const Http::RequestHeaderMap& headers, |
76 | | const StreamInfo::StreamInfo& stream_info, |
77 | | uint64_t random_value) const PURE; |
78 | | |
79 | | // By default, matchers do not support null Path headers. |
80 | 1.07k | virtual bool supportsPathlessHeaders() const { return false; } |
81 | | }; |
82 | | |
83 | | using OptionalHttpFilters = absl::flat_hash_set<std::string>; |
84 | | |
85 | | class PerFilterConfigs : public Logger::Loggable<Logger::Id::http> { |
86 | | public: |
87 | | struct FilterConfig { |
88 | | RouteSpecificFilterConfigConstSharedPtr config_; |
89 | | bool disabled_{}; |
90 | | }; |
91 | | |
92 | | PerFilterConfigs(const Protobuf::Map<std::string, ProtobufWkt::Any>& typed_configs, |
93 | | const OptionalHttpFilters& optional_http_filters, |
94 | | Server::Configuration::ServerFactoryContext& factory_context, |
95 | | ProtobufMessage::ValidationVisitor& validator); |
96 | | |
97 | | const RouteSpecificFilterConfig* get(const std::string& name) const; |
98 | | |
99 | | /** |
100 | | * @return true if the filter is explicitly disabled for this route or virtual host, false |
101 | | * if the filter is explicitly enabled. If the filter is not explicitly enabled or disabled, |
102 | | * returns absl::nullopt. |
103 | | */ |
104 | | absl::optional<bool> disabled(absl::string_view name) const; |
105 | | |
106 | | private: |
107 | | RouteSpecificFilterConfigConstSharedPtr |
108 | | createRouteSpecificFilterConfig(const std::string& name, const ProtobufWkt::Any& typed_config, |
109 | | bool is_optional, |
110 | | Server::Configuration::ServerFactoryContext& factory_context, |
111 | | ProtobufMessage::ValidationVisitor& validator); |
112 | | absl::flat_hash_map<std::string, FilterConfig> configs_; |
113 | | }; |
114 | | |
115 | | class RouteEntryImplBase; |
116 | | using RouteEntryImplBaseConstSharedPtr = std::shared_ptr<const RouteEntryImplBase>; |
117 | | |
118 | | /** |
119 | | * Direct response entry that does an SSL redirect. |
120 | | */ |
121 | | class SslRedirector : public DirectResponseEntry { |
122 | | public: |
123 | | // Router::DirectResponseEntry |
124 | | void finalizeResponseHeaders(Http::ResponseHeaderMap&, |
125 | 0 | const StreamInfo::StreamInfo&) const override {} |
126 | | Http::HeaderTransforms responseHeaderTransforms(const StreamInfo::StreamInfo&, |
127 | 0 | bool) const override { |
128 | 0 | return {}; |
129 | 0 | } |
130 | | std::string newUri(const Http::RequestHeaderMap& headers) const override; |
131 | 0 | void rewritePathHeader(Http::RequestHeaderMap&, bool) const override {} |
132 | 0 | Http::Code responseCode() const override { return Http::Code::MovedPermanently; } |
133 | 0 | const std::string& responseBody() const override { return EMPTY_STRING; } |
134 | | }; |
135 | | |
136 | | class SslRedirectRoute : public Route { |
137 | | public: |
138 | | // Router::Route |
139 | 0 | const DirectResponseEntry* directResponseEntry() const override { return &SSL_REDIRECTOR; } |
140 | 9 | const RouteEntry* routeEntry() const override { return nullptr; } |
141 | 0 | const Decorator* decorator() const override { return nullptr; } |
142 | 0 | const RouteTracing* tracingConfig() const override { return nullptr; } |
143 | 0 | const RouteSpecificFilterConfig* mostSpecificPerFilterConfig(const std::string&) const override { |
144 | 0 | return nullptr; |
145 | 0 | } |
146 | 0 | absl::optional<bool> filterDisabled(absl::string_view) const override { return {}; } |
147 | | void traversePerFilterConfig( |
148 | | const std::string&, |
149 | 0 | std::function<void(const Router::RouteSpecificFilterConfig&)>) const override {} |
150 | 0 | const envoy::config::core::v3::Metadata& metadata() const override { return metadata_; } |
151 | 0 | const Envoy::Config::TypedMetadata& typedMetadata() const override { return typed_metadata_; } |
152 | 0 | const std::string& routeName() const override { return EMPTY_STRING; } |
153 | | |
154 | | private: |
155 | | static const SslRedirector SSL_REDIRECTOR; |
156 | | static const envoy::config::core::v3::Metadata metadata_; |
157 | | static const Envoy::Config::TypedMetadataImpl<Envoy::Config::TypedMetadataFactory> |
158 | | typed_metadata_; |
159 | | }; |
160 | | |
161 | | /** |
162 | | * Implementation of CorsPolicy that reads from the proto route and virtual host config. |
163 | | * TODO(wbpcode): move all cors interfaces and implementation to 'extensions/filters/http/cors'. |
164 | | */ |
165 | | template <class ProtoType> class CorsPolicyImplBase : public CorsPolicy { |
166 | | public: |
167 | | CorsPolicyImplBase(const ProtoType& config, Runtime::Loader& loader) |
168 | | : config_(config), loader_(loader), allow_methods_(config.allow_methods()), |
169 | | allow_headers_(config.allow_headers()), expose_headers_(config.expose_headers()), |
170 | 5.25k | max_age_(config.max_age()) { |
171 | 5.25k | for (const auto& string_match : config.allow_origin_string_match()) { |
172 | 1.90k | allow_origins_.push_back( |
173 | 1.90k | std::make_unique<Matchers::StringMatcherImpl<envoy::type::matcher::v3::StringMatcher>>( |
174 | 1.90k | string_match)); |
175 | 1.90k | } |
176 | 5.25k | if (config.has_allow_credentials()) { |
177 | 1.46k | allow_credentials_ = PROTOBUF_GET_WRAPPED_REQUIRED(config, allow_credentials); |
178 | 1.46k | } |
179 | 5.25k | if (config.has_allow_private_network_access()) { |
180 | 1.87k | allow_private_network_access_ = |
181 | 1.87k | PROTOBUF_GET_WRAPPED_REQUIRED(config, allow_private_network_access); |
182 | 1.87k | } |
183 | 5.25k | } Envoy::Router::CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>::CorsPolicyImplBase(envoy::config::route::v3::CorsPolicy const&, Envoy::Runtime::Loader&) Line | Count | Source | 170 | 5.25k | max_age_(config.max_age()) { | 171 | 5.25k | for (const auto& string_match : config.allow_origin_string_match()) { | 172 | 1.90k | allow_origins_.push_back( | 173 | 1.90k | std::make_unique<Matchers::StringMatcherImpl<envoy::type::matcher::v3::StringMatcher>>( | 174 | 1.90k | string_match)); | 175 | 1.90k | } | 176 | 5.25k | if (config.has_allow_credentials()) { | 177 | 1.46k | allow_credentials_ = PROTOBUF_GET_WRAPPED_REQUIRED(config, allow_credentials); | 178 | 1.46k | } | 179 | 5.25k | if (config.has_allow_private_network_access()) { | 180 | 1.87k | allow_private_network_access_ = | 181 | 1.87k | PROTOBUF_GET_WRAPPED_REQUIRED(config, allow_private_network_access); | 182 | 1.87k | } | 183 | 5.25k | } |
Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::extensions::filters::http::cors::v3::CorsPolicy>::CorsPolicyImplBase(envoy::extensions::filters::http::cors::v3::CorsPolicy const&, Envoy::Runtime::Loader&) |
184 | | |
185 | | // Router::CorsPolicy |
186 | 0 | const std::vector<Matchers::StringMatcherPtr>& allowOrigins() const override { |
187 | 0 | return allow_origins_; |
188 | 0 | }; Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>::allowOrigins() const Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::extensions::filters::http::cors::v3::CorsPolicy>::allowOrigins() const |
189 | 0 | const std::string& allowMethods() const override { return allow_methods_; };Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>::allowMethods() const Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::extensions::filters::http::cors::v3::CorsPolicy>::allowMethods() const |
190 | 0 | const std::string& allowHeaders() const override { return allow_headers_; };Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>::allowHeaders() const Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::extensions::filters::http::cors::v3::CorsPolicy>::allowHeaders() const |
191 | 0 | const std::string& exposeHeaders() const override { return expose_headers_; };Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>::exposeHeaders() const Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::extensions::filters::http::cors::v3::CorsPolicy>::exposeHeaders() const |
192 | 0 | const std::string& maxAge() const override { return max_age_; };Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>::maxAge() const Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::extensions::filters::http::cors::v3::CorsPolicy>::maxAge() const |
193 | 0 | const absl::optional<bool>& allowCredentials() const override { return allow_credentials_; };Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>::allowCredentials() const Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::extensions::filters::http::cors::v3::CorsPolicy>::allowCredentials() const |
194 | 0 | const absl::optional<bool>& allowPrivateNetworkAccess() const override { |
195 | 0 | return allow_private_network_access_; |
196 | 0 | }; Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>::allowPrivateNetworkAccess() const Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::extensions::filters::http::cors::v3::CorsPolicy>::allowPrivateNetworkAccess() const |
197 | 0 | bool enabled() const override { |
198 | 0 | if (config_.has_filter_enabled()) { |
199 | 0 | const auto& filter_enabled = config_.filter_enabled(); |
200 | 0 | return loader_.snapshot().featureEnabled(filter_enabled.runtime_key(), |
201 | 0 | filter_enabled.default_value()); |
202 | 0 | } |
203 | 0 | return true; |
204 | 0 | }; Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>::enabled() const Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::extensions::filters::http::cors::v3::CorsPolicy>::enabled() const |
205 | 0 | bool shadowEnabled() const override { |
206 | 0 | if (config_.has_shadow_enabled()) { |
207 | 0 | const auto& shadow_enabled = config_.shadow_enabled(); |
208 | 0 | return loader_.snapshot().featureEnabled(shadow_enabled.runtime_key(), |
209 | 0 | shadow_enabled.default_value()); |
210 | 0 | } |
211 | 0 | return false; |
212 | 0 | }; Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>::shadowEnabled() const Unexecuted instantiation: Envoy::Router::CorsPolicyImplBase<envoy::extensions::filters::http::cors::v3::CorsPolicy>::shadowEnabled() const |
213 | | |
214 | | private: |
215 | | const ProtoType config_; |
216 | | Runtime::Loader& loader_; |
217 | | std::vector<Matchers::StringMatcherPtr> allow_origins_; |
218 | | const std::string allow_methods_; |
219 | | const std::string allow_headers_; |
220 | | const std::string expose_headers_; |
221 | | const std::string max_age_; |
222 | | absl::optional<bool> allow_credentials_{}; |
223 | | absl::optional<bool> allow_private_network_access_{}; |
224 | | }; |
225 | | using CorsPolicyImpl = CorsPolicyImplBase<envoy::config::route::v3::CorsPolicy>; |
226 | | |
227 | | using RetryPolicyConstOptRef = const OptRef<const envoy::config::route::v3::RetryPolicy>; |
228 | | using HedgePolicyConstOptRef = const OptRef<const envoy::config::route::v3::HedgePolicy>; |
229 | | |
230 | | class ConfigImpl; |
231 | | class CommonConfigImpl; |
232 | | using CommonConfigSharedPtr = std::shared_ptr<CommonConfigImpl>; |
233 | | |
234 | | /** |
235 | | * Implementation of VirtualHost that reads from the proto config. This class holds all shared |
236 | | * data for all routes in the virtual host. |
237 | | */ |
238 | | class CommonVirtualHostImpl : public VirtualHost, Logger::Loggable<Logger::Id::router> { |
239 | | public: |
240 | | CommonVirtualHostImpl(const envoy::config::route::v3::VirtualHost& virtual_host, |
241 | | const OptionalHttpFilters& optional_http_filters, |
242 | | const CommonConfigSharedPtr& global_route_config, |
243 | | Server::Configuration::ServerFactoryContext& factory_context, |
244 | | Stats::Scope& scope, ProtobufMessage::ValidationVisitor& validator); |
245 | | |
246 | | const VirtualCluster* virtualClusterFromEntries(const Http::HeaderMap& headers) const; |
247 | 103k | const CommonConfigImpl& globalRouteConfig() const { return *global_route_config_; } |
248 | 2.47k | const HeaderParser& requestHeaderParser() const { |
249 | 2.47k | if (request_headers_parser_ != nullptr) { |
250 | 501 | return *request_headers_parser_; |
251 | 501 | } |
252 | 1.97k | return HeaderParser::defaultParser(); |
253 | 2.47k | } |
254 | 1.37k | const HeaderParser& responseHeaderParser() const { |
255 | 1.37k | if (response_headers_parser_ != nullptr) { |
256 | 0 | return *response_headers_parser_; |
257 | 0 | } |
258 | 1.37k | return HeaderParser::defaultParser(); |
259 | 1.37k | } |
260 | | absl::optional<bool> filterDisabled(absl::string_view config_name) const; |
261 | | |
262 | | // Router::VirtualHost |
263 | 0 | const CorsPolicy* corsPolicy() const override { return cors_policy_.get(); } |
264 | 27.7k | Stats::StatName statName() const override { return stat_name_storage_.statName(); } |
265 | 0 | const RateLimitPolicy& rateLimitPolicy() const override { |
266 | 0 | if (rate_limit_policy_ != nullptr) { |
267 | 0 | return *rate_limit_policy_; |
268 | 0 | } |
269 | 0 | return DefaultRateLimitPolicy::get(); |
270 | 0 | } |
271 | | const CommonConfig& routeConfig() const override; |
272 | | const RouteSpecificFilterConfig* mostSpecificPerFilterConfig(const std::string&) const override; |
273 | 1.27k | bool includeAttemptCountInRequest() const override { return include_attempt_count_in_request_; } |
274 | 1.27k | bool includeAttemptCountInResponse() const override { return include_attempt_count_in_response_; } |
275 | 1.27k | bool includeIsTimeoutRetryHeader() const override { return include_is_timeout_retry_header_; } |
276 | 82.9k | const std::vector<ShadowPolicyPtr>& shadowPolicies() const { return shadow_policies_; } |
277 | 84.8k | RetryPolicyConstOptRef retryPolicy() const { |
278 | 84.8k | if (retry_policy_ != nullptr) { |
279 | 27.4k | return *retry_policy_; |
280 | 27.4k | } |
281 | 57.3k | return absl::nullopt; |
282 | 84.8k | } |
283 | 84.8k | HedgePolicyConstOptRef hedgePolicy() const { |
284 | 84.8k | if (hedge_policy_ != nullptr) { |
285 | 14.5k | return *hedge_policy_; |
286 | 14.5k | } |
287 | 70.2k | return absl::nullopt; |
288 | 84.8k | } |
289 | 76.0k | uint32_t retryShadowBufferLimit() const override { return retry_shadow_buffer_limit_; } |
290 | | |
291 | | void traversePerFilterConfig( |
292 | | const std::string& filter_name, |
293 | | std::function<void(const Router::RouteSpecificFilterConfig&)> cb) const override; |
294 | | const envoy::config::core::v3::Metadata& metadata() const override; |
295 | | const Envoy::Config::TypedMetadata& typedMetadata() const override; |
296 | | |
297 | | private: |
298 | | struct StatNameProvider { |
299 | | StatNameProvider(absl::string_view name, Stats::SymbolTable& symbol_table) |
300 | 2.90k | : stat_name_storage_(name, symbol_table) {} |
301 | | Stats::StatNameManagedStorage stat_name_storage_; |
302 | | }; |
303 | | |
304 | | struct VirtualClusterBase : public VirtualCluster { |
305 | | public: |
306 | | VirtualClusterBase(const absl::optional<std::string>& name, Stats::StatName stat_name, |
307 | | Stats::ScopeSharedPtr&& scope, const VirtualClusterStatNames& stat_names) |
308 | | : name_(name), stat_name_(stat_name), scope_(std::move(scope)), |
309 | 4.01k | stats_(generateStats(*scope_, stat_names)) {} |
310 | | |
311 | | // Router::VirtualCluster |
312 | | // name_ and stat_name_ are two different representations for the same string, retained in |
313 | | // memory to avoid symbol-table locks that would be needed when converting on-the-fly. |
314 | 0 | const absl::optional<std::string>& name() const override { return name_; } |
315 | 0 | Stats::StatName statName() const override { return stat_name_; } |
316 | 0 | VirtualClusterStats& stats() const override { return stats_; } |
317 | | |
318 | | private: |
319 | | const absl::optional<std::string> name_; |
320 | | const Stats::StatName stat_name_; |
321 | | Stats::ScopeSharedPtr scope_; |
322 | | mutable VirtualClusterStats stats_; |
323 | | }; |
324 | | |
325 | | struct VirtualClusterEntry : public StatNameProvider, public VirtualClusterBase { |
326 | | VirtualClusterEntry(const envoy::config::route::v3::VirtualCluster& virtual_cluster, |
327 | | Stats::Scope& scope, const VirtualClusterStatNames& stat_names); |
328 | | std::vector<Http::HeaderUtility::HeaderDataPtr> headers_; |
329 | | }; |
330 | | |
331 | | struct CatchAllVirtualCluster : public VirtualClusterBase { |
332 | | CatchAllVirtualCluster(Stats::Scope& scope, const VirtualClusterStatNames& stat_names) |
333 | | : VirtualClusterBase(absl::nullopt, stat_names.other_, |
334 | 1.11k | scope.scopeFromStatName(stat_names.other_), stat_names) {} |
335 | | }; |
336 | | |
337 | | const Stats::StatNameManagedStorage stat_name_storage_; |
338 | | Stats::ScopeSharedPtr vcluster_scope_; |
339 | | std::vector<VirtualClusterEntry> virtual_clusters_; |
340 | | std::unique_ptr<const RateLimitPolicyImpl> rate_limit_policy_; |
341 | | std::vector<ShadowPolicyPtr> shadow_policies_; |
342 | | std::unique_ptr<const CorsPolicyImpl> cors_policy_; |
343 | | // Keep an copy of the shared pointer to the shared part of the route config. This is needed |
344 | | // to keep the shared part alive while the virtual host is alive. |
345 | | const CommonConfigSharedPtr global_route_config_; |
346 | | HeaderParserPtr request_headers_parser_; |
347 | | HeaderParserPtr response_headers_parser_; |
348 | | PerFilterConfigs per_filter_configs_; |
349 | | std::unique_ptr<envoy::config::route::v3::RetryPolicy> retry_policy_; |
350 | | std::unique_ptr<envoy::config::route::v3::HedgePolicy> hedge_policy_; |
351 | | std::unique_ptr<const CatchAllVirtualCluster> virtual_cluster_catch_all_; |
352 | | RouteMetadataPackPtr metadata_; |
353 | | // Keep small members (bools and enums) at the end of class, to reduce alignment overhead. |
354 | | uint32_t retry_shadow_buffer_limit_{std::numeric_limits<uint32_t>::max()}; |
355 | | const bool include_attempt_count_in_request_ : 1; |
356 | | const bool include_attempt_count_in_response_ : 1; |
357 | | const bool include_is_timeout_retry_header_ : 1; |
358 | | }; |
359 | | |
360 | | using CommonVirtualHostSharedPtr = std::shared_ptr<CommonVirtualHostImpl>; |
361 | | |
362 | | /** |
363 | | * Virtual host that holds a collection of routes. |
364 | | */ |
365 | | class VirtualHostImpl : Logger::Loggable<Logger::Id::router> { |
366 | | public: |
367 | | VirtualHostImpl( |
368 | | const envoy::config::route::v3::VirtualHost& virtual_host, |
369 | | const OptionalHttpFilters& optional_http_filters, |
370 | | const CommonConfigSharedPtr& global_route_config, |
371 | | Server::Configuration::ServerFactoryContext& factory_context, Stats::Scope& scope, |
372 | | ProtobufMessage::ValidationVisitor& validator, |
373 | | const absl::optional<Upstream::ClusterManager::ClusterInfoMaps>& validation_clusters); |
374 | | |
375 | | RouteConstSharedPtr getRouteFromEntries(const RouteCallback& cb, |
376 | | const Http::RequestHeaderMap& headers, |
377 | | const StreamInfo::StreamInfo& stream_info, |
378 | | uint64_t random_value) const; |
379 | | |
380 | | RouteConstSharedPtr |
381 | | getRouteFromRoutes(const RouteCallback& cb, const Http::RequestHeaderMap& headers, |
382 | | const StreamInfo::StreamInfo& stream_info, uint64_t random_value, |
383 | | absl::Span<const RouteEntryImplBaseConstSharedPtr> routes) const; |
384 | | |
385 | | private: |
386 | | enum class SslRequirements : uint8_t { None, ExternalOnly, All }; |
387 | | |
388 | | static const std::shared_ptr<const SslRedirectRoute> SSL_REDIRECT_ROUTE; |
389 | | |
390 | | CommonVirtualHostSharedPtr shared_virtual_host_; |
391 | | |
392 | | SslRequirements ssl_requirements_; |
393 | | |
394 | | std::vector<RouteEntryImplBaseConstSharedPtr> routes_; |
395 | | Matcher::MatchTreeSharedPtr<Http::HttpMatchingData> matcher_; |
396 | | }; |
397 | | |
398 | | using VirtualHostSharedPtr = std::shared_ptr<VirtualHostImpl>; |
399 | | |
400 | | /** |
401 | | * Implementation of RetryPolicy that reads from the proto route or virtual host config. |
402 | | */ |
403 | | class RetryPolicyImpl : public RetryPolicy { |
404 | | |
405 | | public: |
406 | | RetryPolicyImpl(const envoy::config::route::v3::RetryPolicy& retry_policy, |
407 | | ProtobufMessage::ValidationVisitor& validation_visitor, |
408 | | Upstream::RetryExtensionFactoryContext& factory_context); |
409 | 1.12k | RetryPolicyImpl() = default; |
410 | | |
411 | | // Router::RetryPolicy |
412 | 2.39k | std::chrono::milliseconds perTryTimeout() const override { return per_try_timeout_; } |
413 | 2.39k | std::chrono::milliseconds perTryIdleTimeout() const override { return per_try_idle_timeout_; } |
414 | 0 | uint32_t numRetries() const override { return num_retries_; } |
415 | 2.39k | uint32_t retryOn() const override { return retry_on_; } |
416 | | std::vector<Upstream::RetryHostPredicateSharedPtr> retryHostPredicates() const override; |
417 | | Upstream::RetryPrioritySharedPtr retryPriority() const override; |
418 | | absl::Span<const Upstream::RetryOptionsPredicateConstSharedPtr> |
419 | 0 | retryOptionsPredicates() const override { |
420 | 0 | return retry_options_predicates_; |
421 | 0 | } |
422 | 0 | uint32_t hostSelectionMaxAttempts() const override { return host_selection_attempts_; } |
423 | 0 | const std::vector<uint32_t>& retriableStatusCodes() const override { |
424 | 0 | return retriable_status_codes_; |
425 | 0 | } |
426 | 0 | const std::vector<Http::HeaderMatcherSharedPtr>& retriableHeaders() const override { |
427 | 0 | return retriable_headers_; |
428 | 0 | } |
429 | 0 | const std::vector<Http::HeaderMatcherSharedPtr>& retriableRequestHeaders() const override { |
430 | 0 | return retriable_request_headers_; |
431 | 0 | } |
432 | 0 | absl::optional<std::chrono::milliseconds> baseInterval() const override { return base_interval_; } |
433 | 0 | absl::optional<std::chrono::milliseconds> maxInterval() const override { return max_interval_; } |
434 | 0 | const std::vector<ResetHeaderParserSharedPtr>& resetHeaders() const override { |
435 | 0 | return reset_headers_; |
436 | 0 | } |
437 | 0 | std::chrono::milliseconds resetMaxInterval() const override { return reset_max_interval_; } |
438 | | |
439 | | private: |
440 | | std::chrono::milliseconds per_try_timeout_{0}; |
441 | | std::chrono::milliseconds per_try_idle_timeout_{0}; |
442 | | // We set the number of retries to 1 by default (i.e. when no route or vhost level retry policy is |
443 | | // set) so that when retries get enabled through the x-envoy-retry-on header we default to 1 |
444 | | // retry. |
445 | | uint32_t num_retries_{1}; |
446 | | uint32_t retry_on_{}; |
447 | | // Each pair contains the name and config proto to be used to create the RetryHostPredicates |
448 | | // that should be used when with this policy. |
449 | | std::vector<std::pair<Upstream::RetryHostPredicateFactory&, ProtobufTypes::MessagePtr>> |
450 | | retry_host_predicate_configs_; |
451 | | Upstream::RetryPrioritySharedPtr retry_priority_; |
452 | | // Name and config proto to use to create the RetryPriority to use with this policy. Default |
453 | | // initialized when no RetryPriority should be used. |
454 | | std::pair<Upstream::RetryPriorityFactory*, ProtobufTypes::MessagePtr> retry_priority_config_; |
455 | | uint32_t host_selection_attempts_{1}; |
456 | | std::vector<uint32_t> retriable_status_codes_; |
457 | | std::vector<Http::HeaderMatcherSharedPtr> retriable_headers_; |
458 | | std::vector<Http::HeaderMatcherSharedPtr> retriable_request_headers_; |
459 | | absl::optional<std::chrono::milliseconds> base_interval_; |
460 | | absl::optional<std::chrono::milliseconds> max_interval_; |
461 | | std::vector<ResetHeaderParserSharedPtr> reset_headers_{}; |
462 | | std::chrono::milliseconds reset_max_interval_{300000}; |
463 | | ProtobufMessage::ValidationVisitor* validation_visitor_{}; |
464 | | std::vector<Upstream::RetryOptionsPredicateConstSharedPtr> retry_options_predicates_; |
465 | | }; |
466 | | using DefaultRetryPolicy = ConstSingleton<RetryPolicyImpl>; |
467 | | |
468 | | /** |
469 | | * Implementation of ShadowPolicy that reads from the proto route config. |
470 | | */ |
471 | | class ShadowPolicyImpl : public ShadowPolicy { |
472 | | public: |
473 | | using RequestMirrorPolicy = envoy::config::route::v3::RouteAction::RequestMirrorPolicy; |
474 | | explicit ShadowPolicyImpl(const RequestMirrorPolicy& config); |
475 | | |
476 | | // Router::ShadowPolicy |
477 | 1.74k | const std::string& cluster() const override { return cluster_; } |
478 | 32 | const Http::LowerCaseString& clusterHeader() const override { return cluster_header_; } |
479 | 0 | const std::string& runtimeKey() const override { return runtime_key_; } |
480 | 0 | const envoy::type::v3::FractionalPercent& defaultValue() const override { return default_value_; } |
481 | 0 | bool traceSampled() const override { return trace_sampled_; } |
482 | | |
483 | | private: |
484 | | const std::string cluster_; |
485 | | const Http::LowerCaseString cluster_header_; |
486 | | std::string runtime_key_; |
487 | | envoy::type::v3::FractionalPercent default_value_; |
488 | | bool trace_sampled_; |
489 | | }; |
490 | | |
491 | | /** |
492 | | * Implementation of HedgePolicy that reads from the proto route or virtual host config. |
493 | | */ |
494 | | class HedgePolicyImpl : public HedgePolicy { |
495 | | |
496 | | public: |
497 | | explicit HedgePolicyImpl(const envoy::config::route::v3::HedgePolicy& hedge_policy); |
498 | | HedgePolicyImpl(); |
499 | | |
500 | | // Router::HedgePolicy |
501 | 0 | uint32_t initialRequests() const override { return initial_requests_; } |
502 | 0 | const envoy::type::v3::FractionalPercent& additionalRequestChance() const override { |
503 | 0 | return additional_request_chance_; |
504 | 0 | } |
505 | 1.27k | bool hedgeOnPerTryTimeout() const override { return hedge_on_per_try_timeout_; } |
506 | | |
507 | | private: |
508 | | const uint32_t initial_requests_; |
509 | | const envoy::type::v3::FractionalPercent additional_request_chance_; |
510 | | const bool hedge_on_per_try_timeout_; |
511 | | }; |
512 | | using DefaultHedgePolicy = ConstSingleton<HedgePolicyImpl>; |
513 | | |
514 | | /** |
515 | | * Implementation of Decorator that reads from the proto route decorator. |
516 | | */ |
517 | | class DecoratorImpl : public Decorator { |
518 | | public: |
519 | | explicit DecoratorImpl(const envoy::config::route::v3::Decorator& decorator); |
520 | | |
521 | | // Decorator::apply |
522 | | void apply(Tracing::Span& span) const override; |
523 | | |
524 | | // Decorator::getOperation |
525 | | const std::string& getOperation() const override; |
526 | | |
527 | | // Decorator::getOperation |
528 | | bool propagate() const override; |
529 | | |
530 | | private: |
531 | | const std::string operation_; |
532 | | const bool propagate_; |
533 | | }; |
534 | | |
535 | | /** |
536 | | * Implementation of RouteTracing that reads from the proto route tracing. |
537 | | */ |
538 | | class RouteTracingImpl : public RouteTracing { |
539 | | public: |
540 | | explicit RouteTracingImpl(const envoy::config::route::v3::Tracing& tracing); |
541 | | |
542 | | // Tracing::getClientSampling |
543 | | const envoy::type::v3::FractionalPercent& getClientSampling() const override; |
544 | | |
545 | | // Tracing::getRandomSampling |
546 | | const envoy::type::v3::FractionalPercent& getRandomSampling() const override; |
547 | | |
548 | | // Tracing::getOverallSampling |
549 | | const envoy::type::v3::FractionalPercent& getOverallSampling() const override; |
550 | | |
551 | | const Tracing::CustomTagMap& getCustomTags() const override; |
552 | | |
553 | | private: |
554 | | envoy::type::v3::FractionalPercent client_sampling_; |
555 | | envoy::type::v3::FractionalPercent random_sampling_; |
556 | | envoy::type::v3::FractionalPercent overall_sampling_; |
557 | | Tracing::CustomTagMap custom_tags_; |
558 | | }; |
559 | | |
560 | | /** |
561 | | * Implementation of InternalRedirectPolicy that reads from the proto |
562 | | * InternalRedirectPolicy of the RouteAction. |
563 | | */ |
564 | | class InternalRedirectPolicyImpl : public InternalRedirectPolicy { |
565 | | public: |
566 | | // Constructor that enables internal redirect with policy_config controlling the configurable |
567 | | // behaviors. |
568 | | InternalRedirectPolicyImpl(const envoy::config::route::v3::InternalRedirectPolicy& policy_config, |
569 | | ProtobufMessage::ValidationVisitor& validator, |
570 | | absl::string_view current_route_name); |
571 | | // Default constructor that disables internal redirect. |
572 | 94 | InternalRedirectPolicyImpl() = default; |
573 | | |
574 | 6.88k | bool enabled() const override { return enabled_; } |
575 | | |
576 | 0 | bool shouldRedirectForResponseCode(const Http::Code& response_code) const override { |
577 | 0 | return redirect_response_codes_.contains(response_code); |
578 | 0 | } |
579 | | |
580 | | std::vector<InternalRedirectPredicateSharedPtr> predicates() const override; |
581 | | |
582 | 0 | uint32_t maxInternalRedirects() const override { return max_internal_redirects_; } |
583 | | |
584 | 0 | bool isCrossSchemeRedirectAllowed() const override { return allow_cross_scheme_redirect_; } |
585 | | |
586 | | private: |
587 | | absl::flat_hash_set<Http::Code> buildRedirectResponseCodes( |
588 | | const envoy::config::route::v3::InternalRedirectPolicy& policy_config) const; |
589 | | |
590 | | const std::string current_route_name_; |
591 | | const absl::flat_hash_set<Http::Code> redirect_response_codes_; |
592 | | std::vector<std::pair<InternalRedirectPredicateFactory*, ProtobufTypes::MessagePtr>> |
593 | | predicate_factories_; |
594 | | // Keep small members (bools and enums) at the end of class, to reduce alignment overhead. |
595 | | const uint32_t max_internal_redirects_{1}; |
596 | | const bool enabled_{false}; |
597 | | const bool allow_cross_scheme_redirect_{false}; |
598 | | }; |
599 | | using DefaultInternalRedirectPolicy = ConstSingleton<InternalRedirectPolicyImpl>; |
600 | | |
601 | | /** |
602 | | * Base implementation for all route entries.q |
603 | | */ |
604 | | class RouteEntryImplBase : public RouteEntryAndRoute, |
605 | | public Matchable, |
606 | | public DirectResponseEntry, |
607 | | public PathMatchCriterion, |
608 | | public std::enable_shared_from_this<RouteEntryImplBase>, |
609 | | Logger::Loggable<Logger::Id::router> { |
610 | | public: |
611 | | /** |
612 | | * @throw EnvoyException with reason if the route configuration contains any errors |
613 | | */ |
614 | | RouteEntryImplBase(const CommonVirtualHostSharedPtr& vhost, |
615 | | const envoy::config::route::v3::Route& route, |
616 | | const OptionalHttpFilters& optional_http_filters, |
617 | | Server::Configuration::ServerFactoryContext& factory_context, |
618 | | ProtobufMessage::ValidationVisitor& validator); |
619 | | |
620 | 43.4k | bool isDirectResponse() const { return direct_response_code_.has_value(); } |
621 | | |
622 | 3.04k | bool isRedirect() const { |
623 | 3.04k | if (!isDirectResponse()) { |
624 | 2.87k | return false; |
625 | 2.87k | } |
626 | 170 | if (redirect_config_ == nullptr) { |
627 | 170 | return false; |
628 | 170 | } |
629 | 0 | return !redirect_config_->host_redirect_.empty() || !redirect_config_->path_redirect_.empty() || |
630 | 0 | !redirect_config_->prefix_rewrite_redirect_.empty() || |
631 | 0 | redirect_config_->regex_rewrite_redirect_ != nullptr; |
632 | 170 | } |
633 | | |
634 | | bool matchRoute(const Http::RequestHeaderMap& headers, const StreamInfo::StreamInfo& stream_info, |
635 | | uint64_t random_value) const; |
636 | | void validateClusters(const Upstream::ClusterManager::ClusterInfoMaps& cluster_info_maps) const; |
637 | | |
638 | | // Router::RouteEntry |
639 | | const std::string& clusterName() const override; |
640 | 1.27k | const RouteStatsContextOptRef routeStatsContext() const override { |
641 | 1.27k | if (route_stats_context_ != nullptr) { |
642 | 0 | return *route_stats_context_; |
643 | 0 | } |
644 | 1.27k | return RouteStatsContextOptRef(); |
645 | 1.27k | } |
646 | 0 | Http::Code clusterNotFoundResponseCode() const override { |
647 | 0 | return cluster_not_found_response_code_; |
648 | 0 | } |
649 | 0 | const CorsPolicy* corsPolicy() const override { return cors_policy_.get(); } |
650 | 2.47k | const HeaderParser& requestHeaderParser() const { |
651 | 2.47k | if (request_headers_parser_ != nullptr) { |
652 | 831 | return *request_headers_parser_; |
653 | 831 | } |
654 | 1.64k | return HeaderParser::defaultParser(); |
655 | 2.47k | } |
656 | 1.37k | const HeaderParser& responseHeaderParser() const { |
657 | 1.37k | if (response_headers_parser_ != nullptr) { |
658 | 0 | return *response_headers_parser_; |
659 | 0 | } |
660 | 1.37k | return HeaderParser::defaultParser(); |
661 | 1.37k | } |
662 | | void finalizeRequestHeaders(Http::RequestHeaderMap& headers, |
663 | | const StreamInfo::StreamInfo& stream_info, |
664 | | bool insert_envoy_original_path) const override; |
665 | | Http::HeaderTransforms requestHeaderTransforms(const StreamInfo::StreamInfo& stream_info, |
666 | | bool do_formatting = true) const override; |
667 | | void finalizeResponseHeaders(Http::ResponseHeaderMap& headers, |
668 | | const StreamInfo::StreamInfo& stream_info) const override; |
669 | | Http::HeaderTransforms responseHeaderTransforms(const StreamInfo::StreamInfo& stream_info, |
670 | | bool do_formatting = true) const override; |
671 | 0 | const Http::HashPolicy* hashPolicy() const override { return hash_policy_.get(); } |
672 | | |
673 | 1.27k | const HedgePolicy& hedgePolicy() const override { |
674 | 1.27k | if (hedge_policy_ != nullptr) { |
675 | 0 | return *hedge_policy_; |
676 | 0 | } |
677 | 1.27k | return DefaultHedgePolicy::get(); |
678 | 1.27k | } |
679 | | |
680 | 0 | const MetadataMatchCriteria* metadataMatchCriteria() const override { |
681 | 0 | return metadata_match_criteria_.get(); |
682 | 0 | } |
683 | 12.6k | const TlsContextMatchCriteria* tlsContextMatchCriteria() const override { |
684 | 12.6k | return tls_context_match_criteria_.get(); |
685 | 12.6k | } |
686 | 2.54k | Upstream::ResourcePriority priority() const override { return priority_; } |
687 | 0 | const RateLimitPolicy& rateLimitPolicy() const override { |
688 | 0 | if (rate_limit_policy_ != nullptr) { |
689 | 0 | return *rate_limit_policy_; |
690 | 0 | } |
691 | 0 | return DefaultRateLimitPolicy::get(); |
692 | 0 | } |
693 | 3.82k | const RetryPolicy& retryPolicy() const override { |
694 | 3.82k | if (retry_policy_ != nullptr) { |
695 | 0 | return *retry_policy_; |
696 | 0 | } |
697 | 3.82k | return DefaultRetryPolicy::get(); |
698 | 3.82k | } |
699 | 2.40k | const InternalRedirectPolicy& internalRedirectPolicy() const override { |
700 | 2.40k | if (internal_redirect_policy_ != nullptr) { |
701 | 0 | return *internal_redirect_policy_; |
702 | 0 | } |
703 | 2.40k | return DefaultInternalRedirectPolicy::get(); |
704 | 2.40k | } |
705 | | |
706 | 0 | const PathMatcherSharedPtr& pathMatcher() const override { return path_matcher_; } |
707 | 0 | const PathRewriterSharedPtr& pathRewriter() const override { return path_rewriter_; } |
708 | | |
709 | 1.27k | uint32_t retryShadowBufferLimit() const override { return retry_shadow_buffer_limit_; } |
710 | 27.8k | const std::vector<ShadowPolicyPtr>& shadowPolicies() const override { return shadow_policies_; } |
711 | 1.27k | const VirtualCluster* virtualCluster(const Http::HeaderMap& headers) const override { |
712 | 1.27k | return vhost_->virtualClusterFromEntries(headers); |
713 | 1.27k | } |
714 | 1.27k | std::chrono::milliseconds timeout() const override { return timeout_; } |
715 | 1.27k | bool usingNewTimeouts() const override { return using_new_timeouts_; } |
716 | | |
717 | | // `OptionalTimeouts` manages various `optional` values. We pack them in a |
718 | | // separate data structure for memory efficiency -- avoiding overhead of |
719 | | // `absl::optional` per variable, and avoiding overhead of storing unset |
720 | | // timeouts. |
721 | | enum class OptionalTimeoutNames { |
722 | | IdleTimeout = 0, |
723 | | MaxStreamDuration, |
724 | | GrpcTimeoutHeaderMax, |
725 | | GrpcTimeoutHeaderOffset, |
726 | | MaxGrpcTimeout, |
727 | | GrpcTimeoutOffset |
728 | | }; |
729 | | using OptionalTimeouts = PackedStruct<std::chrono::milliseconds, 6, OptionalTimeoutNames>; |
730 | | |
731 | 1.30k | absl::optional<std::chrono::milliseconds> idleTimeout() const override { |
732 | 1.30k | return getOptionalTimeout<OptionalTimeoutNames::IdleTimeout>(); |
733 | 1.30k | } |
734 | 1.30k | absl::optional<std::chrono::milliseconds> maxStreamDuration() const override { |
735 | 1.30k | return getOptionalTimeout<OptionalTimeoutNames::MaxStreamDuration>(); |
736 | 1.30k | } |
737 | 0 | absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderMax() const override { |
738 | 0 | return getOptionalTimeout<OptionalTimeoutNames::GrpcTimeoutHeaderMax>(); |
739 | 0 | } |
740 | 0 | absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderOffset() const override { |
741 | 0 | return getOptionalTimeout<OptionalTimeoutNames::GrpcTimeoutHeaderOffset>(); |
742 | 0 | } |
743 | 0 | absl::optional<std::chrono::milliseconds> maxGrpcTimeout() const override { |
744 | 0 | return getOptionalTimeout<OptionalTimeoutNames::MaxGrpcTimeout>(); |
745 | 0 | } |
746 | 0 | absl::optional<std::chrono::milliseconds> grpcTimeoutOffset() const override { |
747 | 0 | return getOptionalTimeout<OptionalTimeoutNames::GrpcTimeoutOffset>(); |
748 | 0 | } |
749 | | |
750 | 3.51k | const VirtualHost& virtualHost() const override { return *vhost_; } |
751 | 1.20k | bool autoHostRewrite() const override { return auto_host_rewrite_; } |
752 | 0 | bool appendXfh() const override { return append_xfh_; } |
753 | 0 | const std::multimap<std::string, std::string>& opaqueConfig() const override { |
754 | 0 | return opaque_config_; |
755 | 0 | } |
756 | 0 | bool includeVirtualHostRateLimits() const override { return include_vh_rate_limits_; } |
757 | | const envoy::config::core::v3::Metadata& metadata() const override; |
758 | | const Envoy::Config::TypedMetadata& typedMetadata() const override; |
759 | 0 | const PathMatchCriterion& pathMatchCriterion() const override { return *this; } |
760 | 1.27k | bool includeAttemptCountInRequest() const override { |
761 | 1.27k | return vhost_->includeAttemptCountInRequest(); |
762 | 1.27k | } |
763 | 1.27k | bool includeAttemptCountInResponse() const override { |
764 | 1.27k | return vhost_->includeAttemptCountInResponse(); |
765 | 1.27k | } |
766 | 1.27k | const ConnectConfigOptRef connectConfig() const override { |
767 | 1.27k | if (connect_config_ != nullptr) { |
768 | 0 | return *connect_config_; |
769 | 0 | } |
770 | 1.27k | return absl::nullopt; |
771 | 1.27k | } |
772 | 0 | const UpgradeMap& upgradeMap() const override { return upgrade_map_; } |
773 | 1.27k | const EarlyDataPolicy& earlyDataPolicy() const override { return *early_data_policy_; } |
774 | | |
775 | | // Router::DirectResponseEntry |
776 | | std::string newUri(const Http::RequestHeaderMap& headers) const override; |
777 | 0 | void rewritePathHeader(Http::RequestHeaderMap&, bool) const override {} |
778 | 510 | Http::Code responseCode() const override { return direct_response_code_.value(); } |
779 | 170 | const std::string& responseBody() const override { return direct_response_body_; } |
780 | | |
781 | | // Router::Route |
782 | | const DirectResponseEntry* directResponseEntry() const override; |
783 | | const RouteEntry* routeEntry() const override; |
784 | 0 | const Decorator* decorator() const override { return decorator_.get(); } |
785 | 0 | const RouteTracing* tracingConfig() const override { return route_tracing_.get(); } |
786 | | absl::optional<bool> filterDisabled(absl::string_view config_name) const override; |
787 | | const RouteSpecificFilterConfig* |
788 | 0 | mostSpecificPerFilterConfig(const std::string& name) const override { |
789 | 0 | auto* config = per_filter_configs_.get(name); |
790 | 0 | return config ? config : vhost_->mostSpecificPerFilterConfig(name); |
791 | 0 | } |
792 | | void traversePerFilterConfig( |
793 | | const std::string& filter_name, |
794 | | std::function<void(const Router::RouteSpecificFilterConfig&)> cb) const override; |
795 | 0 | const std::string& routeName() const override { return route_name_; } |
796 | | |
797 | | // Sanitizes the |path| before passing it to PathMatcher, if configured, this method makes the |
798 | | // path matching to ignore the path-parameters. |
799 | | absl::string_view sanitizePathBeforePathMatching(const absl::string_view path) const; |
800 | | |
801 | | class DynamicRouteEntry : public RouteEntryAndRoute { |
802 | | public: |
803 | | DynamicRouteEntry(const RouteEntryAndRoute* parent, RouteConstSharedPtr owner, |
804 | | const std::string& name) |
805 | 46.4k | : parent_(parent), owner_(std::move(owner)), cluster_name_(name) {} |
806 | | |
807 | | // Router::RouteEntry |
808 | 536 | const std::string& clusterName() const override { return cluster_name_; } |
809 | 0 | Http::Code clusterNotFoundResponseCode() const override { |
810 | 0 | return parent_->clusterNotFoundResponseCode(); |
811 | 0 | } |
812 | | |
813 | | absl::optional<std::string> |
814 | 0 | currentUrlPathAfterRewrite(const Http::RequestHeaderMap& headers) const override { |
815 | 0 | return parent_->currentUrlPathAfterRewrite(headers); |
816 | 0 | } |
817 | | void finalizeRequestHeaders(Http::RequestHeaderMap& headers, |
818 | | const StreamInfo::StreamInfo& stream_info, |
819 | 847 | bool insert_envoy_original_path) const override { |
820 | 847 | return parent_->finalizeRequestHeaders(headers, stream_info, insert_envoy_original_path); |
821 | 847 | } |
822 | | Http::HeaderTransforms requestHeaderTransforms(const StreamInfo::StreamInfo& stream_info, |
823 | 0 | bool do_formatting = true) const override { |
824 | 0 | return parent_->requestHeaderTransforms(stream_info, do_formatting); |
825 | 0 | } |
826 | | void finalizeResponseHeaders(Http::ResponseHeaderMap& headers, |
827 | 0 | const StreamInfo::StreamInfo& stream_info) const override { |
828 | 0 | return parent_->finalizeResponseHeaders(headers, stream_info); |
829 | 0 | } |
830 | | Http::HeaderTransforms responseHeaderTransforms(const StreamInfo::StreamInfo& stream_info, |
831 | 0 | bool do_formatting = true) const override { |
832 | 0 | return parent_->responseHeaderTransforms(stream_info, do_formatting); |
833 | 0 | } |
834 | | |
835 | 0 | const CorsPolicy* corsPolicy() const override { return parent_->corsPolicy(); } |
836 | 0 | const Http::HashPolicy* hashPolicy() const override { return parent_->hashPolicy(); } |
837 | 0 | const HedgePolicy& hedgePolicy() const override { return parent_->hedgePolicy(); } |
838 | 0 | Upstream::ResourcePriority priority() const override { return parent_->priority(); } |
839 | 0 | const RateLimitPolicy& rateLimitPolicy() const override { return parent_->rateLimitPolicy(); } |
840 | 0 | const RetryPolicy& retryPolicy() const override { return parent_->retryPolicy(); } |
841 | 0 | const InternalRedirectPolicy& internalRedirectPolicy() const override { |
842 | 0 | return parent_->internalRedirectPolicy(); |
843 | 0 | } |
844 | 0 | const PathMatcherSharedPtr& pathMatcher() const override { return parent_->pathMatcher(); } |
845 | 0 | const PathRewriterSharedPtr& pathRewriter() const override { return parent_->pathRewriter(); } |
846 | 0 | uint32_t retryShadowBufferLimit() const override { return parent_->retryShadowBufferLimit(); } |
847 | 0 | const std::vector<ShadowPolicyPtr>& shadowPolicies() const override { |
848 | 0 | return parent_->shadowPolicies(); |
849 | 0 | } |
850 | 0 | std::chrono::milliseconds timeout() const override { return parent_->timeout(); } |
851 | 0 | absl::optional<std::chrono::milliseconds> idleTimeout() const override { |
852 | 0 | return parent_->idleTimeout(); |
853 | 0 | } |
854 | 0 | bool usingNewTimeouts() const override { return parent_->usingNewTimeouts(); } |
855 | 0 | absl::optional<std::chrono::milliseconds> maxStreamDuration() const override { |
856 | 0 | return parent_->maxStreamDuration(); |
857 | 0 | } |
858 | 0 | absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderMax() const override { |
859 | 0 | return parent_->grpcTimeoutHeaderMax(); |
860 | 0 | } |
861 | 0 | absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderOffset() const override { |
862 | 0 | return parent_->grpcTimeoutHeaderOffset(); |
863 | 0 | } |
864 | 0 | absl::optional<std::chrono::milliseconds> maxGrpcTimeout() const override { |
865 | 0 | return parent_->maxGrpcTimeout(); |
866 | 0 | } |
867 | 0 | absl::optional<std::chrono::milliseconds> grpcTimeoutOffset() const override { |
868 | 0 | return parent_->grpcTimeoutOffset(); |
869 | 0 | } |
870 | 0 | const MetadataMatchCriteria* metadataMatchCriteria() const override { |
871 | 0 | return parent_->metadataMatchCriteria(); |
872 | 0 | } |
873 | 0 | const TlsContextMatchCriteria* tlsContextMatchCriteria() const override { |
874 | 0 | return parent_->tlsContextMatchCriteria(); |
875 | 0 | } |
876 | | |
877 | 0 | const VirtualCluster* virtualCluster(const Http::HeaderMap& headers) const override { |
878 | 0 | return parent_->virtualCluster(headers); |
879 | 0 | } |
880 | | |
881 | 0 | const std::multimap<std::string, std::string>& opaqueConfig() const override { |
882 | 0 | return parent_->opaqueConfig(); |
883 | 0 | } |
884 | | |
885 | 0 | const VirtualHost& virtualHost() const override { return parent_->virtualHost(); } |
886 | 0 | bool autoHostRewrite() const override { return parent_->autoHostRewrite(); } |
887 | 0 | bool appendXfh() const override { return parent_->appendXfh(); } |
888 | 0 | bool includeVirtualHostRateLimits() const override { |
889 | 0 | return parent_->includeVirtualHostRateLimits(); |
890 | 0 | } |
891 | 0 | const envoy::config::core::v3::Metadata& metadata() const override { |
892 | 0 | return parent_->metadata(); |
893 | 0 | } |
894 | 0 | const Envoy::Config::TypedMetadata& typedMetadata() const override { |
895 | 0 | return parent_->typedMetadata(); |
896 | 0 | } |
897 | 0 | const PathMatchCriterion& pathMatchCriterion() const override { |
898 | 0 | return parent_->pathMatchCriterion(); |
899 | 0 | } |
900 | | |
901 | 0 | bool includeAttemptCountInRequest() const override { |
902 | 0 | return parent_->includeAttemptCountInRequest(); |
903 | 0 | } |
904 | 0 | bool includeAttemptCountInResponse() const override { |
905 | 0 | return parent_->includeAttemptCountInResponse(); |
906 | 0 | } |
907 | 0 | const ConnectConfigOptRef connectConfig() const override { return parent_->connectConfig(); } |
908 | 0 | const RouteStatsContextOptRef routeStatsContext() const override { |
909 | 0 | return parent_->routeStatsContext(); |
910 | 0 | } |
911 | 0 | const UpgradeMap& upgradeMap() const override { return parent_->upgradeMap(); } |
912 | 0 | const EarlyDataPolicy& earlyDataPolicy() const override { return parent_->earlyDataPolicy(); } |
913 | | |
914 | | // Router::Route |
915 | 0 | const DirectResponseEntry* directResponseEntry() const override { return nullptr; } |
916 | 1.44k | const RouteEntry* routeEntry() const override { return this; } |
917 | 0 | const Decorator* decorator() const override { return parent_->decorator(); } |
918 | 0 | const RouteTracing* tracingConfig() const override { return parent_->tracingConfig(); } |
919 | 0 | absl::optional<bool> filterDisabled(absl::string_view config_name) const override { |
920 | 0 | return parent_->filterDisabled(config_name); |
921 | 0 | } |
922 | | const RouteSpecificFilterConfig* |
923 | 0 | mostSpecificPerFilterConfig(const std::string& name) const override { |
924 | 0 | return parent_->mostSpecificPerFilterConfig(name); |
925 | 0 | } |
926 | | void traversePerFilterConfig( |
927 | | const std::string& filter_name, |
928 | 0 | std::function<void(const Router::RouteSpecificFilterConfig&)> cb) const override { |
929 | 0 | parent_->traversePerFilterConfig(filter_name, cb); |
930 | 0 | }; |
931 | 0 | const std::string& routeName() const override { return parent_->routeName(); } |
932 | | |
933 | | private: |
934 | | const RouteEntryAndRoute* parent_; |
935 | | |
936 | | // If a DynamicRouteEntry instance is created and returned to the caller directly, then keep an |
937 | | // copy of the shared pointer to the parent Route (RouteEntryImplBase) to ensure the parent |
938 | | // is not destroyed before this entry. |
939 | | // |
940 | | // This should be nullptr if the DynamicRouteEntry is part of the parent (RouteEntryImplBase) to |
941 | | // avoid possible circular reference. For example, the WeightedClusterEntry (derived from |
942 | | // DynamicRouteEntry) will be member of the RouteEntryImplBase, so the owner_ should be nullptr. |
943 | | const RouteConstSharedPtr owner_; |
944 | | const std::string cluster_name_; |
945 | | }; |
946 | | |
947 | | /** |
948 | | * Route entry implementation for weighted clusters. The RouteEntryImplBase object holds |
949 | | * one or more weighted cluster objects, where each object has a back pointer to the parent |
950 | | * RouteEntryImplBase object. Almost all functions in this class forward calls back to the |
951 | | * parent, with the exception of clusterName, routeEntry, and metadataMatchCriteria. |
952 | | */ |
953 | | class WeightedClusterEntry : public DynamicRouteEntry { |
954 | | public: |
955 | | WeightedClusterEntry(const RouteEntryImplBase* parent, const std::string& rutime_key, |
956 | | Server::Configuration::ServerFactoryContext& factory_context, |
957 | | ProtobufMessage::ValidationVisitor& validator, |
958 | | const envoy::config::route::v3::WeightedCluster::ClusterWeight& cluster, |
959 | | const OptionalHttpFilters& optional_http_filters); |
960 | | |
961 | 45.8k | uint64_t clusterWeight() const { |
962 | 45.8k | return loader_.snapshot().getInteger(runtime_key_, cluster_weight_); |
963 | 45.8k | } |
964 | | |
965 | 0 | const MetadataMatchCriteria* metadataMatchCriteria() const override { |
966 | 0 | if (cluster_metadata_match_criteria_) { |
967 | 0 | return cluster_metadata_match_criteria_.get(); |
968 | 0 | } |
969 | 0 | return DynamicRouteEntry::metadataMatchCriteria(); |
970 | 0 | } |
971 | | |
972 | 124 | const HeaderParser& requestHeaderParser() const { |
973 | 124 | if (request_headers_parser_ != nullptr) { |
974 | 49 | return *request_headers_parser_; |
975 | 49 | } |
976 | 75 | return HeaderParser::defaultParser(); |
977 | 124 | } |
978 | 0 | const HeaderParser& responseHeaderParser() const { |
979 | 0 | if (response_headers_parser_ != nullptr) { |
980 | 0 | return *response_headers_parser_; |
981 | 0 | } |
982 | 0 | return HeaderParser::defaultParser(); |
983 | 0 | } |
984 | | |
985 | | void finalizeRequestHeaders(Http::RequestHeaderMap& headers, |
986 | | const StreamInfo::StreamInfo& stream_info, |
987 | 124 | bool insert_envoy_original_path) const override { |
988 | 124 | requestHeaderParser().evaluateHeaders(headers, stream_info); |
989 | 124 | if (!host_rewrite_.empty()) { |
990 | 26 | headers.setHost(host_rewrite_); |
991 | 26 | } |
992 | 124 | DynamicRouteEntry::finalizeRequestHeaders(headers, stream_info, insert_envoy_original_path); |
993 | 124 | } |
994 | | Http::HeaderTransforms requestHeaderTransforms(const StreamInfo::StreamInfo& stream_info, |
995 | | bool do_formatting = true) const override; |
996 | | void finalizeResponseHeaders(Http::ResponseHeaderMap& headers, |
997 | 0 | const StreamInfo::StreamInfo& stream_info) const override { |
998 | 0 | const Http::RequestHeaderMap& request_headers = |
999 | 0 | stream_info.getRequestHeaders() == nullptr |
1000 | 0 | ? *Http::StaticEmptyHeaders::get().request_headers |
1001 | 0 | : *stream_info.getRequestHeaders(); |
1002 | 0 | responseHeaderParser().evaluateHeaders(headers, {&request_headers, &headers}, stream_info); |
1003 | 0 | DynamicRouteEntry::finalizeResponseHeaders(headers, stream_info); |
1004 | 0 | } |
1005 | | Http::HeaderTransforms responseHeaderTransforms(const StreamInfo::StreamInfo& stream_info, |
1006 | | bool do_formatting = true) const override; |
1007 | | |
1008 | 0 | absl::optional<bool> filterDisabled(absl::string_view config_name) const override { |
1009 | 0 | absl::optional<bool> result = per_filter_configs_.disabled(config_name); |
1010 | 0 | if (result.has_value()) { |
1011 | 0 | return result.value(); |
1012 | 0 | } |
1013 | 0 | return DynamicRouteEntry::filterDisabled(config_name); |
1014 | 0 | } |
1015 | | const RouteSpecificFilterConfig* |
1016 | 0 | mostSpecificPerFilterConfig(const std::string& name) const override { |
1017 | 0 | auto* config = per_filter_configs_.get(name); |
1018 | 0 | return config ? config : DynamicRouteEntry::mostSpecificPerFilterConfig(name); |
1019 | 0 | } |
1020 | | |
1021 | | void traversePerFilterConfig( |
1022 | | const std::string& filter_name, |
1023 | | std::function<void(const Router::RouteSpecificFilterConfig&)> cb) const override; |
1024 | | |
1025 | 584 | const Http::LowerCaseString& clusterHeaderName() const { return cluster_header_name_; } |
1026 | | |
1027 | | private: |
1028 | | const std::string runtime_key_; |
1029 | | Runtime::Loader& loader_; |
1030 | | const uint64_t cluster_weight_; |
1031 | | MetadataMatchCriteriaConstPtr cluster_metadata_match_criteria_; |
1032 | | HeaderParserPtr request_headers_parser_; |
1033 | | HeaderParserPtr response_headers_parser_; |
1034 | | PerFilterConfigs per_filter_configs_; |
1035 | | const std::string host_rewrite_; |
1036 | | const Http::LowerCaseString cluster_header_name_; |
1037 | | }; |
1038 | | |
1039 | | using WeightedClusterEntrySharedPtr = std::shared_ptr<WeightedClusterEntry>; |
1040 | | // Container for route config elements that pertain to weighted clusters. |
1041 | | // We keep them in a separate data structure to avoid memory overhead for the routes that do not |
1042 | | // use weighted clusters. |
1043 | | struct WeightedClustersConfig { |
1044 | | WeightedClustersConfig(const std::vector<WeightedClusterEntrySharedPtr>&& weighted_clusters, |
1045 | | uint64_t total_cluster_weight, |
1046 | | const std::string& random_value_header_name) |
1047 | | : weighted_clusters_(std::move(weighted_clusters)), |
1048 | | total_cluster_weight_(total_cluster_weight), |
1049 | 4.73k | random_value_header_name_(random_value_header_name) {} |
1050 | | const std::vector<WeightedClusterEntrySharedPtr> weighted_clusters_; |
1051 | | const uint64_t total_cluster_weight_; |
1052 | | const std::string random_value_header_name_; |
1053 | | }; |
1054 | | |
1055 | | protected: |
1056 | | const std::string prefix_rewrite_; |
1057 | | Regex::CompiledMatcherPtr regex_rewrite_; |
1058 | | const PathMatcherSharedPtr path_matcher_; |
1059 | | const PathRewriterSharedPtr path_rewriter_; |
1060 | | std::string regex_rewrite_substitution_; |
1061 | | const std::string host_rewrite_; |
1062 | | std::unique_ptr<ConnectConfig> connect_config_; |
1063 | | |
1064 | 42.3k | bool case_sensitive() const { return case_sensitive_; } |
1065 | | RouteConstSharedPtr clusterEntry(const Http::RequestHeaderMap& headers, |
1066 | | uint64_t random_value) const; |
1067 | | |
1068 | | /** |
1069 | | * Returns the correct path rewrite string for this route. |
1070 | | * |
1071 | | * The provided container may be used to store memory backing the return value |
1072 | | * therefore it must outlive any use of the return value. |
1073 | | */ |
1074 | | const std::string& getPathRewrite(const Http::RequestHeaderMap& headers, |
1075 | | absl::optional<std::string>& container) const; |
1076 | | |
1077 | | void finalizePathHeader(Http::RequestHeaderMap& headers, absl::string_view matched_path, |
1078 | | bool insert_envoy_original_path) const; |
1079 | | |
1080 | | absl::optional<std::string> |
1081 | | currentUrlPathAfterRewriteWithMatchedPath(const Http::RequestHeaderMap& headers, |
1082 | | absl::string_view matched_path) const; |
1083 | | |
1084 | | private: |
1085 | | struct RuntimeData { |
1086 | | std::string fractional_runtime_key_{}; |
1087 | | envoy::type::v3::FractionalPercent fractional_runtime_default_{}; |
1088 | | }; |
1089 | | |
1090 | | /** |
1091 | | * Returns a vector of request header parsers which applied or will apply header transformations |
1092 | | * to the request in this route. |
1093 | | * @param specificity_ascend specifies whether the returned parsers will be sorted from least |
1094 | | * specific to most specific (global connection manager level header parser, virtual host |
1095 | | * level header parser and finally route-level parser.) or the reverse. |
1096 | | * @return a vector of request header parsers. |
1097 | | */ |
1098 | | absl::InlinedVector<const HeaderParser*, 3> |
1099 | | getRequestHeaderParsers(bool specificity_ascend) const; |
1100 | | |
1101 | | /** |
1102 | | * Returns a vector of response header parsers which applied or will apply header transformations |
1103 | | * to the response in this route. |
1104 | | * @param specificity_ascend specifies whether the returned parsers will be sorted from least |
1105 | | * specific to most specific (global connection manager level header parser, virtual host |
1106 | | * level header parser and finally route-level parser.) or the reverse. |
1107 | | * @return a vector of request header parsers. |
1108 | | */ |
1109 | | absl::InlinedVector<const HeaderParser*, 3> |
1110 | | getResponseHeaderParsers(bool specificity_ascend) const; |
1111 | | |
1112 | | std::unique_ptr<const RuntimeData> |
1113 | | loadRuntimeData(const envoy::config::route::v3::RouteMatch& route); |
1114 | | |
1115 | | static std::multimap<std::string, std::string> |
1116 | | parseOpaqueConfig(const envoy::config::route::v3::Route& route); |
1117 | | |
1118 | | static DecoratorConstPtr parseDecorator(const envoy::config::route::v3::Route& route); |
1119 | | |
1120 | | static RouteTracingConstPtr parseRouteTracing(const envoy::config::route::v3::Route& route); |
1121 | | |
1122 | | bool evaluateRuntimeMatch(const uint64_t random_value) const; |
1123 | | |
1124 | | bool evaluateTlsContextMatch(const StreamInfo::StreamInfo& stream_info) const; |
1125 | | |
1126 | | std::unique_ptr<HedgePolicyImpl> |
1127 | | buildHedgePolicy(HedgePolicyConstOptRef vhost_hedge_policy, |
1128 | | const envoy::config::route::v3::RouteAction& route_config) const; |
1129 | | |
1130 | | std::unique_ptr<RetryPolicyImpl> |
1131 | | buildRetryPolicy(RetryPolicyConstOptRef vhost_retry_policy, |
1132 | | const envoy::config::route::v3::RouteAction& route_config, |
1133 | | ProtobufMessage::ValidationVisitor& validation_visitor, |
1134 | | Server::Configuration::ServerFactoryContext& factory_context) const; |
1135 | | |
1136 | | std::unique_ptr<InternalRedirectPolicyImpl> |
1137 | | buildInternalRedirectPolicy(const envoy::config::route::v3::RouteAction& route_config, |
1138 | | ProtobufMessage::ValidationVisitor& validator, |
1139 | | absl::string_view current_route_name) const; |
1140 | | |
1141 | | OptionalTimeouts buildOptionalTimeouts(const envoy::config::route::v3::RouteAction& route) const; |
1142 | | template <OptionalTimeoutNames timeout_name> |
1143 | 2.61k | absl::optional<std::chrono::milliseconds> getOptionalTimeout() const { |
1144 | 2.61k | const auto timeout = optional_timeouts_.get<timeout_name>(); |
1145 | 2.61k | if (timeout.has_value()) { |
1146 | 0 | return *timeout; |
1147 | 0 | } |
1148 | 2.61k | return absl::nullopt; |
1149 | 2.61k | } std::__1::optional<std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l> > > Envoy::Router::RouteEntryImplBase::getOptionalTimeout<(Envoy::Router::RouteEntryImplBase::OptionalTimeoutNames)0>() const Line | Count | Source | 1143 | 1.30k | absl::optional<std::chrono::milliseconds> getOptionalTimeout() const { | 1144 | 1.30k | const auto timeout = optional_timeouts_.get<timeout_name>(); | 1145 | 1.30k | if (timeout.has_value()) { | 1146 | 0 | return *timeout; | 1147 | 0 | } | 1148 | 1.30k | return absl::nullopt; | 1149 | 1.30k | } |
std::__1::optional<std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l> > > Envoy::Router::RouteEntryImplBase::getOptionalTimeout<(Envoy::Router::RouteEntryImplBase::OptionalTimeoutNames)1>() const Line | Count | Source | 1143 | 1.30k | absl::optional<std::chrono::milliseconds> getOptionalTimeout() const { | 1144 | 1.30k | const auto timeout = optional_timeouts_.get<timeout_name>(); | 1145 | 1.30k | if (timeout.has_value()) { | 1146 | 0 | return *timeout; | 1147 | 0 | } | 1148 | 1.30k | return absl::nullopt; | 1149 | 1.30k | } |
Unexecuted instantiation: std::__1::optional<std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l> > > Envoy::Router::RouteEntryImplBase::getOptionalTimeout<(Envoy::Router::RouteEntryImplBase::OptionalTimeoutNames)2>() const Unexecuted instantiation: std::__1::optional<std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l> > > Envoy::Router::RouteEntryImplBase::getOptionalTimeout<(Envoy::Router::RouteEntryImplBase::OptionalTimeoutNames)3>() const Unexecuted instantiation: std::__1::optional<std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l> > > Envoy::Router::RouteEntryImplBase::getOptionalTimeout<(Envoy::Router::RouteEntryImplBase::OptionalTimeoutNames)4>() const Unexecuted instantiation: std::__1::optional<std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l> > > Envoy::Router::RouteEntryImplBase::getOptionalTimeout<(Envoy::Router::RouteEntryImplBase::OptionalTimeoutNames)5>() const |
1150 | | |
1151 | | PathMatcherSharedPtr buildPathMatcher(envoy::config::route::v3::Route route, |
1152 | | ProtobufMessage::ValidationVisitor& validator) const; |
1153 | | |
1154 | | PathRewriterSharedPtr buildPathRewriter(envoy::config::route::v3::Route route, |
1155 | | ProtobufMessage::ValidationVisitor& validator) const; |
1156 | | |
1157 | | RouteConstSharedPtr |
1158 | | pickClusterViaClusterHeader(const Http::LowerCaseString& cluster_header_name, |
1159 | | const Http::HeaderMap& headers, |
1160 | | const RouteEntryAndRoute* route_selector_override) const; |
1161 | | |
1162 | | RouteConstSharedPtr pickWeightedCluster(const Http::HeaderMap& headers, uint64_t random_value, |
1163 | | bool ignore_overflow) const; |
1164 | | |
1165 | | // Default timeout is 15s if nothing is specified in the route config. |
1166 | | static const uint64_t DEFAULT_ROUTE_TIMEOUT_MS = 15000; |
1167 | | |
1168 | | std::unique_ptr<const CorsPolicyImpl> cors_policy_; |
1169 | | // Keep an copy of the shared pointer to the shared part of the virtual host. This is needed |
1170 | | // to keep the shared part alive while the route is alive. |
1171 | | const CommonVirtualHostSharedPtr vhost_; |
1172 | | const absl::optional<Http::LowerCaseString> auto_host_rewrite_header_; |
1173 | | const Regex::CompiledMatcherPtr host_rewrite_path_regex_; |
1174 | | const std::string host_rewrite_path_regex_substitution_; |
1175 | | const std::string cluster_name_; |
1176 | | RouteStatsContextPtr route_stats_context_; |
1177 | | const Http::LowerCaseString cluster_header_name_; |
1178 | | ClusterSpecifierPluginSharedPtr cluster_specifier_plugin_; |
1179 | | const std::chrono::milliseconds timeout_; |
1180 | | const OptionalTimeouts optional_timeouts_; |
1181 | | Runtime::Loader& loader_; |
1182 | | std::unique_ptr<const RuntimeData> runtime_; |
1183 | | std::unique_ptr<const ::Envoy::Http::Utility::RedirectConfig> redirect_config_; |
1184 | | std::unique_ptr<const HedgePolicyImpl> hedge_policy_; |
1185 | | std::unique_ptr<const RetryPolicyImpl> retry_policy_; |
1186 | | std::unique_ptr<const InternalRedirectPolicyImpl> internal_redirect_policy_; |
1187 | | std::unique_ptr<const RateLimitPolicyImpl> rate_limit_policy_; |
1188 | | std::vector<ShadowPolicyPtr> shadow_policies_; |
1189 | | std::vector<Http::HeaderUtility::HeaderDataPtr> config_headers_; |
1190 | | std::vector<ConfigUtility::QueryParameterMatcherPtr> config_query_parameters_; |
1191 | | std::unique_ptr<const WeightedClustersConfig> weighted_clusters_config_; |
1192 | | |
1193 | | UpgradeMap upgrade_map_; |
1194 | | std::unique_ptr<const Http::HashPolicyImpl> hash_policy_; |
1195 | | MetadataMatchCriteriaConstPtr metadata_match_criteria_; |
1196 | | TlsContextMatchCriteriaConstPtr tls_context_match_criteria_; |
1197 | | HeaderParserPtr request_headers_parser_; |
1198 | | HeaderParserPtr response_headers_parser_; |
1199 | | RouteMetadataPackPtr metadata_; |
1200 | | const std::vector<Envoy::Matchers::MetadataMatcher> dynamic_metadata_; |
1201 | | |
1202 | | // TODO(danielhochman): refactor multimap into unordered_map since JSON is unordered map. |
1203 | | const std::multimap<std::string, std::string> opaque_config_; |
1204 | | |
1205 | | const DecoratorConstPtr decorator_; |
1206 | | const RouteTracingConstPtr route_tracing_; |
1207 | | std::string direct_response_body_; |
1208 | | PerFilterConfigs per_filter_configs_; |
1209 | | const std::string route_name_; |
1210 | | TimeSource& time_source_; |
1211 | | EarlyDataPolicyPtr early_data_policy_; |
1212 | | |
1213 | | // Keep small members (bools and enums) at the end of class, to reduce alignment overhead. |
1214 | | uint32_t retry_shadow_buffer_limit_{std::numeric_limits<uint32_t>::max()}; |
1215 | | const absl::optional<Http::Code> direct_response_code_; |
1216 | | const Http::Code cluster_not_found_response_code_; |
1217 | | const Upstream::ResourcePriority priority_; |
1218 | | const bool auto_host_rewrite_ : 1; |
1219 | | const bool append_xfh_ : 1; |
1220 | | const bool using_new_timeouts_ : 1; |
1221 | | const bool match_grpc_ : 1; |
1222 | | const bool case_sensitive_ : 1; |
1223 | | bool include_vh_rate_limits_ : 1; |
1224 | | }; |
1225 | | |
1226 | | /** |
1227 | | * Route entry implementation for uri template match based routing. |
1228 | | */ |
1229 | | class UriTemplateMatcherRouteEntryImpl : public RouteEntryImplBase { |
1230 | | public: |
1231 | | UriTemplateMatcherRouteEntryImpl(const CommonVirtualHostSharedPtr& vhost, |
1232 | | const envoy::config::route::v3::Route& route, |
1233 | | const OptionalHttpFilters& optional_http_filters, |
1234 | | Server::Configuration::ServerFactoryContext& factory_context, |
1235 | | ProtobufMessage::ValidationVisitor& validator); |
1236 | | |
1237 | | // Router::PathMatchCriterion |
1238 | 0 | const std::string& matcher() const override { return uri_template_; } |
1239 | 0 | PathMatchType matchType() const override { return PathMatchType::Template; } |
1240 | | |
1241 | | // Router::Matchable |
1242 | | RouteConstSharedPtr matches(const Http::RequestHeaderMap& headers, |
1243 | | const StreamInfo::StreamInfo& stream_info, |
1244 | | uint64_t random_value) const override; |
1245 | | |
1246 | | // Router::DirectResponseEntry |
1247 | | void rewritePathHeader(Http::RequestHeaderMap& headers, |
1248 | | bool insert_envoy_original_path) const override; |
1249 | | |
1250 | | // Router::RouteEntry |
1251 | | absl::optional<std::string> |
1252 | | currentUrlPathAfterRewrite(const Http::RequestHeaderMap& headers) const override; |
1253 | | |
1254 | | private: |
1255 | | const std::string uri_template_; |
1256 | | }; |
1257 | | |
1258 | | /** |
1259 | | * Route entry implementation for prefix path match routing. |
1260 | | */ |
1261 | | class PrefixRouteEntryImpl : public RouteEntryImplBase { |
1262 | | public: |
1263 | | PrefixRouteEntryImpl(const CommonVirtualHostSharedPtr& vhost, |
1264 | | const envoy::config::route::v3::Route& route, |
1265 | | const OptionalHttpFilters& optional_http_filters, |
1266 | | Server::Configuration::ServerFactoryContext& factory_context, |
1267 | | ProtobufMessage::ValidationVisitor& validator); |
1268 | | |
1269 | | // Router::PathMatchCriterion |
1270 | 444 | const std::string& matcher() const override { |
1271 | 444 | return path_matcher_ != nullptr ? path_matcher_->matcher().matcher().prefix() : EMPTY_STRING; |
1272 | 444 | } |
1273 | 0 | PathMatchType matchType() const override { return PathMatchType::Prefix; } |
1274 | | |
1275 | | // Router::Matchable |
1276 | | RouteConstSharedPtr matches(const Http::RequestHeaderMap& headers, |
1277 | | const StreamInfo::StreamInfo& stream_info, |
1278 | | uint64_t random_value) const override; |
1279 | | |
1280 | | // Router::DirectResponseEntry |
1281 | | void rewritePathHeader(Http::RequestHeaderMap& headers, |
1282 | | bool insert_envoy_original_path) const override; |
1283 | | |
1284 | | // Router::RouteEntry |
1285 | | absl::optional<std::string> |
1286 | | currentUrlPathAfterRewrite(const Http::RequestHeaderMap& headers) const override; |
1287 | | |
1288 | | private: |
1289 | | const Matchers::PathMatcherConstSharedPtr path_matcher_; |
1290 | | }; |
1291 | | |
1292 | | /** |
1293 | | * Route entry implementation for exact path match routing. |
1294 | | */ |
1295 | | class PathRouteEntryImpl : public RouteEntryImplBase { |
1296 | | public: |
1297 | | PathRouteEntryImpl(const CommonVirtualHostSharedPtr& vhost, |
1298 | | const envoy::config::route::v3::Route& route, |
1299 | | const OptionalHttpFilters& optional_http_filters, |
1300 | | Server::Configuration::ServerFactoryContext& factory_context, |
1301 | | ProtobufMessage::ValidationVisitor& validator); |
1302 | | |
1303 | | // Router::PathMatchCriterion |
1304 | 92 | const std::string& matcher() const override { |
1305 | 92 | return path_matcher_ != nullptr ? path_matcher_->matcher().matcher().exact() : EMPTY_STRING; |
1306 | 92 | } |
1307 | 0 | PathMatchType matchType() const override { return PathMatchType::Exact; } |
1308 | | |
1309 | | // Router::Matchable |
1310 | | RouteConstSharedPtr matches(const Http::RequestHeaderMap& headers, |
1311 | | const StreamInfo::StreamInfo& stream_info, |
1312 | | uint64_t random_value) const override; |
1313 | | |
1314 | | // Router::DirectResponseEntry |
1315 | | void rewritePathHeader(Http::RequestHeaderMap& headers, |
1316 | | bool insert_envoy_original_path) const override; |
1317 | | |
1318 | | // Router::RouteEntry |
1319 | | absl::optional<std::string> |
1320 | | currentUrlPathAfterRewrite(const Http::RequestHeaderMap& headers) const override; |
1321 | | |
1322 | | private: |
1323 | | const Matchers::PathMatcherConstSharedPtr path_matcher_; |
1324 | | }; |
1325 | | |
1326 | | /** |
1327 | | * Route entry implementation for regular expression match routing. |
1328 | | */ |
1329 | | class RegexRouteEntryImpl : public RouteEntryImplBase { |
1330 | | public: |
1331 | | RegexRouteEntryImpl(const CommonVirtualHostSharedPtr& vhost, |
1332 | | const envoy::config::route::v3::Route& route, |
1333 | | const OptionalHttpFilters& optional_http_filters, |
1334 | | Server::Configuration::ServerFactoryContext& factory_context, |
1335 | | ProtobufMessage::ValidationVisitor& validator); |
1336 | | |
1337 | | // Router::PathMatchCriterion |
1338 | 0 | const std::string& matcher() const override { |
1339 | 0 | return path_matcher_ != nullptr ? path_matcher_->matcher().matcher().safe_regex().regex() |
1340 | 0 | : EMPTY_STRING; |
1341 | 0 | } |
1342 | 0 | PathMatchType matchType() const override { return PathMatchType::Regex; } |
1343 | | |
1344 | | // Router::Matchable |
1345 | | RouteConstSharedPtr matches(const Http::RequestHeaderMap& headers, |
1346 | | const StreamInfo::StreamInfo& stream_info, |
1347 | | uint64_t random_value) const override; |
1348 | | |
1349 | | // Router::DirectResponseEntry |
1350 | | void rewritePathHeader(Http::RequestHeaderMap& headers, |
1351 | | bool insert_envoy_original_path) const override; |
1352 | | |
1353 | | // Router::RouteEntry |
1354 | | absl::optional<std::string> |
1355 | | currentUrlPathAfterRewrite(const Http::RequestHeaderMap& headers) const override; |
1356 | | |
1357 | | private: |
1358 | | const Matchers::PathMatcherConstSharedPtr path_matcher_; |
1359 | | }; |
1360 | | |
1361 | | /** |
1362 | | * Route entry implementation for CONNECT requests. |
1363 | | */ |
1364 | | class ConnectRouteEntryImpl : public RouteEntryImplBase { |
1365 | | public: |
1366 | | ConnectRouteEntryImpl(const CommonVirtualHostSharedPtr& vhost, |
1367 | | const envoy::config::route::v3::Route& route, |
1368 | | const OptionalHttpFilters& optional_http_filters, |
1369 | | Server::Configuration::ServerFactoryContext& factory_context, |
1370 | | ProtobufMessage::ValidationVisitor& validator); |
1371 | | |
1372 | | // Router::PathMatchCriterion |
1373 | 0 | const std::string& matcher() const override { return EMPTY_STRING; } |
1374 | 0 | PathMatchType matchType() const override { return PathMatchType::None; } |
1375 | | |
1376 | | // Router::Matchable |
1377 | | RouteConstSharedPtr matches(const Http::RequestHeaderMap& headers, |
1378 | | const StreamInfo::StreamInfo& stream_info, |
1379 | | uint64_t random_value) const override; |
1380 | | |
1381 | | // Router::DirectResponseEntry |
1382 | | void rewritePathHeader(Http::RequestHeaderMap&, bool) const override; |
1383 | | |
1384 | | // Router::RouteEntry |
1385 | | absl::optional<std::string> |
1386 | | currentUrlPathAfterRewrite(const Http::RequestHeaderMap& headers) const override; |
1387 | | |
1388 | 535 | bool supportsPathlessHeaders() const override { return true; } |
1389 | | }; |
1390 | | |
1391 | | /** |
1392 | | * Route entry implementation for path separated prefix match routing. |
1393 | | */ |
1394 | | class PathSeparatedPrefixRouteEntryImpl : public RouteEntryImplBase { |
1395 | | public: |
1396 | | PathSeparatedPrefixRouteEntryImpl(const CommonVirtualHostSharedPtr& vhost, |
1397 | | const envoy::config::route::v3::Route& route, |
1398 | | const OptionalHttpFilters& optional_http_filters, |
1399 | | Server::Configuration::ServerFactoryContext& factory_context, |
1400 | | ProtobufMessage::ValidationVisitor& validator); |
1401 | | |
1402 | | // Router::PathMatchCriterion |
1403 | 359 | const std::string& matcher() const override { |
1404 | 359 | return path_matcher_ != nullptr ? path_matcher_->matcher().matcher().prefix() : EMPTY_STRING; |
1405 | 359 | } |
1406 | 0 | PathMatchType matchType() const override { return PathMatchType::PathSeparatedPrefix; } |
1407 | | |
1408 | | // Router::Matchable |
1409 | | RouteConstSharedPtr matches(const Http::RequestHeaderMap& headers, |
1410 | | const StreamInfo::StreamInfo& stream_info, |
1411 | | uint64_t random_value) const override; |
1412 | | |
1413 | | // Router::DirectResponseEntry |
1414 | | void rewritePathHeader(Http::RequestHeaderMap& headers, |
1415 | | bool insert_envoy_original_path) const override; |
1416 | | |
1417 | | // Router::RouteEntry |
1418 | | absl::optional<std::string> |
1419 | | currentUrlPathAfterRewrite(const Http::RequestHeaderMap& headers) const override; |
1420 | | |
1421 | | private: |
1422 | | const Matchers::PathMatcherConstSharedPtr path_matcher_; |
1423 | | }; |
1424 | | |
1425 | | // Contextual information used to construct the route actions for a match tree. |
1426 | | struct RouteActionContext { |
1427 | | const CommonVirtualHostSharedPtr& vhost; |
1428 | | const OptionalHttpFilters& optional_http_filters; |
1429 | | Server::Configuration::ServerFactoryContext& factory_context; |
1430 | | }; |
1431 | | |
1432 | | // Action used with the matching tree to specify route to use for an incoming stream. |
1433 | | class RouteMatchAction : public Matcher::ActionBase<envoy::config::route::v3::Route> { |
1434 | | public: |
1435 | 1.50k | explicit RouteMatchAction(RouteEntryImplBaseConstSharedPtr route) : route_(std::move(route)) {} |
1436 | | |
1437 | 1.50k | RouteEntryImplBaseConstSharedPtr route() const { return route_; } |
1438 | | |
1439 | | private: |
1440 | | const RouteEntryImplBaseConstSharedPtr route_; |
1441 | | }; |
1442 | | |
1443 | | // Registered factory for RouteMatchAction. |
1444 | | class RouteMatchActionFactory : public Matcher::ActionFactory<RouteActionContext> { |
1445 | | public: |
1446 | | Matcher::ActionFactoryCb |
1447 | | createActionFactoryCb(const Protobuf::Message& config, RouteActionContext& context, |
1448 | | ProtobufMessage::ValidationVisitor& validation_visitor) override; |
1449 | 220 | std::string name() const override { return "route"; } |
1450 | 56.0k | ProtobufTypes::MessagePtr createEmptyConfigProto() override { |
1451 | 56.0k | return std::make_unique<envoy::config::route::v3::Route>(); |
1452 | 56.0k | } |
1453 | | }; |
1454 | | |
1455 | | DECLARE_FACTORY(RouteMatchActionFactory); |
1456 | | |
1457 | | // Similar to RouteMatchAction, but accepts v3::RouteList instead of v3::Route. |
1458 | | class RouteListMatchAction : public Matcher::ActionBase<envoy::config::route::v3::RouteList> { |
1459 | | public: |
1460 | | explicit RouteListMatchAction(std::vector<RouteEntryImplBaseConstSharedPtr> routes) |
1461 | 0 | : routes_(std::move(routes)) {} |
1462 | | |
1463 | 0 | const std::vector<RouteEntryImplBaseConstSharedPtr>& routes() const { return routes_; } |
1464 | | |
1465 | | private: |
1466 | | const std::vector<RouteEntryImplBaseConstSharedPtr> routes_; |
1467 | | }; |
1468 | | |
1469 | | // Registered factory for RouteListMatchAction. |
1470 | | class RouteListMatchActionFactory : public Matcher::ActionFactory<RouteActionContext> { |
1471 | | public: |
1472 | | Matcher::ActionFactoryCb |
1473 | | createActionFactoryCb(const Protobuf::Message& config, RouteActionContext& context, |
1474 | | ProtobufMessage::ValidationVisitor& validation_visitor) override; |
1475 | 220 | std::string name() const override { return "route_match_action"; } |
1476 | 2 | ProtobufTypes::MessagePtr createEmptyConfigProto() override { |
1477 | 2 | return std::make_unique<envoy::config::route::v3::RouteList>(); |
1478 | 2 | } |
1479 | | }; |
1480 | | |
1481 | | DECLARE_FACTORY(RouteListMatchActionFactory); |
1482 | | |
1483 | | /** |
1484 | | * Wraps the route configuration which matches an incoming request headers to a backend cluster. |
1485 | | * This is split out mainly to help with unit testing. |
1486 | | */ |
1487 | | class RouteMatcher { |
1488 | | public: |
1489 | | RouteMatcher(const envoy::config::route::v3::RouteConfiguration& config, |
1490 | | const OptionalHttpFilters& optional_http_filters, |
1491 | | const CommonConfigSharedPtr& global_route_config, |
1492 | | Server::Configuration::ServerFactoryContext& factory_context, |
1493 | | ProtobufMessage::ValidationVisitor& validator, bool validate_clusters); |
1494 | | |
1495 | | RouteConstSharedPtr route(const RouteCallback& cb, const Http::RequestHeaderMap& headers, |
1496 | | const StreamInfo::StreamInfo& stream_info, uint64_t random_value) const; |
1497 | | |
1498 | | const VirtualHostImpl* findVirtualHost(const Http::RequestHeaderMap& headers) const; |
1499 | | |
1500 | | private: |
1501 | | using WildcardVirtualHosts = |
1502 | | std::map<int64_t, absl::node_hash_map<std::string, VirtualHostSharedPtr>, std::greater<>>; |
1503 | | using SubstringFunction = std::function<absl::string_view(absl::string_view, int)>; |
1504 | | const VirtualHostImpl* findWildcardVirtualHost(absl::string_view host, |
1505 | | const WildcardVirtualHosts& wildcard_virtual_hosts, |
1506 | | SubstringFunction substring_function) const; |
1507 | 255 | bool ignorePortInHostMatching() const { return ignore_port_in_host_matching_; } |
1508 | | |
1509 | | Stats::ScopeSharedPtr vhost_scope_; |
1510 | | absl::node_hash_map<std::string, VirtualHostSharedPtr> virtual_hosts_; |
1511 | | // std::greater as a minor optimization to iterate from more to less specific |
1512 | | // |
1513 | | // A note on using an unordered_map versus a vector of (string, VirtualHostSharedPtr) pairs: |
1514 | | // |
1515 | | // Based on local benchmarks, each vector entry costs around 20ns for recall and (string) |
1516 | | // comparison with a fixed cost of about 25ns. For unordered_map, the empty map costs about 65ns |
1517 | | // and climbs to about 110ns once there are any entries. |
1518 | | // |
1519 | | // The break-even is 4 entries. |
1520 | | WildcardVirtualHosts wildcard_virtual_host_suffixes_; |
1521 | | WildcardVirtualHosts wildcard_virtual_host_prefixes_; |
1522 | | |
1523 | | VirtualHostSharedPtr default_virtual_host_; |
1524 | | const bool ignore_port_in_host_matching_{false}; |
1525 | | }; |
1526 | | |
1527 | | /** |
1528 | | * Shared part of the route configuration implementation. |
1529 | | */ |
1530 | | class CommonConfigImpl : public CommonConfig { |
1531 | | public: |
1532 | | CommonConfigImpl(const envoy::config::route::v3::RouteConfiguration& config, |
1533 | | const OptionalHttpFilters& optional_http_filters, |
1534 | | Server::Configuration::ServerFactoryContext& factory_context, |
1535 | | ProtobufMessage::ValidationVisitor& validator); |
1536 | | |
1537 | 2.47k | const HeaderParser& requestHeaderParser() const { |
1538 | 2.47k | if (request_headers_parser_ != nullptr) { |
1539 | 520 | return *request_headers_parser_; |
1540 | 520 | } |
1541 | 1.95k | return HeaderParser::defaultParser(); |
1542 | 2.47k | } |
1543 | 1.37k | const HeaderParser& responseHeaderParser() const { |
1544 | 1.37k | if (response_headers_parser_ != nullptr) { |
1545 | 170 | return *response_headers_parser_; |
1546 | 170 | } |
1547 | 1.20k | return HeaderParser::defaultParser(); |
1548 | 1.37k | } |
1549 | | |
1550 | 1.10k | const RouteSpecificFilterConfig* perFilterConfig(const std::string& name) const { |
1551 | 1.10k | return per_filter_configs_.get(name); |
1552 | 1.10k | } |
1553 | 2.57k | absl::optional<bool> filterDisabled(absl::string_view config_name) const { |
1554 | 2.57k | return per_filter_configs_.disabled(config_name); |
1555 | 2.57k | } |
1556 | | |
1557 | | // Router::CommonConfig |
1558 | 1.63k | const std::list<Http::LowerCaseString>& internalOnlyHeaders() const override { |
1559 | 1.63k | return internal_only_headers_; |
1560 | 1.63k | } |
1561 | 0 | const std::string& name() const override { return name_; } |
1562 | 0 | bool usesVhds() const override { return uses_vhds_; } |
1563 | 3.84k | bool mostSpecificHeaderMutationsWins() const override { |
1564 | 3.84k | return most_specific_header_mutations_wins_; |
1565 | 3.84k | } |
1566 | 84.6k | uint32_t maxDirectResponseBodySizeBytes() const override { |
1567 | 84.6k | return max_direct_response_body_size_bytes_; |
1568 | 84.6k | } |
1569 | 20.8k | const std::vector<ShadowPolicyPtr>& shadowPolicies() const { return shadow_policies_; } |
1570 | | ClusterSpecifierPluginSharedPtr clusterSpecifierPlugin(absl::string_view provider) const; |
1571 | 10.7k | bool ignorePathParametersInPathMatching() const { |
1572 | 10.7k | return ignore_path_parameters_in_path_matching_; |
1573 | 10.7k | } |
1574 | | const envoy::config::core::v3::Metadata& metadata() const override; |
1575 | | const Envoy::Config::TypedMetadata& typedMetadata() const override; |
1576 | | |
1577 | | private: |
1578 | | std::list<Http::LowerCaseString> internal_only_headers_; |
1579 | | HeaderParserPtr request_headers_parser_; |
1580 | | HeaderParserPtr response_headers_parser_; |
1581 | | const std::string name_; |
1582 | | Stats::SymbolTable& symbol_table_; |
1583 | | std::vector<ShadowPolicyPtr> shadow_policies_; |
1584 | | // Cluster specifier plugins/providers. |
1585 | | absl::flat_hash_map<std::string, ClusterSpecifierPluginSharedPtr> cluster_specifier_plugins_; |
1586 | | PerFilterConfigs per_filter_configs_; |
1587 | | RouteMetadataPackPtr metadata_; |
1588 | | // Keep small members (bools and enums) at the end of class, to reduce alignment overhead. |
1589 | | const uint32_t max_direct_response_body_size_bytes_; |
1590 | | const bool uses_vhds_ : 1; |
1591 | | const bool most_specific_header_mutations_wins_ : 1; |
1592 | | const bool ignore_path_parameters_in_path_matching_ : 1; |
1593 | | }; |
1594 | | |
1595 | | /** |
1596 | | * Implementation of Config that reads from a proto file. |
1597 | | */ |
1598 | | class ConfigImpl : public Config { |
1599 | | public: |
1600 | | ConfigImpl(const envoy::config::route::v3::RouteConfiguration& config, |
1601 | | const OptionalHttpFilters& optional_http_filters, |
1602 | | Server::Configuration::ServerFactoryContext& factory_context, |
1603 | | ProtobufMessage::ValidationVisitor& validator, bool validate_clusters_default); |
1604 | | |
1605 | 0 | bool virtualHostExists(const Http::RequestHeaderMap& headers) const { |
1606 | 0 | return route_matcher_->findVirtualHost(headers) != nullptr; |
1607 | 0 | } |
1608 | | |
1609 | | // Router::Config |
1610 | | RouteConstSharedPtr route(const Http::RequestHeaderMap& headers, |
1611 | | const StreamInfo::StreamInfo& stream_info, |
1612 | 9.13k | uint64_t random_value) const override { |
1613 | 9.13k | return route(nullptr, headers, stream_info, random_value); |
1614 | 9.13k | } |
1615 | | RouteConstSharedPtr route(const RouteCallback& cb, const Http::RequestHeaderMap& headers, |
1616 | | const StreamInfo::StreamInfo& stream_info, |
1617 | | uint64_t random_value) const override; |
1618 | 1.63k | const std::list<Http::LowerCaseString>& internalOnlyHeaders() const override { |
1619 | 1.63k | return shared_config_->internalOnlyHeaders(); |
1620 | 1.63k | } |
1621 | 0 | const std::string& name() const override { return shared_config_->name(); } |
1622 | 0 | bool usesVhds() const override { return shared_config_->usesVhds(); } |
1623 | 0 | bool mostSpecificHeaderMutationsWins() const override { |
1624 | 0 | return shared_config_->mostSpecificHeaderMutationsWins(); |
1625 | 0 | } |
1626 | 0 | uint32_t maxDirectResponseBodySizeBytes() const override { |
1627 | 0 | return shared_config_->maxDirectResponseBodySizeBytes(); |
1628 | 0 | } |
1629 | 0 | const std::vector<ShadowPolicyPtr>& shadowPolicies() const { |
1630 | 0 | return shared_config_->shadowPolicies(); |
1631 | 0 | } |
1632 | 0 | bool ignorePathParametersInPathMatching() const { |
1633 | 0 | return shared_config_->ignorePathParametersInPathMatching(); |
1634 | 0 | } |
1635 | 0 | const envoy::config::core::v3::Metadata& metadata() const override { |
1636 | 0 | return shared_config_->metadata(); |
1637 | 0 | } |
1638 | 0 | const Envoy::Config::TypedMetadata& typedMetadata() const override { |
1639 | 0 | return shared_config_->typedMetadata(); |
1640 | 0 | } |
1641 | | |
1642 | | private: |
1643 | | CommonConfigSharedPtr shared_config_; |
1644 | | std::unique_ptr<RouteMatcher> route_matcher_; |
1645 | | }; |
1646 | | |
1647 | | /** |
1648 | | * Implementation of Config that is empty. |
1649 | | */ |
1650 | | class NullConfigImpl : public Config { |
1651 | | public: |
1652 | | // Router::Config |
1653 | | RouteConstSharedPtr route(const Http::RequestHeaderMap&, const StreamInfo::StreamInfo&, |
1654 | 0 | uint64_t) const override { |
1655 | 0 | return nullptr; |
1656 | 0 | } |
1657 | | |
1658 | | RouteConstSharedPtr route(const RouteCallback&, const Http::RequestHeaderMap&, |
1659 | 2.65k | const StreamInfo::StreamInfo&, uint64_t) const override { |
1660 | 2.65k | return nullptr; |
1661 | 2.65k | } |
1662 | | |
1663 | 2.64k | const std::list<Http::LowerCaseString>& internalOnlyHeaders() const override { |
1664 | 2.64k | return internal_only_headers_; |
1665 | 2.64k | } |
1666 | | |
1667 | 0 | const std::string& name() const override { return name_; } |
1668 | 0 | bool usesVhds() const override { return false; } |
1669 | 0 | bool mostSpecificHeaderMutationsWins() const override { return false; } |
1670 | 0 | uint32_t maxDirectResponseBodySizeBytes() const override { return 0; } |
1671 | | const envoy::config::core::v3::Metadata& metadata() const override; |
1672 | | const Envoy::Config::TypedMetadata& typedMetadata() const override; |
1673 | | |
1674 | | private: |
1675 | | std::list<Http::LowerCaseString> internal_only_headers_; |
1676 | | const std::string name_; |
1677 | | }; |
1678 | | |
1679 | | } // namespace Router |
1680 | | } // namespace Envoy |