Coverage Report

Created: 2024-09-19 09:45

/proc/self/cwd/source/common/http/utility.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <chrono>
4
#include <cstdint>
5
#include <functional>
6
#include <memory>
7
#include <string>
8
#include <vector>
9
10
#include "envoy/common/regex.h"
11
#include "envoy/config/core/v3/http_uri.pb.h"
12
#include "envoy/config/core/v3/protocol.pb.h"
13
#include "envoy/config/route/v3/route_components.pb.h"
14
#include "envoy/grpc/status.h"
15
#include "envoy/http/codes.h"
16
#include "envoy/http/filter.h"
17
#include "envoy/http/message.h"
18
#include "envoy/http/metadata_interface.h"
19
#include "envoy/http/query_params.h"
20
21
#include "source/common/http/exception.h"
22
#include "source/common/http/http_option_limits.h"
23
#include "source/common/http/status.h"
24
25
#include "absl/strings/string_view.h"
26
#include "absl/types/optional.h"
27
28
namespace Envoy {
29
namespace Http {
30
namespace Utility {
31
32
/**
33
 * Well-known HTTP ALPN values.
34
 */
35
class AlpnNameValues {
36
public:
37
  const std::string Http10 = "http/1.0";
38
  const std::string Http11 = "http/1.1";
39
  const std::string Http2 = "h2";
40
  const std::string Http2c = "h2c";
41
  const std::string Http3 = "h3";
42
};
43
44
using AlpnNames = ConstSingleton<AlpnNameValues>;
45
46
} // namespace Utility
47
} // namespace Http
48
49
namespace Http2 {
50
namespace Utility {
51
52
/**
53
 * Validates settings/options already set in |options| and initializes any remaining fields with
54
 * defaults.
55
 */
56
absl::StatusOr<envoy::config::core::v3::Http2ProtocolOptions>
57
initializeAndValidateOptions(const envoy::config::core::v3::Http2ProtocolOptions& options);
58
59
absl::StatusOr<envoy::config::core::v3::Http2ProtocolOptions>
60
initializeAndValidateOptions(const envoy::config::core::v3::Http2ProtocolOptions& options,
61
                             bool hcm_stream_error_set,
62
                             const ProtobufWkt::BoolValue& hcm_stream_error);
63
} // namespace Utility
64
} // namespace Http2
65
namespace Http3 {
66
namespace Utility {
67
68
envoy::config::core::v3::Http3ProtocolOptions
69
initializeAndValidateOptions(const envoy::config::core::v3::Http3ProtocolOptions& options,
70
                             bool hcm_stream_error_set,
71
                             const ProtobufWkt::BoolValue& hcm_stream_error);
72
73
} // namespace Utility
74
} // namespace Http3
75
namespace Http {
76
namespace Utility {
77
78
enum UrlComponents {
79
  UcSchema = 0,
80
  UcHost = 1,
81
  UcPort = 2,
82
  UcPath = 3,
83
  UcQuery = 4,
84
  UcFragment = 5,
85
  UcUserinfo = 6,
86
  UcMax = 7
87
};
88
89
/**
90
 * Given a fully qualified URL, splits the string_view provided into scheme,
91
 * host and path with query parameters components.
92
 */
93
94
class Url {
95
public:
96
  bool initialize(absl::string_view absolute_url, bool is_connect_request);
97
526
  absl::string_view scheme() const { return scheme_; }
98
3.21k
  absl::string_view hostAndPort() const { return host_and_port_; }
99
238
  absl::string_view pathAndQueryParams() const { return path_and_query_params_; }
100
101
0
  void setPathAndQueryParams(absl::string_view path_and_query_params) {
102
0
    path_and_query_params_ = path_and_query_params;
103
0
  }
104
105
  /** Returns the fully qualified URL as a string. */
106
  std::string toString() const;
107
108
  bool containsFragment();
109
  bool containsUserinfo();
110
111
private:
112
  absl::string_view scheme_;
113
  absl::string_view host_and_port_;
114
  absl::string_view path_and_query_params_;
115
  uint8_t component_bitmap_;
116
};
117
118
class PercentEncoding {
119
public:
120
  /**
121
   * Encodes string view to its percent encoded representation. Non-visible ASCII is always escaped,
122
   * in addition to a given list of reserved chars.
123
   *
124
   * @param value supplies string to be encoded.
125
   * @param reserved_chars list of reserved chars to escape. By default the escaped chars in
126
   *        https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#responses are used.
127
   * @return std::string percent-encoded string.
128
   */
129
  static std::string encode(absl::string_view value, absl::string_view reserved_chars = "%");
130
131
  /**
132
   * Decodes string view from its percent encoded representation.
133
   * @param encoded supplies string to be decoded.
134
   * @return std::string decoded string https://tools.ietf.org/html/rfc3986#section-2.1.
135
   */
136
  static std::string decode(absl::string_view encoded);
137
138
  /**
139
   * Encodes string view for storing it as a query parameter according to the
140
   * x-www-form-urlencoded spec:
141
   * https://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm
142
   * @param value supplies string to be encoded.
143
   * @return std::string encoded string according to
144
   * https://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm
145
   *
146
   * Summary:
147
   * The x-www-form-urlencoded spec mandates that all ASCII codepoints are %-encoded except the
148
   * following: ALPHA | DIGIT | * | - | . | _
149
   *
150
   * NOTE: the space character is encoded as %20, NOT as the + character
151
   */
152
  static std::string urlEncodeQueryParameter(absl::string_view value);
153
154
  /**
155
   * Exactly the same as above, but returns false when it finds a character that should be %-encoded
156
   * but is not.
157
   */
158
  static bool queryParameterIsUrlEncoded(absl::string_view value);
159
160
  /**
161
   * Decodes string view that represents URL in x-www-form-urlencoded query parameter.
162
   * @param encoded supplies string to be decoded.
163
   * @return std::string decoded string compliant with https://datatracker.ietf.org/doc/html/rfc3986
164
   *
165
   * This function decodes a query parameter assuming it is a URL. It only decodes characters
166
   * permitted in the URL - the unreserved and reserved character sets.
167
   * unreserved-set := ALPHA | DIGIT | - | . | _ | ~
168
   * reserved-set := sub-delims | gen-delims
169
   * sub-delims := ! | $ | & | ` | ( | ) | * | + | , | ; | =
170
   * gen-delims := : | / | ? | # | [ | ] | @
171
   *
172
   * The following characters are not decoded:
173
   * ASCII controls <= 0x1F, space, DEL (0x7F), extended ASCII > 0x7F
174
   * As well as the following characters without defined meaning in URL
175
   * " | < | > | \ | ^ | { | }
176
   * and the "pipe" `|` character
177
   */
178
  static std::string urlDecodeQueryParameter(absl::string_view encoded);
179
180
private:
181
  // Encodes string view to its percent encoded representation, with start index.
182
  static std::string encode(absl::string_view value, const size_t index,
183
                            const absl::flat_hash_set<char>& reserved_char_set);
184
};
185
186
/**
187
 * Append to x-forwarded-for header.
188
 * @param headers supplies the headers to append to.
189
 * @param remote_address supplies the remote address to append.
190
 */
191
void appendXff(RequestHeaderMap& headers, const Network::Address::Instance& remote_address);
192
193
/**
194
 * Append to via header.
195
 * @param headers supplies the headers to append to.
196
 * @param via supplies the via header to append.
197
 */
198
void appendVia(RequestOrResponseHeaderMap& headers, const std::string& via);
199
200
/**
201
 * Update authority with the specified hostname.
202
 * @param headers headers where authority should be updated.
203
 * @param hostname hostname that authority should be updated with.
204
 * @param append_xfh append the original authority to the x-forwarded-host header.
205
 */
206
void updateAuthority(RequestHeaderMap& headers, absl::string_view hostname, bool append_xfh);
207
208
/**
209
 * Creates an SSL (https) redirect path based on the input host and path headers.
210
 * @param headers supplies the request headers.
211
 * @return std::string the redirect path.
212
 */
213
std::string createSslRedirectPath(const RequestHeaderMap& headers);
214
215
/**
216
 * Finds the start of the query string in a path
217
 * @param path supplies a HeaderString& to search for the query string
218
 * @return absl::string_view starting at the beginning of the query string,
219
 *         or a string_view starting at the end of the path if there was
220
 *         no query string.
221
 */
222
absl::string_view findQueryStringStart(const HeaderString& path);
223
224
/**
225
 * Returns the path without the query string.
226
 * @param path supplies a HeaderString& possibly containing a query string.
227
 * @return std::string the path without query string.
228
 */
229
std::string stripQueryString(const HeaderString& path);
230
231
/**
232
 * Parse a particular value out of a cookie
233
 * @param headers supplies the headers to get the cookie from.
234
 * @param key the key for the particular cookie value to return
235
 * @return std::string the parsed cookie value, or "" if none exists
236
 **/
237
std::string parseCookieValue(const HeaderMap& headers, const std::string& key);
238
239
/**
240
 * Parse cookies from header into a map.
241
 * @param headers supplies the headers to get cookies from.
242
 * @param key_filter predicate that returns true for every cookie key to be included.
243
 * @return absl::flat_hash_map cookie map.
244
 **/
245
absl::flat_hash_map<std::string, std::string>
246
parseCookies(const RequestHeaderMap& headers,
247
             const std::function<bool(absl::string_view)>& key_filter);
248
249
/**
250
 * Parse cookies from header into a map.
251
 * @param headers supplies the headers to get cookies from.
252
 * @return absl::flat_hash_map cookie map.
253
 **/
254
absl::flat_hash_map<std::string, std::string> parseCookies(const RequestHeaderMap& headers);
255
256
/**
257
 * Parse a particular value out of a set-cookie
258
 * @param headers supplies the headers to get the set-cookie from.
259
 * @param key the key for the particular set-cookie value to return
260
 * @return std::string the parsed set-cookie value, or "" if none exists
261
 **/
262
std::string parseSetCookieValue(const HeaderMap& headers, const std::string& key);
263
264
/**
265
 * Produce the value for a Set-Cookie header with the given parameters.
266
 * @param key is the name of the cookie that is being set.
267
 * @param value the value to set the cookie to; this value is trusted.
268
 * @param path the path for the cookie, or the empty string to not set a path.
269
 * @param max_age the length of time for which the cookie is valid, or zero
270
 * @param httponly true if the cookie should have HttpOnly appended.
271
 * to create a session cookie.
272
 * @return std::string a valid Set-Cookie header value string
273
 */
274
std::string makeSetCookieValue(const std::string& key, const std::string& value,
275
                               const std::string& path, const std::chrono::seconds max_age,
276
                               bool httponly, const Http::CookieAttributeRefVector attributes);
277
278
/**
279
 * Get the response status from the response headers.
280
 * @param headers supplies the headers to get the status from.
281
 * @return uint64_t the response code or returns 0 if headers are invalid.
282
 */
283
uint64_t getResponseStatus(const ResponseHeaderMap& headers);
284
285
/**
286
 * Get the response status from the response headers.
287
 * @param headers supplies the headers to get the status from.
288
 * @return absl::optional<uint64_t> the response code or absl::nullopt if the headers are invalid.
289
 */
290
absl::optional<uint64_t> getResponseStatusOrNullopt(const ResponseHeaderMap& headers);
291
292
/**
293
 * Determine whether these headers are a valid Upgrade request or response.
294
 * This function returns true if the following HTTP headers and values are present:
295
 * - Connection: Upgrade
296
 * - Upgrade: [any value]
297
 */
298
bool isUpgrade(const RequestOrResponseHeaderMap& headers);
299
300
/**
301
 * @return true if this is a CONNECT request with a :protocol header present, false otherwise.
302
 */
303
bool isH2UpgradeRequest(const RequestHeaderMap& headers);
304
305
/**
306
 * @return true if this is a CONNECT request with a :protocol header present, false otherwise.
307
 */
308
bool isH3UpgradeRequest(const RequestHeaderMap& headers);
309
310
/**
311
 * Determine whether this is a WebSocket Upgrade request.
312
 * This function returns true if the following HTTP headers and values are present:
313
 * - Connection: Upgrade
314
 * - Upgrade: websocket
315
 */
316
bool isWebSocketUpgradeRequest(const RequestHeaderMap& headers);
317
318
struct EncodeFunctions {
319
  // Function to modify locally generated response headers.
320
  std::function<void(ResponseHeaderMap& headers)> modify_headers_;
321
  // Function to rewrite locally generated response.
322
  std::function<void(ResponseHeaderMap& response_headers, Code& code, std::string& body,
323
                     absl::string_view& content_type)>
324
      rewrite_;
325
  // Function to encode response headers.
326
  std::function<void(ResponseHeaderMapPtr&& headers, bool end_stream)> encode_headers_;
327
  // Function to encode the response body.
328
  std::function<void(Buffer::Instance& data, bool end_stream)> encode_data_;
329
};
330
331
struct LocalReplyData {
332
  // Tells if this is a response to a gRPC request.
333
  bool is_grpc_;
334
  // Supplies the HTTP response code.
335
  Code response_code_;
336
  // Supplies the optional body text which is returned.
337
  absl::string_view body_text_;
338
  // gRPC status code to override the httpToGrpcStatus mapping with.
339
  const absl::optional<Grpc::Status::GrpcStatus> grpc_status_;
340
  // Tells if this is a response to a HEAD request.
341
  bool is_head_request_ = false;
342
};
343
344
// Prepared local reply after modifying headers and rewriting body.
345
struct PreparedLocalReply {
346
  bool is_grpc_request_ = false;
347
  bool is_head_request_ = false;
348
  ResponseHeaderMapPtr response_headers_;
349
  std::string response_body_;
350
  // Function to encode response headers.
351
  std::function<void(ResponseHeaderMapPtr&& headers, bool end_stream)> encode_headers_;
352
  // Function to encode the response body.
353
  std::function<void(Buffer::Instance& data, bool end_stream)> encode_data_;
354
};
355
356
using PreparedLocalReplyPtr = std::unique_ptr<PreparedLocalReply>;
357
358
/**
359
 * Create a locally generated response using the provided lambdas.
360
361
 * @param is_reset boolean reference that indicates whether a stream has been reset. It is the
362
 *                 responsibility of the caller to ensure that this is set to false if onDestroy()
363
 *                 is invoked in the context of sendLocalReply().
364
 * @param encode_functions supplies the functions to encode response body and headers.
365
 * @param local_reply_data struct which keeps data related to generate reply.
366
 */
367
void sendLocalReply(const bool& is_reset, const EncodeFunctions& encode_functions,
368
                    const LocalReplyData& local_reply_data);
369
370
/**
371
 * Prepares a locally generated response.
372
 *
373
 * @param encode_functions supplies the functions to encode response body and headers.
374
 * @param local_reply_data struct which keeps data related to generate reply.
375
 */
376
PreparedLocalReplyPtr prepareLocalReply(const EncodeFunctions& encode_functions,
377
                                        const LocalReplyData& local_reply_data);
378
/**
379
 * Encodes a prepared local reply.
380
 * @param is_reset boolean reference that indicates whether a stream has been reset. It is the
381
 *                 responsibility of the caller to ensure that this is set to false if onDestroy()
382
 *                 is invoked in the context of sendLocalReply().
383
 * @param prepared_local_reply supplies the local reply to encode.
384
 */
385
void encodeLocalReply(const bool& is_reset, PreparedLocalReplyPtr prepared_local_reply);
386
387
struct GetLastAddressFromXffInfo {
388
  // Last valid address pulled from the XFF header.
389
  Network::Address::InstanceConstSharedPtr address_;
390
  // Whether this address can be used to determine if it's an internal request.
391
  bool allow_trusted_address_checks_;
392
};
393
394
/**
395
 * Checks if the remote address is contained by one of the trusted proxy CIDRs.
396
 * @param remote the remote address
397
 * @param trusted_cidrs the list of CIDRs which are considered trusted proxies
398
 * @return whether the remote address is a trusted proxy
399
 */
400
bool remoteAddressIsTrustedProxy(const Envoy::Network::Address::Instance& remote,
401
                                 absl::Span<const Network::Address::CidrRange> trusted_cidrs);
402
403
/**
404
 * Retrieves the last address in the x-forwarded-header after removing all trusted proxy addresses.
405
 * @param request_headers supplies the request headers
406
 * @param trusted_cidrs the list of CIDRs which are considered trusted proxies
407
 * @return GetLastAddressFromXffInfo information about the last address in the XFF header.
408
 *         @see GetLastAddressFromXffInfo for more information.
409
 */
410
GetLastAddressFromXffInfo
411
getLastNonTrustedAddressFromXFF(const Http::RequestHeaderMap& request_headers,
412
                                absl::Span<const Network::Address::CidrRange> trusted_cidrs);
413
414
/**
415
 * Retrieves the last IPv4/IPv6 address in the x-forwarded-for header.
416
 * @param request_headers supplies the request headers.
417
 * @param num_to_skip specifies the number of addresses at the end of the XFF header
418
 *        to ignore when identifying the "last" address.
419
 * @return GetLastAddressFromXffInfo information about the last address in the XFF header.
420
 *         @see GetLastAddressFromXffInfo for more information.
421
 */
422
GetLastAddressFromXffInfo getLastAddressFromXFF(const Http::RequestHeaderMap& request_headers,
423
                                                uint32_t num_to_skip = 0);
424
425
/**
426
 * Remove any headers nominated by the Connection header
427
 * Sanitize the TE header if it contains unsupported values
428
 *
429
 * @param headers the client request headers
430
 * @return whether the headers were sanitized successfully
431
 */
432
bool sanitizeConnectionHeader(Http::RequestHeaderMap& headers);
433
434
/**
435
 * Get the string for the given http protocol.
436
 * @param protocol for which to return the string representation.
437
 * @return string representation of the protocol.
438
 */
439
const std::string& getProtocolString(const Protocol p);
440
441
/**
442
 * Constructs the original URI sent from the client from
443
 * the request headers.
444
 * @param request headers from the original request
445
 * @param length to truncate the constructed URI's path
446
 */
447
std::string buildOriginalUri(const Http::RequestHeaderMap& request_headers,
448
                             absl::optional<uint32_t> max_path_length);
449
450
/**
451
 * Extract host and path from a URI. The host may contain port.
452
 * This function doesn't validate if the URI is valid. It only parses the URI with following
453
 * format: scheme://host/path.
454
 * @param the input URI string
455
 * @param the output host string.
456
 * @param the output path string.
457
 */
458
void extractHostPathFromUri(const absl::string_view& uri, absl::string_view& host,
459
                            absl::string_view& path);
460
461
/**
462
 * Takes a the path component from a file:/// URI and returns a local path for file access.
463
 * @param file_path if we have file:///foo/bar, the file_path is foo/bar. For file:///c:/foo/bar
464
 *                  it is c:/foo/bar. This is not prefixed with /.
465
 * @return std::string with absolute path for local access, e.g. /foo/bar, c:/foo/bar.
466
 */
467
std::string localPathFromFilePath(const absl::string_view& file_path);
468
469
/**
470
 * Prepare headers for a HttpUri.
471
 */
472
RequestMessagePtr prepareHeaders(const envoy::config::core::v3::HttpUri& http_uri);
473
474
/**
475
 * Returns string representation of StreamResetReason.
476
 */
477
const std::string resetReasonToString(const Http::StreamResetReason reset_reason);
478
479
/**
480
 * Transforms the supplied headers from an HTTP/1 Upgrade request to an H2 style upgrade.
481
 * Changes the method to connection, moves the Upgrade to a :protocol header,
482
 * @param headers the headers to convert.
483
 */
484
void transformUpgradeRequestFromH1toH2(RequestHeaderMap& headers);
485
486
/**
487
 * Transforms the supplied headers from an HTTP/1 Upgrade request to an H3 style upgrade,
488
 * which is the same as the H2 upgrade.
489
 * @param headers the headers to convert.
490
 */
491
void transformUpgradeRequestFromH1toH3(RequestHeaderMap& headers);
492
493
/**
494
 * Transforms the supplied headers from an HTTP/1 Upgrade response to an H2 style upgrade response.
495
 * Changes the 101 upgrade response to a 200 for the CONNECT response.
496
 * @param headers the headers to convert.
497
 */
498
void transformUpgradeResponseFromH1toH2(ResponseHeaderMap& headers);
499
500
/**
501
 * Transforms the supplied headers from an HTTP/1 Upgrade response to an H3 style upgrade response,
502
 * which is the same as the H2 style upgrade.
503
 * @param headers the headers to convert.
504
 */
505
void transformUpgradeResponseFromH1toH3(ResponseHeaderMap& headers);
506
507
/**
508
 * Transforms the supplied headers from an H2 "CONNECT"-with-:protocol-header to an HTTP/1 style
509
 * Upgrade response.
510
 * @param headers the headers to convert.
511
 */
512
void transformUpgradeRequestFromH2toH1(RequestHeaderMap& headers);
513
514
/**
515
 * Transforms the supplied headers from an H3 "CONNECT"-with-:protocol-header to an HTTP/1 style
516
 * Upgrade response. Same as H2 upgrade response transform
517
 * @param headers the headers to convert.
518
 */
519
void transformUpgradeRequestFromH3toH1(RequestHeaderMap& headers);
520
521
/**
522
 * Transforms the supplied headers from an H2 "CONNECT success" to an HTTP/1 style Upgrade response.
523
 * The caller is responsible for ensuring this only happens on upgraded streams.
524
 * @param headers the headers to convert.
525
 * @param upgrade the HTTP Upgrade token.
526
 */
527
void transformUpgradeResponseFromH2toH1(ResponseHeaderMap& headers, absl::string_view upgrade);
528
529
/**
530
 * Transforms the supplied headers from an H2 "CONNECT success" to an HTTP/1 style Upgrade response.
531
 * The caller is responsible for ensuring this only happens on upgraded streams.
532
 * Same as H2 Upgrade response transform
533
 * @param headers the headers to convert.
534
 * @param upgrade the HTTP Upgrade token.
535
 */
536
void transformUpgradeResponseFromH3toH1(ResponseHeaderMap& headers, absl::string_view upgrade);
537
538
/**
539
 * Retrieves the route specific config. Route specific config can be in a few
540
 * places, that are checked in order. The first config found is returned. The
541
 * order is:
542
 * - the routeEntry() (for config that's applied on weighted clusters)
543
 * - the route
544
 * - the virtual host object
545
 * - the route configuration
546
 *
547
 * To use, simply:
548
 *
549
 *     const auto* config =
550
 *         Utility::resolveMostSpecificPerFilterConfig<ConcreteType>(stream_callbacks_);
551
 *
552
 * See notes about config's lifetime below.
553
 *
554
 * @param callbacks The stream filter callbacks to check for route configs.
555
 *
556
 * @return The route config if found. nullptr if not found. The returned
557
 * pointer's lifetime is the same as the matched route.
558
 */
559
template <class ConfigType>
560
92.7k
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
92.7k
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
92.7k
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
92.7k
  ASSERT(callbacks != nullptr);
564
92.7k
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
92.7k
}
Unexecuted instantiation: Envoy::Extensions::HttpFilters::OnDemand::OnDemandFilterConfig const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::OnDemand::OnDemandFilterConfig>(Envoy::Http::StreamFilterCallbacks const*)
Envoy::Extensions::HttpFilters::JwtAuthn::PerRouteFilterConfig const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::JwtAuthn::PerRouteFilterConfig>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
560
23.4k
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
23.4k
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
23.4k
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
23.4k
  ASSERT(callbacks != nullptr);
564
23.4k
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
23.4k
}
Unexecuted instantiation: Envoy::Extensions::HttpFilters::AwsLambdaFilter::FilterSettings const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::AwsLambdaFilter::FilterSettings>(Envoy::Http::StreamFilterCallbacks const*)
Unexecuted instantiation: Envoy::Extensions::HttpFilters::AwsRequestSigningFilter::FilterConfig const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::AwsRequestSigningFilter::FilterConfig>(Envoy::Http::StreamFilterCallbacks const*)
Envoy::Extensions::HttpFilters::BandwidthLimitFilter::FilterConfig const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::BandwidthLimitFilter::FilterConfig>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
560
2
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
2
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
2
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
2
  ASSERT(callbacks != nullptr);
564
2
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
2
}
Unexecuted instantiation: Envoy::Extensions::HttpFilters::BasicAuth::FilterConfigPerRoute const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::BasicAuth::FilterConfigPerRoute>(Envoy::Http::StreamFilterCallbacks const*)
Unexecuted instantiation: Envoy::Extensions::HttpFilters::BufferFilter::BufferFilterSettings const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::BufferFilter::BufferFilterSettings>(Envoy::Http::StreamFilterCallbacks const*)
Unexecuted instantiation: Envoy::Extensions::HttpFilters::Compressor::CompressorPerRouteFilterConfig const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::Compressor::CompressorPerRouteFilterConfig>(Envoy::Http::StreamFilterCallbacks const*)
Unexecuted instantiation: Envoy::Extensions::HttpFilters::Csrf::CsrfPolicy const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::Csrf::CsrfPolicy>(Envoy::Http::StreamFilterCallbacks const*)
Unexecuted instantiation: Envoy::Extensions::HttpFilters::DynamicForwardProxy::ProxyPerRouteConfig const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::DynamicForwardProxy::ProxyPerRouteConfig>(Envoy::Http::StreamFilterCallbacks const*)
Envoy::Extensions::HttpFilters::ExtAuthz::FilterConfigPerRoute const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::ExtAuthz::FilterConfigPerRoute>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
560
8.44k
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
8.44k
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
8.44k
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
8.44k
  ASSERT(callbacks != nullptr);
