1
#pragma once
2

            
3
#include "envoy/router/router.h"
4

            
5
#include "source/common/config/metadata.h"
6

            
7
namespace Envoy {
8
namespace Router {
9

            
10
/**
11
 * Wrapper class around Router::Route that delegates all method calls to the RouteConstSharedPtr
12
 * base route it wraps around.
13
 *
14
 * Intended to be used as a route mutability mechanism, where a filter can create a derived class of
15
 * DelegatingRoute and override specific methods (e.g. routeEntry) while preserving the rest of the
16
 * properties/behavior of the base route.
17
 */
18
template <class Interface> class DelegatingRouteBase : public Interface {
19
public:
20
419
  explicit DelegatingRouteBase(Router::RouteConstSharedPtr route) : base_route_(std::move(route)) {
21
419
    ASSERT(base_route_ != nullptr);
22
419
  }
23

            
24
  // Router::Route
25
298
  const Router::DirectResponseEntry* directResponseEntry() const override {
26
298
    return base_route_->directResponseEntry();
27
298
  }
28
1
  const Router::RouteEntry* routeEntry() const override { return base_route_->routeEntry(); }
29
2
  const Router::Decorator* decorator() const override { return base_route_->decorator(); }
30
1
  const Router::RouteTracing* tracingConfig() const override {
31
1
    return base_route_->tracingConfig();
32
1
  }
33
  const RouteSpecificFilterConfig*
34
139
  mostSpecificPerFilterConfig(absl::string_view name) const override {
35
139
    return base_route_->mostSpecificPerFilterConfig(name);
36
139
  }
37
5
  RouteSpecificFilterConfigs perFilterConfigs(absl::string_view filter_name) const override {
38
5
    return base_route_->perFilterConfigs(filter_name);
39
5
  }
40
2
  const envoy::config::core::v3::Metadata& metadata() const override {
41
2
    return base_route_->metadata();
42
2
  }
43
3
  const Envoy::Config::TypedMetadata& typedMetadata() const override {
44
3
    return base_route_->typedMetadata();
45
3
  }
46
448
  absl::optional<bool> filterDisabled(absl::string_view name) const override {
47
448
    return base_route_->filterDisabled(name);
48
448
  }
49
2
  const std::string& routeName() const override { return base_route_->routeName(); }
50
989
  const VirtualHostConstSharedPtr& virtualHost() const override {
51
989
    return base_route_->virtualHost();
52
989
  }
53

            
54
protected:
55
  const Router::RouteConstSharedPtr base_route_;
56
};
57

            
58
using DelegatingRoute = DelegatingRouteBase<Route>;
59

            
60
/**
61
 * Wrapper class around Router::RouteEntryAndRoute that delegates all method calls to the
62
 * RouteConstSharedPtr base route it wraps around.
63
 *
64
 * Intended to be used when a filter wants to override the routeEntry() method.
65
 * See example with SetRouteFilter in test/integration/filters.
66
 */
67
class DelegatingRouteEntry : public DelegatingRouteBase<RouteEntryAndRoute> {
68
public:
69
  explicit DelegatingRouteEntry(RouteConstSharedPtr route)
70
418
      : DelegatingRouteBase(std::move(route)), base_route_entry_(base_route_->routeEntry()) {
71
418
    ASSERT(base_route_entry_ != nullptr);
72
418
    ASSERT(base_route_->directResponseEntry() == nullptr);
73
418
  }
74

            
75
  // Override the routeEntry to return this. By this way, the derived class of this class can
76
  // override the methods of Router::RouteEntry directly.
77

            
78
  // Router::Route
79
2583
  const Router::RouteEntry* routeEntry() const override { return this; }
80

            
81
  // Router::ResponseEntry
82
  void finalizeResponseHeaders(Http::ResponseHeaderMap& headers, const Formatter::Context& context,
83
                               const StreamInfo::StreamInfo& stream_info) const override;
84
  Http::HeaderTransforms responseHeaderTransforms(const StreamInfo::StreamInfo& stream_info,
85
                                                  bool do_formatting = true) const override;
86

            
87
  // Router::RouteEntry
88
  const std::string& clusterName() const override;
89
  Http::Code clusterNotFoundResponseCode() const override;
90
  const CorsPolicy* corsPolicy() const override;
91
  std::string currentUrlPathAfterRewrite(const Http::RequestHeaderMap& headers,
92
                                         const Formatter::Context& context,
93
                                         const StreamInfo::StreamInfo& stream_info) const override;
94
  void finalizeRequestHeaders(Http::RequestHeaderMap& headers, const Formatter::Context& context,
95
                              const StreamInfo::StreamInfo& stream_info,
96
                              bool insert_envoy_original_path) const override;
97
  Http::HeaderTransforms requestHeaderTransforms(const StreamInfo::StreamInfo& stream_info,
98
                                                 bool do_formatting = true) const override;
99

            
100
  const Http::HashPolicy* hashPolicy() const override;
101
  const HedgePolicy& hedgePolicy() const override;
102
  Upstream::ResourcePriority priority() const override;
103
  const RateLimitPolicy& rateLimitPolicy() const override;
104
  const RetryPolicyConstSharedPtr& retryPolicy() const override;
105
  const Router::PathMatcherSharedPtr& pathMatcher() const override;
106
  const Router::PathRewriterSharedPtr& pathRewriter() const override;
107
  const InternalRedirectPolicy& internalRedirectPolicy() const override;
108
  uint64_t requestBodyBufferLimit() const override;
109
  const std::vector<Router::ShadowPolicyPtr>& shadowPolicies() const override;
110
  std::chrono::milliseconds timeout() const override;
111
  absl::optional<std::chrono::milliseconds> idleTimeout() const override;
112
  absl::optional<std::chrono::milliseconds> flushTimeout() const override;
113
  bool usingNewTimeouts() const override;
114
  absl::optional<std::chrono::milliseconds> maxStreamDuration() const override;
115
  absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderMax() const override;
116
  absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderOffset() const override;
117
  absl::optional<std::chrono::milliseconds> maxGrpcTimeout() const override;
118
  absl::optional<std::chrono::milliseconds> grpcTimeoutOffset() const override;
119
  bool autoHostRewrite() const override;
120
  bool appendXfh() const override;
121
  const MetadataMatchCriteria* metadataMatchCriteria() const override;
122
  const std::multimap<std::string, std::string>& opaqueConfig() const override;
123
  bool includeVirtualHostRateLimits() const override;
124
  const TlsContextMatchCriteria* tlsContextMatchCriteria() const override;
125
  const PathMatchCriterion& pathMatchCriterion() const override;
126
  bool includeAttemptCountInRequest() const override;
127
  bool includeAttemptCountInResponse() const override;
128
  const UpgradeMap& upgradeMap() const override;
129
  const ConnectConfigOptRef connectConfig() const override;
130
  const EarlyDataPolicy& earlyDataPolicy() const override;
131
  const RouteStatsContextOptRef routeStatsContext() const override;
132
  void refreshRouteCluster(const Http::RequestHeaderMap& headers,
133
                           const StreamInfo::StreamInfo& stream_info) const override;
134

            
135
private:
136
  const RouteEntry* base_route_entry_{};
137
};
138

            
139
/**
140
 * A DynamicRouteEntry is a DelegatingRouteEntry that overrides the clusterName() method.
141
 * The cluster name is determined by the filter that created this route entry.
142
 */
143
class DynamicRouteEntry : public DelegatingRouteEntry {
144
public:
145
  DynamicRouteEntry(RouteConstSharedPtr route, std::string&& cluster_name)
146
394
      : DelegatingRouteEntry(std::move(route)), cluster_name_(std::move(cluster_name)) {}
147

            
148
460
  const std::string& clusterName() const override { return cluster_name_; }
149

            
150
private:
151
  const std::string cluster_name_;
152
};
153

            
154
} // namespace Router
155
} // namespace Envoy