LCOV - code coverage report
Current view: top level - envoy/http - header_validator.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 9 20 45.0 %
Date: 2024-01-05 06:35:25 Functions: 9 18 50.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <string>
       4             : #include <tuple>
       5             : 
       6             : #include "envoy/http/header_map.h"
       7             : #include "envoy/http/protocol.h"
       8             : 
       9             : namespace Envoy {
      10             : namespace Http {
      11             : 
      12             : /**
      13             :  * Common interface for server and client header validators.
      14             :  */
      15             : class HeaderValidator {
      16             : public:
      17           0 :   virtual ~HeaderValidator() = default;
      18             : 
      19             :   // A class that holds either success condition or an error condition with tuple of
      20             :   // action and error details.
      21             :   template <typename ActionType> class Result {
      22             :   public:
      23             :     using Action = ActionType;
      24             : 
      25             :     // Helper for constructing successful results
      26         801 :     static Result success() { return Result(ActionType::Accept, absl::string_view()); }
      27             : 
      28         879 :     Result(ActionType action, absl::string_view details) : result_(action, details) {
      29         879 :       ENVOY_BUG(action == ActionType::Accept || !details.empty(),
      30         879 :                 "Error details must not be empty in case of an error");
      31         879 :     }
      32             : 
      33         527 :     bool ok() const { return std::get<0>(result_) == ActionType::Accept; }
      34         373 :     operator bool() const { return ok(); }
      35           0 :     absl::string_view details() const { return std::get<1>(result_); }
      36         784 :     Action action() const { return std::get<0>(result_); }
      37             : 
      38             :   private:
      39             :     const std::tuple<ActionType, std::string> result_;
      40             :   };
      41             : 
      42             :   enum class RejectAction { Accept, Reject };
      43             :   enum class RejectOrRedirectAction { Accept, Reject, Redirect };
      44             :   using RejectResult = Result<RejectAction>;
      45             :   using RejectOrRedirectResult = Result<RejectOrRedirectAction>;
      46             :   using TransformationResult = RejectResult;
      47             : 
      48             :   /**
      49             :    * Validate the entire request header map.
      50             :    * Returning the Reject value form this method causes the HTTP request to be rejected with 400
      51             :    * status, and the gRPC request with the INTERNAL (13) error code.
      52             :    */
      53             :   using ValidationResult = RejectResult;
      54             :   virtual ValidationResult validateRequestHeaders(const RequestHeaderMap& header_map) PURE;
      55             : 
      56             :   /**
      57             :    * Validate the entire response header map.
      58             :    * Returning the Reject value causes the HTTP request to be rejected with the 502 status,
      59             :    * and the gRPC request with the UNAVAILABLE (14) error code.
      60             :    */
      61             :   virtual ValidationResult validateResponseHeaders(const ResponseHeaderMap& header_map) PURE;
      62             : 
      63             :   /**
      64             :    * Validate the entire request trailer map.
      65             :    * Returning the Reject value causes the HTTP request to be rejected with the 502 status,
      66             :    * and the gRPC request with the UNAVAILABLE (14) error code.
      67             :    * If response headers have already been sent the request is reset.
      68             :    */
      69             :   virtual ValidationResult validateRequestTrailers(const RequestTrailerMap& trailer_map) PURE;
      70             : 
      71             :   /**
      72             :    * Validate the entire response trailer map.
      73             :    * Returning the Reject value causes the HTTP request to be reset.
      74             :    */
      75             :   virtual ValidationResult validateResponseTrailers(const ResponseTrailerMap& trailer_map) PURE;
      76             : };
      77             : 
      78             : /**
      79             :  * Interface for server header validators.
      80             :  */
      81             : class ServerHeaderValidator : public HeaderValidator {
      82             : public:
      83           0 :   ~ServerHeaderValidator() override = default;
      84             : 
      85             :   /**
      86             :    * Transform the entire request header map.
      87             :    * This method transforms the header map, for example by normalizing URI path, before processing
      88             :    * by the filter chain.
      89             :    * Returning the Reject value from this method causes the HTTP request to be rejected with 400
      90             :    * status, and the gRPC request with the INTERNAL (13) error code. Returning the Redirect
      91             :    * value causes the HTTP request to be redirected to the :path presudo header in the request map.
      92             :    * The gRPC request will still be rejected with the INTERNAL (13) error code.
      93             :    */
      94             :   using RequestHeadersTransformationResult = RejectOrRedirectResult;
      95             :   virtual RequestHeadersTransformationResult
      96             :   transformRequestHeaders(RequestHeaderMap& header_map) PURE;
      97             : 
      98             :   /**
      99             :    * Transform the entire request trailer map.
     100             :    * Returning the Reject value causes the HTTP request to be rejected with the 502 status,
     101             :    * and the gRPC request with the UNAVAILABLE (14) error code.
     102             :    * If response headers have already been sent the request is reset.
     103             :    */
     104             :   virtual TransformationResult transformRequestTrailers(RequestTrailerMap& header_map) PURE;
     105             : 
     106             :   /**
     107             :    * Transform the entire response header map.
     108             :    * HTTP/2 and HTTP/3 server header validator may transform the HTTP/1 upgrade response
     109             :    * to HTTP/2 extended CONNECT response, iff it transformed extended CONNECT to upgrade request
     110             :    * during request validation.
     111             :    * Returning the Reject value causes the HTTP request to be rejected with the 502 status,
     112             :    * and the gRPC request with the UNAVAILABLE (14) error code.
     113             :    */
     114             :   struct ResponseHeadersTransformationResult {
     115           0 :     static ResponseHeadersTransformationResult success() {
     116           0 :       return ResponseHeadersTransformationResult{RejectResult::success(), nullptr};
     117           0 :     }
     118             :     RejectResult status;
     119             :     ResponseHeaderMapPtr new_headers;
     120             :   };
     121             :   virtual ResponseHeadersTransformationResult
     122             :   transformResponseHeaders(const ResponseHeaderMap& header_map) PURE;
     123             : };
     124             : 
     125             : /**
     126             :  * Interface for server header validators.
     127             :  */
     128             : class ClientHeaderValidator : public HeaderValidator {
     129             : public:
     130           0 :   ~ClientHeaderValidator() override = default;
     131             : 
     132             :   /**
     133             :    * Transform the entire request header map.
     134             :    * This method can not mutate the header map as it is immutable after the terminal decoder filter.
     135             :    * However HTTP/2 and HTTP/3 header validators may need to change the request from the HTTP/1
     136             :    * upgrade to to the extended CONNECT. In this case the new header map is returned in the
     137             :    * `new_headers` member of the returned structure. Returning the Reject value form this method
     138             :    * causes the HTTP request to be rejected with 400 status, and the gRPC request with the INTERNAL
     139             :    * (13) error code.
     140             :    */
     141             :   struct RequestHeadersTransformationResult {
     142           0 :     static RequestHeadersTransformationResult success() {
     143           0 :       return RequestHeadersTransformationResult{RejectResult::success(), nullptr};
     144           0 :     }
     145             :     RejectResult status;
     146             :     RequestHeaderMapPtr new_headers;
     147             :   };
     148             :   virtual RequestHeadersTransformationResult
     149             :   transformRequestHeaders(const RequestHeaderMap& header_map) PURE;
     150             : 
     151             :   /**
     152             :    * Transform the entire response header map.
     153             :    * HTTP/2 and HTTP/3 client header validator may transform the extended CONNECT response
     154             :    * to HTTP/1 upgrade response, iff it transformed upgrade request to extended CONNECT
     155             :    * during request validation.
     156             :    * Returning the Reject value causes the HTTP request to be rejected with the 502 status,
     157             :    * and the gRPC request with the UNAVAILABLE (14) error code.
     158             :    */
     159             :   virtual TransformationResult transformResponseHeaders(ResponseHeaderMap& header_map) PURE;
     160             : };
     161             : 
     162             : using ServerHeaderValidatorPtr = std::unique_ptr<ServerHeaderValidator>;
     163             : using ClientHeaderValidatorPtr = std::unique_ptr<ClientHeaderValidator>;
     164             : 
     165             : /**
     166             :  * Interface for stats.
     167             :  */
     168             : class HeaderValidatorStats {
     169             : public:
     170        2607 :   virtual ~HeaderValidatorStats() = default;
     171             : 
     172             :   virtual void incDroppedHeadersWithUnderscores() PURE;
     173             :   virtual void incRequestsRejectedWithUnderscoresInHeaders() PURE;
     174             :   virtual void incMessagingError() PURE;
     175             : };
     176             : 
     177             : /**
     178             :  * Interface for creating header validators.
     179             :  * TODO(yanavlasov): split into factories dedicated to server and client header validators.
     180             :  */
     181             : class HeaderValidatorFactory {
     182             : public:
     183           0 :   virtual ~HeaderValidatorFactory() = default;
     184             : 
     185             :   /**
     186             :    * Create a new header validator for the specified protocol.
     187             :    */
     188             :   virtual ServerHeaderValidatorPtr createServerHeaderValidator(Protocol protocol,
     189             :                                                                HeaderValidatorStats& stats) PURE;
     190             :   virtual ClientHeaderValidatorPtr createClientHeaderValidator(Protocol protocol,
     191             :                                                                HeaderValidatorStats& stats) PURE;
     192             : };
     193             : 
     194             : using HeaderValidatorFactoryPtr = std::unique_ptr<HeaderValidatorFactory>;
     195             : 
     196             : } // namespace Http
     197             : } // namespace Envoy

Generated by: LCOV version 1.15