564
8.44k
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
8.44k
}
Envoy::Extensions::HttpFilters::Fault::FaultSettings const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::Fault::FaultSettings>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
560
6
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
6
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
6
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
6
  ASSERT(callbacks != nullptr);
564
6
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
6
}
Envoy::Extensions::HttpFilters::GrpcHttp1ReverseBridge::FilterConfigPerRoute const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::GrpcHttp1ReverseBridge::FilterConfigPerRoute>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
560
1
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
1
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
1
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
1
  ASSERT(callbacks != nullptr);
564
1
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
1
}
Envoy::Extensions::HttpFilters::GrpcJsonTranscoder::JsonTranscoderConfig const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::GrpcJsonTranscoder::JsonTranscoderConfig>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
560
63
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
63
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
63
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
63
  ASSERT(callbacks != nullptr);
564
63
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
63
}
Envoy::Extensions::HttpFilters::HeaderToMetadataFilter::Config const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::HeaderToMetadataFilter::Config>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
560
10
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
10
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
10
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
10
  ASSERT(callbacks != nullptr);
564
10
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
10
}
Envoy::Extensions::HttpFilters::LocalRateLimitFilter::FilterConfig const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::LocalRateLimitFilter::FilterConfig>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
560
1
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
1
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
1
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
1
  ASSERT(callbacks != nullptr);
