1
#pragma once
2

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

            
5
#include "source/common/http/hash_policy.h"
6
#include "source/common/protobuf/message_validator_impl.h"
7
#include "source/common/router/config_impl.h"
8
#include "source/common/upstream/retry_factory.h"
9
#include "source/extensions/early_data/default_early_data_policy.h"
10

            
11
namespace Envoy {
12
namespace Http {
13

            
14
struct NullHedgePolicy : public Router::HedgePolicy {
15
  // Router::HedgePolicy
16
1
  uint32_t initialRequests() const override { return 1; }
17
1
  const envoy::type::v3::FractionalPercent& additionalRequestChance() const override {
18
1
    return additional_request_chance_;
19
1
  }
20
3084
  bool hedgeOnPerTryTimeout() const override { return false; }
21

            
22
  const envoy::type::v3::FractionalPercent additional_request_chance_;
23
};
24

            
25
struct NullRateLimitPolicy : public Router::RateLimitPolicy {
26
  // Router::RateLimitPolicy
27
  const std::vector<std::reference_wrapper<const Router::RateLimitPolicyEntry>>&
28
1
  getApplicableRateLimit(uint64_t) const override {
29
1
    return rate_limit_policy_entry_;
30
1
  }
31
2
  bool empty() const override { return true; }
32

            
33
  static const std::vector<std::reference_wrapper<const Router::RateLimitPolicyEntry>>
34
      rate_limit_policy_entry_;
35
};
36

            
37
struct NullCommonConfig : public Router::CommonConfig {
38
1
  const std::vector<LowerCaseString>& internalOnlyHeaders() const override {
39
1
    return internal_only_headers_;
40
1
  }
41

            
42
1
  const std::string& name() const override { return EMPTY_STRING; }
43
1
  bool usesVhds() const override { return false; }
44
1
  bool mostSpecificHeaderMutationsWins() const override { return false; }
45
  uint32_t maxDirectResponseBodySizeBytes() const override { return 0; }
46
  const envoy::config::core::v3::Metadata& metadata() const override {
47
    return Router::DefaultRouteMetadataPack::get().proto_metadata_;
48
  }
49
  const Envoy::Config::TypedMetadata& typedMetadata() const override {
50
    return Router::DefaultRouteMetadataPack::get().typed_metadata_;
51
  }
52

            
53
  static const std::vector<LowerCaseString> internal_only_headers_;
54
};
55

            
56
struct NullVirtualHost : public Router::VirtualHost {
57
  // Router::VirtualHost
58
  const std::string& name() const override { return EMPTY_STRING; }
59
3627
  Stats::StatName statName() const override { return {}; }
60
1
  const Router::RateLimitPolicy& rateLimitPolicy() const override { return rate_limit_policy_; }
61
1
  const Router::CorsPolicy* corsPolicy() const override { return nullptr; }
62
2
  const Router::CommonConfig& routeConfig() const override { return route_configuration_; }
63
1
  bool includeAttemptCountInRequest() const override { return false; }
64
1
  bool includeAttemptCountInResponse() const override { return false; }
65
3080
  bool includeIsTimeoutRetryHeader() const override { return false; }
66
  const Router::RouteSpecificFilterConfig*
67
  mostSpecificPerFilterConfig(absl::string_view) const override {
68
    return nullptr;
69
  }
70
  Router::RouteSpecificFilterConfigs perFilterConfigs(absl::string_view) const override {
71
    return {};
72
  }
73
  const envoy::config::core::v3::Metadata& metadata() const override {
74
    return Router::DefaultRouteMetadataPack::get().proto_metadata_;
75
  }
76
  const Envoy::Config::TypedMetadata& typedMetadata() const override {
77
    return Router::DefaultRouteMetadataPack::get().typed_metadata_;
78
  }
79
3083
  const Router::VirtualCluster* virtualCluster(const Http::HeaderMap&) const override {
80
3083
    return nullptr;
81
3083
  }
82

            
83
  static const NullRateLimitPolicy rate_limit_policy_;
84
  static const NullCommonConfig route_configuration_;
85
};
86

            
87
struct NullPathMatchCriterion : public Router::PathMatchCriterion {
88
1
  Router::PathMatchType matchType() const override { return Router::PathMatchType::None; }
89
1
  const std::string& matcher() const override { return EMPTY_STRING; }
90
};
91

            
92
struct RouteEntryImpl : public Router::RouteEntry {
93
  static absl::StatusOr<std::unique_ptr<RouteEntryImpl>>
94
  create(const std::string& cluster_name, const absl::optional<std::chrono::milliseconds>& timeout,
95
         const Protobuf::RepeatedPtrField<envoy::config::route::v3::RouteAction::HashPolicy>&
96
             hash_policy,
97
         Router::RetryPolicyConstSharedPtr retry_policy, Regex::Engine& regex_engine,
98
3633
         const Router::MetadataMatchCriteria* metadata_match) {
99
3633
    absl::Status creation_status = absl::OkStatus();
100
3633
    auto ret = std::unique_ptr<RouteEntryImpl>(
101
3633
        new RouteEntryImpl(cluster_name, timeout, hash_policy, std::move(retry_policy),
102
3633
                           regex_engine, creation_status, metadata_match));
103
3633
    RETURN_IF_NOT_OK(creation_status);
104
3633
    return ret;
105
3633
  }
106

            
107
protected:
108
  RouteEntryImpl(
109
      const std::string& cluster_name, const absl::optional<std::chrono::milliseconds>& timeout,
110
      const Protobuf::RepeatedPtrField<envoy::config::route::v3::RouteAction::HashPolicy>&
111
          hash_policy,
112
      Router::RetryPolicyConstSharedPtr retry_policy, Regex::Engine& regex_engine,
113
      absl::Status& creation_status, const Router::MetadataMatchCriteria* metadata_match)
114
3633
      : metadata_match_(metadata_match), retry_policy_(std::move(retry_policy)),
115
3633
        cluster_name_(cluster_name), timeout_(timeout) {
116
3633
    if (!hash_policy.empty()) {
117
2
      auto policy_or_error = HashPolicyImpl::create(hash_policy, regex_engine);
118
2
      SET_AND_RETURN_IF_NOT_OK(policy_or_error.status(), creation_status);
119
2
      hash_policy_ = std::move(*policy_or_error);
120
2
    }
121
3633
  }
122

            
123
  // Router::RouteEntry
124
3130
  const std::string& clusterName() const override { return cluster_name_; }
125
3083
  const Router::RouteStatsContextOptRef routeStatsContext() const override {
126
3083
    return Router::RouteStatsContextOptRef();
127
3083
  }
128
1
  Http::Code clusterNotFoundResponseCode() const override {
129
1
    return Http::Code::InternalServerError;
130
1
  }
131
1
  const Router::CorsPolicy* corsPolicy() const override { return nullptr; }
132
  std::string currentUrlPathAfterRewrite(const Http::RequestHeaderMap&, const Formatter::Context&,
133
                                         const StreamInfo::StreamInfo&) const override {
134
    return {};
135
  }
136
  void finalizeRequestHeaders(Http::RequestHeaderMap&, const Formatter::Context&,
137
3083
                              const StreamInfo::StreamInfo&, bool) const override {}
138
  Http::HeaderTransforms requestHeaderTransforms(const StreamInfo::StreamInfo&,
139
                                                 bool) const override {
140
    return {};
141
  }
142
  void finalizeResponseHeaders(Http::ResponseHeaderMap&, const Formatter::Context&,
143
2654
                               const StreamInfo::StreamInfo&) const override {}
144
  Http::HeaderTransforms responseHeaderTransforms(const StreamInfo::StreamInfo&,
145
                                                  bool) const override {
146
    return {};
147
  }
148
2
  const HashPolicy* hashPolicy() const override { return hash_policy_.get(); }
149
3086
  const Router::HedgePolicy& hedgePolicy() const override { return hedge_policy_; }
150
8
  const Router::MetadataMatchCriteria* metadataMatchCriteria() const override {
151
8
    return metadata_match_;
152
8
  }
153
6623
  Upstream::ResourcePriority priority() const override {
154
6623
    return Upstream::ResourcePriority::Default;
155
6623
  }
156
2
  const Router::RateLimitPolicy& rateLimitPolicy() const override { return rate_limit_policy_; }
157
9309
  const Router::RetryPolicyConstSharedPtr& retryPolicy() const override { return retry_policy_; }
158
73136
  const Router::InternalRedirectPolicy& internalRedirectPolicy() const override {
159
73136
    return internal_redirect_policy_;
160
73136
  }
161
  const Router::PathMatcherSharedPtr& pathMatcher() const override { return path_matcher_; }
162
  const Router::PathRewriterSharedPtr& pathRewriter() const override { return path_rewriter_; }
163
3083
  uint64_t requestBodyBufferLimit() const override { return std::numeric_limits<uint64_t>::max(); }
164
3081
  const std::vector<Router::ShadowPolicyPtr>& shadowPolicies() const override {
165
3081
    return shadow_policies_;
166
3081
  }
167
3083
  std::chrono::milliseconds timeout() const override {
168
3083
    if (timeout_) {
169
601
      return timeout_.value();
170
3038
    } else {
171
2482
      return std::chrono::milliseconds(0);
172
2482
    }
173
3083
  }
174
3247
  bool usingNewTimeouts() const override { return false; }
175
1
  absl::optional<std::chrono::milliseconds> idleTimeout() const override { return absl::nullopt; }
176
  absl::optional<std::chrono::milliseconds> flushTimeout() const override { return absl::nullopt; }
177
  absl::optional<std::chrono::milliseconds> maxStreamDuration() const override {
178
    return absl::nullopt;
179
  }
180
  absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderMax() const override {
181
    return absl::nullopt;
182
  }
183
  absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderOffset() const override {
184
    return absl::nullopt;
185
  }
186
2507
  absl::optional<std::chrono::milliseconds> maxGrpcTimeout() const override {
187
2507
    return absl::nullopt;
188
2507
  }
189
1
  absl::optional<std::chrono::milliseconds> grpcTimeoutOffset() const override {
190
1
    return absl::nullopt;
191
1
  }
192
1
  const Router::TlsContextMatchCriteria* tlsContextMatchCriteria() const override {
193
1
    return nullptr;
194
1
  }
195
1
  const std::multimap<std::string, std::string>& opaqueConfig() const override {
196
1
    return opaque_config_;
197
1
  }
198
3335
  bool autoHostRewrite() const override { return false; }
199
  bool appendXfh() const override { return false; }
200
1
  bool includeVirtualHostRateLimits() const override { return true; }
201
1
  const Router::PathMatchCriterion& pathMatchCriterion() const override {
202
1
    return path_match_criterion_;
203
1
  }
204

            
205
3122
  const ConnectConfigOptRef connectConfig() const override { return connect_config_nullopt_; }
206

            
207
3083
  bool includeAttemptCountInRequest() const override { return false; }
208
3033
  bool includeAttemptCountInResponse() const override { return false; }
209
1
  const Router::RouteEntry::UpgradeMap& upgradeMap() const override { return upgrade_map_; }
210
3080
  const Router::EarlyDataPolicy& earlyDataPolicy() const override { return *early_data_policy_; }
211
  void refreshRouteCluster(const Http::RequestHeaderMap&,
212
                           const StreamInfo::StreamInfo&) const override {}
213

            
214
  const Router::MetadataMatchCriteria* metadata_match_;
215
  std::unique_ptr<const HashPolicyImpl> hash_policy_;
216
  const Router::RetryPolicyConstSharedPtr retry_policy_;
217

            
218
  static const NullHedgePolicy hedge_policy_;
219
  static const NullRateLimitPolicy rate_limit_policy_;
220
  static const Router::InternalRedirectPolicyImpl internal_redirect_policy_;
221
  static const Router::PathMatcherSharedPtr path_matcher_;
222
  static const Router::PathRewriterSharedPtr path_rewriter_;
223
  static const std::vector<Router::ShadowPolicyPtr> shadow_policies_;
224
  static const std::multimap<std::string, std::string> opaque_config_;
225
  static const NullPathMatchCriterion path_match_criterion_;
226

            
227
  Router::RouteEntry::UpgradeMap upgrade_map_;
228
  const std::string cluster_name_;
229
  absl::optional<std::chrono::milliseconds> timeout_;
230
  static const ConnectConfigOptRef connect_config_nullopt_;
231
  // Pass early data option config through StreamOptions.
232
  std::unique_ptr<Router::EarlyDataPolicy> early_data_policy_{
233
      new Router::DefaultEarlyDataPolicy(true)};
234
};
235

            
236
struct NullRouteImpl : public Router::Route {
237
  static absl::StatusOr<std::unique_ptr<NullRouteImpl>>
238
  create(const std::string cluster_name, Router::RetryPolicyConstSharedPtr retry_policy,
239
         Regex::Engine& regex_engine, const absl::optional<std::chrono::milliseconds>& timeout = {},
240
         const Protobuf::RepeatedPtrField<envoy::config::route::v3::RouteAction::HashPolicy>&
241
             hash_policy = {},
242
3633
         const Router::MetadataMatchCriteria* metadata_match = nullptr) {
243
3633
    absl::Status creation_status;
244
3633
    auto ret = std::unique_ptr<NullRouteImpl>(
245
3633
        new NullRouteImpl(cluster_name, std::move(retry_policy), regex_engine, timeout, hash_policy,
246
3633
                          creation_status, metadata_match));
247
3633
    RETURN_IF_NOT_OK(creation_status);
248
3633
    return ret;
249
3633
  }
250

            
251
  // Router::Route
252
3083
  const Router::DirectResponseEntry* directResponseEntry() const override { return nullptr; }
253
6848
  const Router::RouteEntry* routeEntry() const override { return route_entry_.get(); }
254
1
  const Router::Decorator* decorator() const override { return nullptr; }
255
1
  const Router::RouteTracing* tracingConfig() const override { return nullptr; }
256
  const Router::RouteSpecificFilterConfig*
257
  mostSpecificPerFilterConfig(absl::string_view) const override {
258
    return nullptr;
259
  }
260
  Router::RouteSpecificFilterConfigs perFilterConfigs(absl::string_view) const override {
261
    return {};
262
  }
263
  const envoy::config::core::v3::Metadata& metadata() const override {
264
    return Router::DefaultRouteMetadataPack::get().proto_metadata_;
265
  }
266
1
  const Envoy::Config::TypedMetadata& typedMetadata() const override {
267
1
    return Router::DefaultRouteMetadataPack::get().typed_metadata_;
268
1
  }
269
22
  absl::optional<bool> filterDisabled(absl::string_view) const override { return {}; }
270
1
  const std::string& routeName() const override { return EMPTY_STRING; }
271
9796
  const Router::VirtualHostConstSharedPtr& virtualHost() const override { return virtual_host_; }
272

            
273
  std::unique_ptr<RouteEntryImpl> route_entry_;
274
  static const Router::VirtualHostConstSharedPtr virtual_host_;
275

            
276
protected:
277
  NullRouteImpl(const std::string cluster_name, Router::RetryPolicyConstSharedPtr retry_policy,
278
                Regex::Engine& regex_engine,
279
                const absl::optional<std::chrono::milliseconds>& timeout,
280
                const Protobuf::RepeatedPtrField<envoy::config::route::v3::RouteAction::HashPolicy>&
281
                    hash_policy,
282
                absl::Status& creation_status,
283
3633
                const Router::MetadataMatchCriteria* metadata_match) {
284
3633
    auto entry_or_error = RouteEntryImpl::create(
285
3633
        cluster_name, timeout, hash_policy, std::move(retry_policy), regex_engine, metadata_match);
286
3633
    SET_AND_RETURN_IF_NOT_OK(entry_or_error.status(), creation_status);
287
3633
    route_entry_ = std::move(*entry_or_error);
288
3633
  }
289
};
290

            
291
} // namespace Http
292
} // namespace Envoy