LCOV - code coverage report
Current view: top level - source/common/http - utility.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 18 32 56.2 %
Date: 2024-01-05 06:35:25 Functions: 14 27 51.9 %

          Line data    Source code
       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           1 :   absl::string_view scheme() const { return scheme_; }
     150           3 :   absl::string_view hostAndPort() const { return host_and_port_; }
     151           2 :   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             :  * Finds the start of the query string in a path
     263             :  * @param path supplies a HeaderString& to search for the query string
     264             :  * @return absl::string_view starting at the beginning of the query string,
     265             :  *         or a string_view starting at the end of the path if there was
     266             :  *         no query string.
     267             :  */
     268             : absl::string_view findQueryStringStart(const HeaderString& path);
     269             : 
     270             : /**
     271             :  * Returns the path without the query string.
     272             :  * @param path supplies a HeaderString& possibly containing a query string.
     273             :  * @return std::string the path without query string.
     274             :  */
     275             : std::string stripQueryString(const HeaderString& path);
     276             : 
     277             : /**
     278             :  * Parse a particular value out of a cookie
     279             :  * @param headers supplies the headers to get the cookie from.
     280             :  * @param key the key for the particular cookie value to return
     281             :  * @return std::string the parsed cookie value, or "" if none exists
     282             :  **/
     283             : std::string parseCookieValue(const HeaderMap& headers, const std::string& key);
     284             : 
     285             : /**
     286             :  * Parse cookies from header into a map.
     287             :  * @param headers supplies the headers to get cookies from.
     288             :  * @param key_filter predicate that returns true for every cookie key to be included.
     289             :  * @return absl::flat_hash_map cookie map.
     290             :  **/
     291             : absl::flat_hash_map<std::string, std::string>
     292             : parseCookies(const RequestHeaderMap& headers,
     293             :              const std::function<bool(absl::string_view)>& key_filter);
     294             : 
     295             : /**
     296             :  * Parse cookies from header into a map.
     297             :  * @param headers supplies the headers to get cookies from.
     298             :  * @return absl::flat_hash_map cookie map.
     299             :  **/
     300             : absl::flat_hash_map<std::string, std::string> parseCookies(const RequestHeaderMap& headers);
     301             : 
     302             : /**
     303             :  * Parse a particular value out of a set-cookie
     304             :  * @param headers supplies the headers to get the set-cookie from.
     305             :  * @param key the key for the particular set-cookie value to return
     306             :  * @return std::string the parsed set-cookie value, or "" if none exists
     307             :  **/
     308             : std::string parseSetCookieValue(const HeaderMap& headers, const std::string& key);
     309             : 
     310             : /**
     311             :  * Produce the value for a Set-Cookie header with the given parameters.
     312             :  * @param key is the name of the cookie that is being set.
     313             :  * @param value the value to set the cookie to; this value is trusted.
     314             :  * @param path the path for the cookie, or the empty string to not set a path.
     315             :  * @param max_age the length of time for which the cookie is valid, or zero
     316             :  * @param httponly true if the cookie should have HttpOnly appended.
     317             :  * to create a session cookie.
     318             :  * @return std::string a valid Set-Cookie header value string
     319             :  */
     320             : std::string makeSetCookieValue(const std::string& key, const std::string& value,
     321             :                                const std::string& path, const std::chrono::seconds max_age,
     322             :                                bool httponly, const Http::CookieAttributeRefVector attributes);
     323             : 
     324             : /**
     325             :  * Get the response status from the response headers.
     326             :  * @param headers supplies the headers to get the status from.
     327             :  * @return uint64_t the response code or returns 0 if headers are invalid.
     328             :  */
     329             : uint64_t getResponseStatus(const ResponseHeaderMap& headers);
     330             : 
     331             : /**
     332             :  * Get the response status from the response headers.
     333             :  * @param headers supplies the headers to get the status from.
     334             :  * @return absl::optional<uint64_t> the response code or absl::nullopt if the headers are invalid.
     335             :  */
     336             : absl::optional<uint64_t> getResponseStatusOrNullopt(const ResponseHeaderMap& headers);
     337             : 
     338             : /**
     339             :  * Determine whether these headers are a valid Upgrade request or response.
     340             :  * This function returns true if the following HTTP headers and values are present:
     341             :  * - Connection: Upgrade
     342             :  * - Upgrade: [any value]
     343             :  */
     344             : bool isUpgrade(const RequestOrResponseHeaderMap& headers);
     345             : 
     346             : /**
     347             :  * @return true if this is a CONNECT request with a :protocol header present, false otherwise.
     348             :  */
     349             : bool isH2UpgradeRequest(const RequestHeaderMap& headers);
     350             : 
     351             : /**
     352             :  * @return true if this is a CONNECT request with a :protocol header present, false otherwise.
     353             :  */
     354             : bool isH3UpgradeRequest(const RequestHeaderMap& headers);
     355             : 
     356             : /**
     357             :  * Determine whether this is a WebSocket Upgrade request.
     358             :  * This function returns true if the following HTTP headers and values are present:
     359             :  * - Connection: Upgrade
     360             :  * - Upgrade: websocket
     361             :  */
     362             : bool isWebSocketUpgradeRequest(const RequestHeaderMap& headers);
     363             : 
     364             : struct EncodeFunctions {
     365             :   // Function to modify locally generated response headers.
     366             :   std::function<void(ResponseHeaderMap& headers)> modify_headers_;
     367             :   // Function to rewrite locally generated response.
     368             :   std::function<void(ResponseHeaderMap& response_headers, Code& code, std::string& body,
     369             :                      absl::string_view& content_type)>
     370             :       rewrite_;
     371             :   // Function to encode response headers.
     372             :   std::function<void(ResponseHeaderMapPtr&& headers, bool end_stream)> encode_headers_;
     373             :   // Function to encode the response body.
     374             :   std::function<void(Buffer::Instance& data, bool end_stream)> encode_data_;
     375             : };
     376             : 
     377             : struct LocalReplyData {
     378             :   // Tells if this is a response to a gRPC request.
     379             :   bool is_grpc_;
     380             :   // Supplies the HTTP response code.
     381             :   Code response_code_;
     382             :   // Supplies the optional body text which is returned.
     383             :   absl::string_view body_text_;
     384             :   // gRPC status code to override the httpToGrpcStatus mapping with.
     385             :   const absl::optional<Grpc::Status::GrpcStatus> grpc_status_;
     386             :   // Tells if this is a response to a HEAD request.
     387             :   bool is_head_request_ = false;
     388             : };
     389             : 
     390             : // Prepared local reply after modifying headers and rewriting body.
     391             : struct PreparedLocalReply {
     392             :   bool is_grpc_request_ = false;
     393             :   bool is_head_request_ = false;
     394             :   ResponseHeaderMapPtr response_headers_;
     395             :   std::string response_body_;
     396             :   // Function to encode response headers.
     397             :   std::function<void(ResponseHeaderMapPtr&& headers, bool end_stream)> encode_headers_;
     398             :   // Function to encode the response body.
     399             :   std::function<void(Buffer::Instance& data, bool end_stream)> encode_data_;
     400             : };
     401             : 
     402             : using PreparedLocalReplyPtr = std::unique_ptr<PreparedLocalReply>;
     403             : 
     404             : /**
     405             :  * Create a locally generated response using the provided lambdas.
     406             : 
     407             :  * @param is_reset boolean reference that indicates whether a stream has been reset. It is the
     408             :  *                 responsibility of the caller to ensure that this is set to false if onDestroy()
     409             :  *                 is invoked in the context of sendLocalReply().
     410             :  * @param encode_functions supplies the functions to encode response body and headers.
     411             :  * @param local_reply_data struct which keeps data related to generate reply.
     412             :  */
     413             : void sendLocalReply(const bool& is_reset, const EncodeFunctions& encode_functions,
     414             :                     const LocalReplyData& local_reply_data);
     415             : 
     416             : /**
     417             :  * Prepares a locally generated response.
     418             :  *
     419             :  * @param encode_functions supplies the functions to encode response body and headers.
     420             :  * @param local_reply_data struct which keeps data related to generate reply.
     421             :  */
     422             : PreparedLocalReplyPtr prepareLocalReply(const EncodeFunctions& encode_functions,
     423             :                                         const LocalReplyData& local_reply_data);
     424             : /**
     425             :  * Encodes a prepared local reply.
     426             :  * @param is_reset boolean reference that indicates whether a stream has been reset. It is the
     427             :  *                 responsibility of the caller to ensure that this is set to false if onDestroy()
     428             :  *                 is invoked in the context of sendLocalReply().
     429             :  * @param prepared_local_reply supplies the local reply to encode.
     430             :  */
     431             : void encodeLocalReply(const bool& is_reset, PreparedLocalReplyPtr prepared_local_reply);
     432             : 
     433             : struct GetLastAddressFromXffInfo {
     434             :   // Last valid address pulled from the XFF header.
     435             :   Network::Address::InstanceConstSharedPtr address_;
     436             :   // Whether this address can be used to determine if it's an internal request.
     437             :   bool allow_trusted_address_checks_;
     438             : };
     439             : 
     440             : /**
     441             :  * Retrieves the last IPv4/IPv6 address in the x-forwarded-for header.
     442             :  * @param request_headers supplies the request headers.
     443             :  * @param num_to_skip specifies the number of addresses at the end of the XFF header
     444             :  *        to ignore when identifying the "last" address.
     445             :  * @return GetLastAddressFromXffInfo information about the last address in the XFF header.
     446             :  *         @see GetLastAddressFromXffInfo for more information.
     447             :  */
     448             : GetLastAddressFromXffInfo getLastAddressFromXFF(const Http::RequestHeaderMap& request_headers,
     449             :                                                 uint32_t num_to_skip = 0);
     450             : 
     451             : /**
     452             :  * Remove any headers nominated by the Connection header
     453             :  * Sanitize the TE header if it contains unsupported values
     454             :  *
     455             :  * @param headers the client request headers
     456             :  * @return whether the headers were sanitized successfully
     457             :  */
     458             : bool sanitizeConnectionHeader(Http::RequestHeaderMap& headers);
     459             : 
     460             : /**
     461             :  * Get the string for the given http protocol.
     462             :  * @param protocol for which to return the string representation.
     463             :  * @return string representation of the protocol.
     464             :  */
     465             : const std::string& getProtocolString(const Protocol p);
     466             : 
     467             : /**
     468             :  * Constructs the original URI sent from the client from
     469             :  * the request headers.
     470             :  * @param request headers from the original request
     471             :  * @param length to truncate the constructed URI's path
     472             :  */
     473             : std::string buildOriginalUri(const Http::RequestHeaderMap& request_headers,
     474             :                              absl::optional<uint32_t> max_path_length);
     475             : 
     476             : /**
     477             :  * Extract host and path from a URI. The host may contain port.
     478             :  * This function doesn't validate if the URI is valid. It only parses the URI with following
     479             :  * format: scheme://host/path.
     480             :  * @param the input URI string
     481             :  * @param the output host string.
     482             :  * @param the output path string.
     483             :  */
     484             : void extractHostPathFromUri(const absl::string_view& uri, absl::string_view& host,
     485             :                             absl::string_view& path);
     486             : 
     487             : /**
     488             :  * Takes a the path component from a file:/// URI and returns a local path for file access.
     489             :  * @param file_path if we have file:///foo/bar, the file_path is foo/bar. For file:///c:/foo/bar
     490             :  *                  it is c:/foo/bar. This is not prefixed with /.
     491             :  * @return std::string with absolute path for local access, e.g. /foo/bar, c:/foo/bar.
     492             :  */
     493             : std::string localPathFromFilePath(const absl::string_view& file_path);
     494             : 
     495             : /**
     496             :  * Prepare headers for a HttpUri.
     497             :  */
     498             : RequestMessagePtr prepareHeaders(const envoy::config::core::v3::HttpUri& http_uri);
     499             : 
     500             : /**
     501             :  * Returns string representation of StreamResetReason.
     502             :  */
     503             : const std::string resetReasonToString(const Http::StreamResetReason reset_reason);
     504             : 
     505             : /**
     506             :  * Transforms the supplied headers from an HTTP/1 Upgrade request to an H2 style upgrade.
     507             :  * Changes the method to connection, moves the Upgrade to a :protocol header,
     508             :  * @param headers the headers to convert.
     509             :  */
     510             : void transformUpgradeRequestFromH1toH2(RequestHeaderMap& headers);
     511             : 
     512             : /**
     513             :  * Transforms the supplied headers from an HTTP/1 Upgrade request to an H3 style upgrade,
     514             :  * which is the same as the H2 upgrade.
     515             :  * @param headers the headers to convert.
     516             :  */
     517             : void transformUpgradeRequestFromH1toH3(RequestHeaderMap& headers);
     518             : 
     519             : /**
     520             :  * Transforms the supplied headers from an HTTP/1 Upgrade response to an H2 style upgrade response.
     521             :  * Changes the 101 upgrade response to a 200 for the CONNECT response.
     522             :  * @param headers the headers to convert.
     523             :  */
     524             : void transformUpgradeResponseFromH1toH2(ResponseHeaderMap& headers);
     525             : 
     526             : /**
     527             :  * Transforms the supplied headers from an HTTP/1 Upgrade response to an H3 style upgrade response,
     528             :  * which is the same as the H2 style upgrade.
     529             :  * @param headers the headers to convert.
     530             :  */
     531             : void transformUpgradeResponseFromH1toH3(ResponseHeaderMap& headers);
     532             : 
     533             : /**
     534             :  * Transforms the supplied headers from an H2 "CONNECT"-with-:protocol-header to an HTTP/1 style
     535             :  * Upgrade response.
     536             :  * @param headers the headers to convert.
     537             :  */
     538             : void transformUpgradeRequestFromH2toH1(RequestHeaderMap& headers);
     539             : 
     540             : /**
     541             :  * Transforms the supplied headers from an H3 "CONNECT"-with-:protocol-header to an HTTP/1 style
     542             :  * Upgrade response. Same as H2 upgrade response transform
     543             :  * @param headers the headers to convert.
     544             :  */
     545             : void transformUpgradeRequestFromH3toH1(RequestHeaderMap& headers);
     546             : 
     547             : /**
     548             :  * Transforms the supplied headers from an H2 "CONNECT success" to an HTTP/1 style Upgrade response.
     549             :  * The caller is responsible for ensuring this only happens on upgraded streams.
     550             :  * @param headers the headers to convert.
     551             :  * @param upgrade the HTTP Upgrade token.
     552             :  */
     553             : void transformUpgradeResponseFromH2toH1(ResponseHeaderMap& headers, absl::string_view upgrade);
     554             : 
     555             : /**
     556             :  * Transforms the supplied headers from an H2 "CONNECT success" to an HTTP/1 style Upgrade response.
     557             :  * The caller is responsible for ensuring this only happens on upgraded streams.
     558             :  * Same as H2 Upgrade response transform
     559             :  * @param headers the headers to convert.
     560             :  * @param upgrade the HTTP Upgrade token.
     561             :  */
     562             : void transformUpgradeResponseFromH3toH1(ResponseHeaderMap& headers, absl::string_view upgrade);
     563             : 
     564             : /**
     565             :  * Retrieves the route specific config. Route specific config can be in a few
     566             :  * places, that are checked in order. The first config found is returned. The
     567             :  * order is:
     568             :  * - the routeEntry() (for config that's applied on weighted clusters)
     569             :  * - the route
     570             :  * - and finally from the virtual host object (routeEntry()->virtualhost()).
     571             :  *
     572             :  * To use, simply:
     573             :  *
     574             :  *     const auto* config =
     575             :  *         Utility::resolveMostSpecificPerFilterConfig<ConcreteType>(stream_callbacks_);
     576             :  *
     577             :  * See notes about config's lifetime below.
     578             :  *
     579             :  * @param callbacks The stream filter callbacks to check for route configs.
     580             :  *
     581             :  * @return The route config if found. nullptr if not found. The returned
     582             :  * pointer's lifetime is the same as the matched route.
     583             :  */
     584             : template <class ConfigType>
     585         150 : const ConfigType* resolveMostSpecificPerFilterConfig(const Http::StreamFilterCallbacks* callbacks) {
     586         150 :   static_assert(std::is_base_of<Router::RouteSpecificFilterConfig, ConfigType>::value,
     587         150 :                 "ConfigType must be a subclass of Router::RouteSpecificFilterConfig");
     588         150 :   ASSERT(callbacks != nullptr);
     589         150 :   return dynamic_cast<const ConfigType*>(callbacks->mostSpecificPerFilterConfig());
     590         150 : }
     591             : 
     592             : /**
     593             :  * Merge all the available per route filter configs into one. To perform the merge,
     594             :  * the reduce function will be called on each two configs until a single merged config is left.
     595             :  *
     596             :  * @param reduce The first argument for this function will be the config from the previous level
     597             :  * and the second argument is the config from the current level (the more specific one). The
     598             :  * function should merge the second argument into the first argument.
     599             :  *
     600             :  * @return The merged config.
     601             :  */
     602             : template <class ConfigType>
     603             : absl::optional<ConfigType>
     604             : getMergedPerFilterConfig(const Http::StreamFilterCallbacks* callbacks,
     605          32 :                          std::function<void(ConfigType&, const ConfigType&)> reduce) {
     606          32 :   static_assert(std::is_copy_constructible<ConfigType>::value,
     607          32 :                 "ConfigType must be copy constructible");
     608          32 :   ASSERT(callbacks != nullptr);
     609             : 
     610          32 :   absl::optional<ConfigType> merged;
     611             : 
     612          32 :   callbacks->traversePerFilterConfig([&reduce,
     613          32 :                                       &merged](const Router::RouteSpecificFilterConfig& cfg) {
     614           0 :     const ConfigType* typed_cfg = dynamic_cast<const ConfigType*>(&cfg);
     615           0 :     if (typed_cfg == nullptr) {
     616           0 :       ENVOY_LOG_MISC(debug, "Failed to retrieve the correct type of route specific filter config");
     617           0 :       return;
     618           0 :     }
     619           0 :     if (!merged) {
     620           0 :       merged.emplace(*typed_cfg);
     621           0 :     } else {
     622           0 :       reduce(merged.value(), *typed_cfg);
     623           0 :     }
     624           0 :   });
     625             : 
     626          32 :   return merged;
     627          32 : }
     628             : 
     629             : struct AuthorityAttributes {
     630             :   // whether parsed authority is pure ip address(IPv4/IPv6), if it is true
     631             :   // passed that are not FQDN
     632             :   bool is_ip_address_{};
     633             : 
     634             :   // If parsed authority has host, that is stored here.
     635             :   absl::string_view host_;
     636             : 
     637             :   // If parsed authority has port, that is stored here.
     638             :   absl::optional<uint16_t> port_;
     639             : };
     640             : 
     641             : /**
     642             :  * Parse passed authority, and get that is valid FQDN or IPv4/IPv6 address, hostname and port-name.
     643             :  * @param host host/authority
     644             :  * @param default_port If passed authority does not have port, this value is returned
     645             :  * @return hostname parse result. that includes whether host is IP Address, hostname and port-name
     646             :  */
     647             : AuthorityAttributes parseAuthority(absl::string_view host);
     648             : 
     649             : /**
     650             :  * It validates RetryPolicy defined in core api. It should be called at the main thread as
     651             :  * it may throw exception.
     652             :  * @param retry_policy core retry policy
     653             :  */
     654             : void validateCoreRetryPolicy(const envoy::config::core::v3::RetryPolicy& retry_policy);
     655             : 
     656             : /**
     657             :  * It returns RetryPolicy defined in core api to route api.
     658             :  * @param retry_policy core retry policy
     659             :  * @param retry_on this specifies when retry should be invoked.
     660             :  * @return route retry policy
     661             :  */
     662             : envoy::config::route::v3::RetryPolicy
     663             : convertCoreToRouteRetryPolicy(const envoy::config::core::v3::RetryPolicy& retry_policy,
     664             :                               const std::string& retry_on);
     665             : 
     666             : /**
     667             :  * @param request_headers the request header to be looked into.
     668             :  * @return true if the request method is safe as defined in
     669             :  * https://www.rfc-editor.org/rfc/rfc7231#section-4.2.1
     670             :  */
     671             : bool isSafeRequest(const Http::RequestHeaderMap& request_headers);
     672             : 
     673             : /**
     674             :  * @param value: the value of the referer header field
     675             :  * @return true if the given value conforms to RFC specifications
     676             :  * https://www.rfc-editor.org/rfc/rfc7231#section-5.5.2
     677             :  */
     678             : bool isValidRefererValue(absl::string_view value);
     679             : 
     680             : /**
     681             :  * Return the GatewayTimeout HTTP code to indicate the request is full received.
     682             :  */
     683             : Http::Code maybeRequestTimeoutCode(bool remote_decode_complete);
     684             : 
     685             : /**
     686             :  * Container for route config elements that pertain to a redirect.
     687             :  */
     688             : struct RedirectConfig {
     689             :   const std::string scheme_redirect_;
     690             :   const std::string host_redirect_;
     691             :   const std::string port_redirect_;
     692             :   const std::string path_redirect_;
     693             :   const std::string prefix_rewrite_redirect_;
     694             :   const std::string regex_rewrite_redirect_substitution_;
     695             :   Regex::CompiledMatcherPtr regex_rewrite_redirect_;
     696             :   // Keep small members (bools and enums) at the end of class, to reduce alignment overhead.
     697             :   const bool path_redirect_has_query_;
     698             :   const bool https_redirect_;
     699             :   const bool strip_query_;
     700             : };
     701             : 
     702             : /**
     703             :  * Validates the provided scheme is valid (either http or https)
     704             :  * @param scheme the scheme to validate
     705             :  * @return bool true if the scheme is valid.
     706             :  */
     707             : bool schemeIsValid(const absl::string_view scheme);
     708             : 
     709             : /**
     710             :  * @param scheme the scheme to validate
     711             :  * @return bool true if the scheme is http.
     712             :  */
     713             : bool schemeIsHttp(const absl::string_view scheme);
     714             : 
     715             : /**
     716             :  * @param scheme the scheme to validate
     717             :  * @return bool true if the scheme is https.
     718             :  */
     719             : bool schemeIsHttps(const absl::string_view scheme);
     720             : 
     721             : /*
     722             :  * Compute new path based on RedirectConfig.
     723             :  */
     724             : std::string newUri(::Envoy::OptRef<const RedirectConfig> redirect_config,
     725             :                    const Http::RequestHeaderMap& headers);
     726             : 
     727             : } // namespace Utility
     728             : } // namespace Http
     729             : } // namespace Envoy

Generated by: LCOV version 1.15