564
1
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
1
}
Envoy::Extensions::HttpFilters::Lua::FilterConfigPerRoute const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::Lua::FilterConfigPerRoute>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
560
38
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
38
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
38
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
38
  ASSERT(callbacks != nullptr);
564
38
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
38
}
Unexecuted instantiation: Envoy::Extensions::HttpFilters::RateLimitFilter::FilterConfigPerRoute const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::RateLimitFilter::FilterConfigPerRoute>(Envoy::Http::StreamFilterCallbacks const*)
Envoy::Extensions::HttpFilters::RBACFilter::RoleBasedAccessControlRouteSpecificFilterConfig const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::RBACFilter::RoleBasedAccessControlRouteSpecificFilterConfig>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
560
60.7k
const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
561
60.7k
  static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
562
60.7k
                "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
563
60.7k
  ASSERT(callbacks != nullptr);
564
60.7k
  return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
565
60.7k
}
Unexecuted instantiation: Envoy::Extensions::HttpFilters::StatefulSession::PerRouteStatefulSession const* Envoy::Http::Utility::resolveMostSpecificPerFilterConfig<Envoy::Extensions::HttpFilters::StatefulSession::PerRouteStatefulSession>(Envoy::Http::StreamFilterCallbacks const*)
566
567
/**
568
 * Return all the available per route filter configs.
569
 *
570
 * @param callbacks The stream filter callbacks to check for route configs.
571
 *
572
 * @return The all available per route config. The returned pointers are guaranteed to be non-null
573
 * and their lifetime is the same as the matched route.
574
 */
