Coverage Report

Created: 2023-11-12 09:30

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