LCOV - code coverage report
Current view: top level - source/extensions/health_checkers/http - health_checker_impl.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 13 24 54.2 %
Date: 2024-01-05 06:35:25 Functions: 7 16 43.8 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstdint>
       4             : 
       5             : #include "envoy/access_log/access_log.h"
       6             : #include "envoy/api/api.h"
       7             : #include "envoy/common/random_generator.h"
       8             : #include "envoy/config/core/v3/health_check.pb.h"
       9             : #include "envoy/data/core/v3/health_check_event.pb.h"
      10             : #include "envoy/grpc/status.h"
      11             : #include "envoy/network/socket.h"
      12             : #include "envoy/server/health_checker_config.h"
      13             : #include "envoy/type/v3/http.pb.h"
      14             : #include "envoy/type/v3/range.pb.h"
      15             : 
      16             : #include "source/common/common/dump_state_utils.h"
      17             : #include "source/common/common/logger.h"
      18             : #include "source/common/grpc/codec.h"
      19             : #include "source/common/http/codec_client.h"
      20             : #include "source/common/router/header_parser.h"
      21             : #include "source/common/stream_info/stream_info_impl.h"
      22             : #include "source/common/upstream/health_checker_impl.h"
      23             : #include "source/extensions/health_checkers/common/health_checker_base_impl.h"
      24             : 
      25             : #include "src/proto/grpc/health/v1/health.pb.h"
      26             : 
      27             : namespace Envoy {
      28             : namespace Upstream {
      29             : 
      30             : class HttpHealthCheckerFactory : public Server::Configuration::CustomHealthCheckerFactory {
      31             : public:
      32             :   Upstream::HealthCheckerSharedPtr
      33             :   createCustomHealthChecker(const envoy::config::core::v3::HealthCheck& config,
      34             :                             Server::Configuration::HealthCheckerFactoryContext& context) override;
      35             : 
      36         148 :   std::string name() const override { return "envoy.health_checkers.http"; }
      37          12 :   ProtobufTypes::MessagePtr createEmptyConfigProto() override {
      38          12 :     return ProtobufTypes::MessagePtr{new envoy::config::core::v3::HealthCheck::HttpHealthCheck()};
      39          12 :   }
      40             : };
      41             : 
      42             : DECLARE_FACTORY(HttpHealthCheckerFactory);
      43             : 
      44             : /**
      45             :  * HTTP health checker implementation. Connection keep alive is used where possible.
      46             :  */
      47             : class HttpHealthCheckerImpl : public HealthCheckerImplBase {
      48             : public:
      49             :   HttpHealthCheckerImpl(const Cluster& cluster, const envoy::config::core::v3::HealthCheck& config,
      50             :                         Event::Dispatcher& dispatcher, Runtime::Loader& runtime,
      51             :                         Random::RandomGenerator& random, HealthCheckEventLoggerPtr&& event_logger);
      52             : 
      53             :   // Returns the HTTP protocol used for the health checker.
      54             :   Http::Protocol protocol() const;
      55             : 
      56             :   /**
      57             :    * Utility class checking if given http status matches configured expectations.
      58             :    */
      59             :   class HttpStatusChecker {
      60             :   public:
      61             :     HttpStatusChecker(
      62             :         const Protobuf::RepeatedPtrField<envoy::type::v3::Int64Range>& expected_statuses,
      63             :         const Protobuf::RepeatedPtrField<envoy::type::v3::Int64Range>& retriable_statuses,
      64             :         uint64_t default_expected_status);
      65             : 
      66             :     bool inRetriableRanges(uint64_t http_status) const;
      67             :     bool inExpectedRanges(uint64_t http_status) const;
      68             : 
      69             :   private:
      70             :     static bool inRanges(uint64_t http_status,
      71             :                          const std::vector<std::pair<uint64_t, uint64_t>>& ranges);
      72             :     static void validateRange(uint64_t start, uint64_t end, absl::string_view range_type);
      73             : 
      74             :     std::vector<std::pair<uint64_t, uint64_t>> expected_ranges_;
      75             :     std::vector<std::pair<uint64_t, uint64_t>> retriable_ranges_;
      76             :   };
      77             : 
      78             : private:
      79             :   struct HttpActiveHealthCheckSession : public ActiveHealthCheckSession,
      80             :                                         public Http::ResponseDecoder,
      81             :                                         public Http::StreamCallbacks {
      82             :     HttpActiveHealthCheckSession(HttpHealthCheckerImpl& parent, const HostSharedPtr& host);
      83             :     ~HttpActiveHealthCheckSession() override;
      84             : 
      85             :     void onResponseComplete();
      86             :     enum class HealthCheckResult { Succeeded, Degraded, Failed, Retriable };
      87             :     HealthCheckResult healthCheckResult();
      88             :     bool shouldClose() const;
      89             : 
      90             :     // ActiveHealthCheckSession
      91             :     void onInterval() override;
      92             :     void onTimeout() override;
      93             :     void onDeferredDelete() final;
      94             : 
      95             :     // Http::StreamDecoder
      96             :     void decodeData(Buffer::Instance& data, bool end_stream) override;
      97           0 :     void decodeMetadata(Http::MetadataMapPtr&&) override {}
      98             : 
      99             :     // Http::ResponseDecoder
     100           0 :     void decode1xxHeaders(Http::ResponseHeaderMapPtr&&) override {}
     101             :     void decodeHeaders(Http::ResponseHeaderMapPtr&& headers, bool end_stream) override;
     102           0 :     void decodeTrailers(Http::ResponseTrailerMapPtr&&) override { onResponseComplete(); }
     103           0 :     void dumpState(std::ostream& os, int indent_level) const override {
     104           0 :       DUMP_STATE_UNIMPLEMENTED(HttpActiveHealthCheckSession);
     105           0 :     }
     106             : 
     107             :     // Http::StreamCallbacks
     108             :     void onResetStream(Http::StreamResetReason reason,
     109             :                        absl::string_view transport_failure_reason) override;
     110           0 :     void onAboveWriteBufferHighWatermark() override {}
     111           0 :     void onBelowWriteBufferLowWatermark() override {}
     112             : 
     113             :     void onEvent(Network::ConnectionEvent event);
     114             :     void onGoAway(Http::GoAwayErrorCode error_code);
     115             : 
     116             :     class ConnectionCallbackImpl : public Network::ConnectionCallbacks {
     117             :     public:
     118          22 :       ConnectionCallbackImpl(HttpActiveHealthCheckSession& parent) : parent_(parent) {}
     119             :       // Network::ConnectionCallbacks
     120          31 :       void onEvent(Network::ConnectionEvent event) override { parent_.onEvent(event); }
     121           0 :       void onAboveWriteBufferHighWatermark() override {}
     122           0 :       void onBelowWriteBufferLowWatermark() override {}
     123             : 
     124             :     private:
     125             :       HttpActiveHealthCheckSession& parent_;
     126             :     };
     127             : 
     128             :     class HttpConnectionCallbackImpl : public Http::ConnectionCallbacks {
     129             :     public:
     130          22 :       HttpConnectionCallbackImpl(HttpActiveHealthCheckSession& parent) : parent_(parent) {}
     131             :       // Http::ConnectionCallbacks
     132           0 :       void onGoAway(Http::GoAwayErrorCode error_code) override { parent_.onGoAway(error_code); }
     133             : 
     134             :     private:
     135             :       HttpActiveHealthCheckSession& parent_;
     136             :     };
     137             : 
     138             :     ConnectionCallbackImpl connection_callback_impl_{*this};
     139             :     HttpConnectionCallbackImpl http_connection_callback_impl_{*this};
     140             :     HttpHealthCheckerImpl& parent_;
     141             :     Http::CodecClientPtr client_;
     142             :     Http::ResponseHeaderMapPtr response_headers_;
     143             :     Buffer::InstancePtr response_body_;
     144             :     const std::string& hostname_;
     145             :     Network::ConnectionInfoProviderSharedPtr local_connection_info_provider_;
     146             :     // Keep small members (bools and enums) at the end of class, to reduce alignment overhead.
     147             :     const Http::Protocol protocol_;
     148             :     bool expect_reset_ : 1;
     149             :     bool reuse_connection_ : 1;
     150             :     bool request_in_flight_ : 1;
     151             :   };
     152             : 
     153             :   using HttpActiveHealthCheckSessionPtr = std::unique_ptr<HttpActiveHealthCheckSession>;
     154             : 
     155             :   virtual Http::CodecClient* createCodecClient(Upstream::Host::CreateConnectionData& data) PURE;
     156             : 
     157             :   // HealthCheckerImplBase
     158          22 :   ActiveHealthCheckSessionPtr makeSession(HostSharedPtr host) override {
     159          22 :     return std::make_unique<HttpActiveHealthCheckSession>(*this, host);
     160          22 :   }
     161          21 :   envoy::data::core::v3::HealthCheckerType healthCheckerType() const override {
     162          21 :     return envoy::data::core::v3::HTTP;
     163          21 :   }
     164             : 
     165             :   Http::CodecType codecClientType(const envoy::type::v3::CodecClientType& type);
     166             : 
     167             :   const std::string path_;
     168             :   const std::string host_value_;
     169             :   PayloadMatcher::MatchSegments receive_bytes_;
     170             :   const envoy::config::core::v3::RequestMethod method_;
     171             :   uint64_t response_buffer_size_;
     172             :   absl::optional<Matchers::StringMatcherImpl<envoy::type::matcher::v3::StringMatcher>>
     173             :       service_name_matcher_;
     174             :   Router::HeaderParserPtr request_headers_parser_;
     175             :   const HttpStatusChecker http_status_checker_;
     176             : 
     177             : protected:
     178             :   const Http::CodecType codec_client_type_;
     179             :   Random::RandomGenerator& random_generator_;
     180             : };
     181             : 
     182             : /**
     183             :  * Production implementation of the HTTP health checker that allocates a real codec client.
     184             :  */
     185             : class ProdHttpHealthCheckerImpl : public HttpHealthCheckerImpl {
     186             : public:
     187             :   using HttpHealthCheckerImpl::HttpHealthCheckerImpl;
     188             : 
     189             :   // HttpHealthCheckerImpl
     190             :   Http::CodecClient* createCodecClient(Upstream::Host::CreateConnectionData& data) override;
     191             : };
     192             : 
     193             : } // namespace Upstream
     194             : } // namespace Envoy

Generated by: LCOV version 1.15