575
template <class ConfigType>
576
absl::InlinedVector<std::reference_wrapper<const ConfigType>, 4>
577
12.8k
getAllPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
578
12.8k
  ASSERT(callbacks != nullptr);
579
580
12.8k
  absl::InlinedVector<std::reference_wrapper<const ConfigType>, 4> all_configs;
581
582
12.8k
  for (const auto* config : callbacks->perFilterConfigs()) {
583
0
    const ConfigType* typed_config = dynamic_cast<const ConfigType*>(config);
584
0
    if (typed_config == nullptr) {
585
0
      ENVOY_LOG_MISC(debug, "Failed to retrieve the correct type of route specific filter config");
586
0
      continue;
587
0
    }
588
0
    all_configs.push_back(*typed_config);
589
0
  }
590
591
12.8k
  return all_configs;
592
12.8k
}
absl::lts_20230802::InlinedVector<std::__1::reference_wrapper<Envoy::Extensions::HttpFilters::ExternalProcessing::FilterConfigPerRoute const>, 4ul, std::__1::allocator<std::__1::reference_wrapper<Envoy::Extensions::HttpFilters::ExternalProcessing::FilterConfigPerRoute const> > > Envoy::Http::Utility::getAllPerFilterConfig<Envoy::Extensions::HttpFilters::ExternalProcessing::FilterConfigPerRoute>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
577
5.04k
getAllPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
578
5.04k
  ASSERT(callbacks != nullptr);
