LCOV - code coverage report
Current view: top level - source/common/grpc - common.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 1 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 1 0.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstdint>
       4             : #include <string>
       5             : 
       6             : #include "envoy/common/exception.h"
       7             : #include "envoy/common/platform.h"
       8             : #include "envoy/grpc/status.h"
       9             : #include "envoy/http/filter.h"
      10             : #include "envoy/http/header_map.h"
      11             : #include "envoy/http/message.h"
      12             : 
      13             : #include "source/common/common/hash.h"
      14             : #include "source/common/grpc/status.h"
      15             : #include "source/common/protobuf/protobuf.h"
      16             : 
      17             : #include "absl/types/optional.h"
      18             : #include "google/rpc/status.pb.h"
      19             : 
      20             : namespace Envoy {
      21             : namespace Grpc {
      22             : 
      23             : class Exception : public EnvoyException {
      24             : public:
      25             :   Exception(const absl::optional<uint64_t>& grpc_status, const std::string& message)
      26           0 :       : EnvoyException(message), grpc_status_(grpc_status) {}
      27             : 
      28             :   const absl::optional<uint64_t> grpc_status_;
      29             : };
      30             : 
      31             : class Common {
      32             : public:
      33             :   /**
      34             :    * @param headers the headers to parse.
      35             :    * @return bool indicating whether content-type is gRPC.
      36             :    */
      37             :   static bool hasGrpcContentType(const Http::RequestOrResponseHeaderMap& headers);
      38             : 
      39             :   /**
      40             :    * @param headers the headers to parse.
      41             :    * @return bool indicating whether Connect-Protocol-Version is present.
      42             :    */
      43             :   static bool hasConnectProtocolVersionHeader(const Http::RequestOrResponseHeaderMap& headers);
      44             : 
      45             :   /**
      46             :    * @param headers the headers to parse.
      47             :    * @return bool indicating whether content-type is connect streaming.
      48             :    */
      49             :   static bool hasConnectStreamingContentType(const Http::RequestOrResponseHeaderMap& headers);
      50             : 
      51             :   /**
      52             :    * @param headers the headers to parse.
      53             :    * @return bool indicating whether content-type is Protobuf.
      54             :    */
      55             :   static bool hasProtobufContentType(const Http::RequestOrResponseHeaderMap& headers);
      56             : 
      57             :   /**
      58             :    * @param headers the headers to parse.
      59             :    * @return bool indicating whether the header is a gRPC request header.
      60             :    * Currently headers are considered gRPC request headers if they have the gRPC
      61             :    * content type, and have a path header.
      62             :    */
      63             :   static bool isGrpcRequestHeaders(const Http::RequestHeaderMap& headers);
      64             : 
      65             :   /**
      66             :    * @param headers the headers to parse.
      67             :    * @return bool indicating whether the header is a Connect request header.
      68             :    * This is determined by checking for the connect protocol version header and a path header.
      69             :    */
      70             :   static bool isConnectRequestHeaders(const Http::RequestHeaderMap& headers);
      71             : 
      72             :   /**
      73             :    * @param headers the headers to parse.
      74             :    * @return bool indicating whether the header is a Connect streaming request header.
      75             :    * This is determined by checking for the connect streaming content type and a path header.
      76             :    */
      77             :   static bool isConnectStreamingRequestHeaders(const Http::RequestHeaderMap& headers);
      78             : 
      79             :   /**
      80             :    * @param headers the headers to parse.
      81             :    * @return bool indicating whether the header is a protobuf request header.
      82             :    * Currently headers are considered gRPC request headers if they have the protobuf
      83             :    * content type, and have a path header.
      84             :    */
      85             :   static bool isProtobufRequestHeaders(const Http::RequestHeaderMap& headers);
      86             : 
      87             :   /**
      88             :    * @param headers the headers to parse.
      89             :    * @param bool indicating whether the header is at end_stream.
      90             :    * @return bool indicating whether the header is a gRPC response header
      91             :    */
      92             :   static bool isGrpcResponseHeaders(const Http::ResponseHeaderMap& headers, bool end_stream);
      93             : 
      94             :   /**
      95             :    * @param headers the headers to parse.
      96             :    * @return bool indicating whether the header is a Connect streaming response header.
      97             :    */
      98             :   static bool isConnectStreamingResponseHeaders(const Http::ResponseHeaderMap& headers);
      99             : 
     100             :   /**
     101             :    * Returns the GrpcStatus code from a given set of trailers, if present.
     102             :    * @param trailers the trailers to parse.
     103             :    * @param allow_user_status whether allow user defined grpc status.
     104             :    *        if this value is false, custom grpc status is regarded as invalid status
     105             :    * @return absl::optional<Status::GrpcStatus> the parsed status code or InvalidCode if no valid
     106             :    * status is found.
     107             :    */
     108             :   static absl::optional<Status::GrpcStatus>
     109             :   getGrpcStatus(const Http::ResponseHeaderOrTrailerMap& trailers, bool allow_user_defined = false);
     110             : 
     111             :   /**
     112             :    * Returns the GrpcStatus code from the set of trailers, headers, and StreamInfo, if present.
     113             :    * @param trailers the trailers to parse for a status code
     114             :    * @param headers the headers to parse if no status code was found in the trailers
     115             :    * @param info the StreamInfo to check for HTTP response code if no code was found in the trailers
     116             :    * or headers
     117             :    * @return absl::optional<Status::GrpcStatus> the parsed status code or absl::nullopt if no status
     118             :    * is found
     119             :    */
     120             :   static absl::optional<Status::GrpcStatus> getGrpcStatus(const Http::ResponseTrailerMap& trailers,
     121             :                                                           const Http::ResponseHeaderMap& headers,
     122             :                                                           const StreamInfo::StreamInfo& info,
     123             :                                                           bool allow_user_defined = false);
     124             : 
     125             :   /**
     126             :    * Returns the grpc-message from a given set of trailers, if present.
     127             :    * @param trailers the trailers to parse.
     128             :    * @return std::string the gRPC status message or empty string if grpc-message is not present in
     129             :    *         trailers.
     130             :    */
     131             :   static std::string getGrpcMessage(const Http::ResponseHeaderOrTrailerMap& trailers);
     132             : 
     133             :   /**
     134             :    * Returns the decoded google.rpc.Status message from a given set of trailers, if present.
     135             :    * @param trailers the trailers to parse.
     136             :    * @return std::unique_ptr<google::rpc::Status> the gRPC status message or empty pointer if no
     137             :    *         grpc-status-details-bin trailer found or it was invalid.
     138             :    */
     139             :   static absl::optional<google::rpc::Status>
     140             :   getGrpcStatusDetailsBin(const Http::HeaderMap& trailers);
     141             : 
     142             :   /**
     143             :    * Parse gRPC header 'grpc-timeout' value to a duration in milliseconds.
     144             :    * @param request_headers the header map from which to extract the value of 'grpc-timeout' header.
     145             :    *        If this header is missing the timeout corresponds to infinity. The header is encoded in
     146             :    *        maximum of 8 decimal digits and a char for the unit.
     147             :    * @return absl::optional<std::chrono::milliseconds> the duration in milliseconds. absl::nullopt
     148             :    *         is returned if 'grpc-timeout' is missing or malformed.
     149             :    */
     150             :   static absl::optional<std::chrono::milliseconds>
     151             :   getGrpcTimeout(const Http::RequestHeaderMap& request_headers);
     152             : 
     153             :   /**
     154             :    * Encode 'timeout' into 'grpc-timeout' format in the grpc-timeout header.
     155             :    * @param timeout the duration in std::chrono::milliseconds.
     156             :    * @param headers the HeaderMap in which the grpc-timeout header will be set with the timeout in
     157             :    * 'grpc-timeout' format, up to 8 decimal digits and a letter indicating the unit.
     158             :    */
     159             :   static void toGrpcTimeout(const std::chrono::milliseconds& timeout,
     160             :                             Http::RequestHeaderMap& headers);
     161             : 
     162             :   /**
     163             :    * Serialize protobuf message with gRPC frame header.
     164             :    */
     165             :   static Buffer::InstancePtr serializeToGrpcFrame(const Protobuf::Message& message);
     166             : 
     167             :   /**
     168             :    * Serialize protobuf message. Without grpc header.
     169             :    */
     170             :   static Buffer::InstancePtr serializeMessage(const Protobuf::Message& message);
     171             : 
     172             :   /**
     173             :    * Prepare headers for protobuf service.
     174             :    */
     175             :   static Http::RequestMessagePtr
     176             :   prepareHeaders(const std::string& upstream_cluster, const std::string& service_full_name,
     177             :                  const std::string& method_name,
     178             :                  const absl::optional<std::chrono::milliseconds>& timeout);
     179             : 
     180             :   /**
     181             :    * @return const std::string& type URL prefix.
     182             :    */
     183             :   static const std::string& typeUrlPrefix();
     184             : 
     185             :   /**
     186             :    * Prefix type URL to a qualified name.
     187             :    * @param qualified_name packagename.messagename.
     188             :    * @return qualified_name prefixed with typeUrlPrefix + "/".
     189             :    */
     190             :   static std::string typeUrl(const std::string& qualified_name);
     191             : 
     192             :   /**
     193             :    * Prepend a gRPC frame header to a Buffer::Instance containing a single gRPC frame.
     194             :    * @param buffer containing the frame data which will be modified.
     195             :    */
     196             :   static void prependGrpcFrameHeader(Buffer::Instance& buffer);
     197             : 
     198             :   /**
     199             :    * Parse a Buffer::Instance into a Protobuf::Message.
     200             :    * @param buffer containing the data to be parsed.
     201             :    * @param proto the parsed proto.
     202             :    * @return bool true if the parse was successful.
     203             :    */
     204             :   static bool parseBufferInstance(Buffer::InstancePtr&& buffer, Protobuf::Message& proto);
     205             : 
     206             :   struct RequestNames {
     207             :     absl::string_view service_;
     208             :     absl::string_view method_;
     209             :   };
     210             : 
     211             :   /**
     212             :    * Resolve the gRPC service and method from the HTTP2 :path header.
     213             :    * @param path supplies the :path header.
     214             :    * @return if both gRPC serve and method have been resolved successfully returns
     215             :    *   a populated RequestNames, otherwise returns an empty optional.
     216             :    * @note The return value is only valid as long as `path` is still valid and unmodified.
     217             :    */
     218             :   static absl::optional<RequestNames> resolveServiceAndMethod(const Http::HeaderEntry* path);
     219             : 
     220             : private:
     221             :   static constexpr size_t MAX_GRPC_TIMEOUT_VALUE = 99999999;
     222             : };
     223             : 
     224             : } // namespace Grpc
     225             : } // namespace Envoy

Generated by: LCOV version 1.15