579
580
5.04k
  absl::InlinedVector<std::reference_wrapper<const ConfigType>, 4> all_configs;
581
582
5.04k
  for (const auto* config : callbacks->perFilterConfigs()) {
583
0
    const ConfigType* typed_config = dynamic_cast<const ConfigType*>(config);
584
0
    if (typed_config == nullptr) {
585
0
      ENVOY_LOG_MISC(debug, "Failed to retrieve the correct type of route specific filter config");
586
0
      continue;
587
0
    }
588
0
    all_configs.push_back(*typed_config);
589
0
  }
590
591
5.04k
  return all_configs;
592
5.04k
}
Unexecuted instantiation: absl::lts_20230802::InlinedVector<std::__1::reference_wrapper<Envoy::Router::CorsPolicy const>, 4ul, std::__1::allocator<std::__1::reference_wrapper<Envoy::Router::CorsPolicy const> > > Envoy::Http::Utility::getAllPerFilterConfig<Envoy::Router::CorsPolicy>(Envoy::Http::StreamFilterCallbacks const*)
absl::lts_20230802::InlinedVector<std::__1::reference_wrapper<Envoy::Extensions::HttpFilters::ExtAuthz::FilterConfigPerRoute const>, 4ul, std::__1::allocator<std::__1::reference_wrapper<Envoy::Extensions::HttpFilters::ExtAuthz::FilterConfigPerRoute const> > > Envoy::Http::Utility::getAllPerFilterConfig<Envoy::Extensions::HttpFilters::ExtAuthz::FilterConfigPerRoute>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
577
7.79k
getAllPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
578
7.79k
  ASSERT(callbacks != nullptr);
579
580
7.79k
  absl::InlinedVector<std::reference_wrapper<const ConfigType>, 4> all_configs;
581
582
7.79k
  for (const auto* config : callbacks->perFilterConfigs()) {
583
0
    const ConfigType* typed_config = dynamic_cast<const ConfigType*>(config);
584
0
    if (typed_config == nullptr) {
585
0
      ENVOY_LOG_MISC(debug, "Failed to retrieve the correct type of route specific filter config");
586
0
      continue;
587
0
    }
588
0
    all_configs.push_back(*typed_config);
589
0
  }
590
591
7.79k
  return all_configs;
592
7.79k
}
absl::lts_20230802::InlinedVector<std::__1::reference_wrapper<Envoy::Extensions::HttpFilters::HeaderMutation::PerRouteHeaderMutation const>, 4ul, std::__1::allocator<std::__1::reference_wrapper<Envoy::Extensions::HttpFilters::HeaderMutation::PerRouteHeaderMutation const> > > Envoy::Http::Utility::getAllPerFilterConfig<Envoy::Extensions::HttpFilters::HeaderMutation::PerRouteHeaderMutation>(Envoy::Http::StreamFilterCallbacks const*)
Line
Count
Source
577
8
getAllPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
578
8
  ASSERT(callbacks != nullptr);
579
580
8
  absl::InlinedVector<std::reference_wrapper<const ConfigType>, 4> all_configs;
581
582
8
  for (const auto* config : callbacks->perFilterConfigs()) {
583
0
    const ConfigType* typed_config = dynamic_cast<const ConfigType*>(config);
584
0
    if (typed_config == nullptr) {
585
0
      ENVOY_LOG_MISC(debug, "Failed to retrieve the correct type of route specific filter config");
586
0
      continue;
587
0
    }
588
0
    all_configs.push_back(*typed_config);
589
0
  }
590
591
8
  return all_configs;
592
8
}
Unexecuted instantiation: absl::lts_20230802::InlinedVector<std::__1::reference_wrapper<Envoy::Extensions::HttpFilters::CustomResponse::FilterConfig const>, 4ul, std::__1::allocator<std::__1::reference_wrapper<Envoy::Extensions::HttpFilters::CustomResponse::FilterConfig const> > > Envoy::Http::Utility::getAllPerFilterConfig<Envoy::Extensions::HttpFilters::CustomResponse::FilterConfig>(Envoy::Http::StreamFilterCallbacks const*)
593
594
struct AuthorityAttributes {
595
  // whether parsed authority is pure ip address(IPv4/IPv6), if it is true
596
  // passed that are not FQDN
597
  bool is_ip_address_{};
598
599
  // If parsed authority has host, that is stored here.
600
  absl::string_view host_;
601
602
  // If parsed authority has port, that is stored here.
603
  absl::optional<uint16_t> port_;
604
};
605
606
/**
607
 * Parse passed authority, and get that is valid FQDN or IPv4/IPv6 address, hostname and port-name.
608
 * @param host host/authority
609
 * @param default_port If passed authority does not have port, this value is returned
610
 * @return hostname parse result. that includes whether host is IP Address, hostname and port-name
611
 */
612
AuthorityAttributes parseAuthority(absl::string_view host);
613
614
/**
615
 * It validates RetryPolicy defined in core api. It will return an error status if invalid.
616
 * @param retry_policy core retry policy
617
 */
618
absl::Status validateCoreRetryPolicy(const envoy::config::core::v3::RetryPolicy& retry_policy);
619
620
/**
621
 * It returns RetryPolicy defined in core api to route api.
622
 * @param retry_policy core retry policy
623
 * @param retry_on this specifies when retry should be invoked.
624
 * @return route retry policy
625
 */
626
envoy::config::route::v3::RetryPolicy
627
convertCoreToRouteRetryPolicy(const envoy::config::core::v3::RetryPolicy& retry_policy,
628
                              const std::string& retry_on);
629
630
/**
631
 * @param request_headers the request header to be looked into.
632
 * @return true if the request method is safe as defined in
633
 * https://www.rfc-editor.org/rfc/rfc7231#section-4.2.1
634
 */
635
bool isSafeRequest(const Http::RequestHeaderMap& request_headers);
636
637
/**
638
 * @param value: the value of the referer header field
639
 * @return true if the given value conforms to RFC specifications
640
 * https://www.rfc-editor.org/rfc/rfc7231#section-5.5.2
641
 */
642
bool isValidRefererValue(absl::string_view value);
643
644
/**
645
 * Return the GatewayTimeout HTTP code to indicate the request is full received.
646
 */
647
Http::Code maybeRequestTimeoutCode(bool remote_decode_complete);
648
649
/**
650
 * Container for route config elements that pertain to a redirect.
651
 */
652
struct RedirectConfig {
653
  const std::string scheme_redirect_;
654
  const std::string host_redirect_;
655
  const std::string port_redirect_;
656
  const std::string path_redirect_;
657
  const std::string prefix_rewrite_redirect_;
658
  const std::string regex_rewrite_redirect_substitution_;
659
  Regex::CompiledMatcherPtr regex_rewrite_redirect_;
660
  // Keep small members (bools and enums) at the end of class, to reduce alignment overhead.
661
  const bool path_redirect_has_query_;
662
  const bool https_redirect_;
663
  const bool strip_query_;
664
};
665
666
/**
667
 * Validates the provided scheme is valid (either http or https)
668
 * @param scheme the scheme to validate
669
 * @return bool true if the scheme is valid.
670
 */
671
bool schemeIsValid(const absl::string_view scheme);
672
673
/**
674
 * @param scheme the scheme to validate
675
 * @return bool true if the scheme is http.
676
 */
677
bool schemeIsHttp(const absl::string_view scheme);
678
679
/**
680
 * @param scheme the scheme to validate
681
 * @return bool true if the scheme is https.
682
 */
683
bool schemeIsHttps(const absl::string_view scheme);
684
685
/*
686
 * Compute new path based on RedirectConfig.
687
 */
688
std::string newUri(::Envoy::OptRef<const RedirectConfig> redirect_config,
689
                   const Http::RequestHeaderMap& headers);
690
691
} // namespace Utility
692
} // namespace Http
693
} // namespace Envoy