LCOV - code coverage report
Current view: top level - source/extensions/http/stateful_session/cookie - cookie.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 41 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 6 0.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <chrono>
       4             : #include <functional>
       5             : #include <memory>
       6             : 
       7             : #include "envoy/extensions/http/stateful_session/cookie/v3/cookie.pb.h"
       8             : #include "envoy/http/hash_policy.h"
       9             : #include "envoy/http/stateful_session.h"
      10             : 
      11             : #include "source/common/common/base64.h"
      12             : #include "source/common/http/utility.h"
      13             : #include "source/extensions/http/stateful_session/cookie/cookie.pb.h"
      14             : 
      15             : namespace Envoy {
      16             : namespace Extensions {
      17             : namespace Http {
      18             : namespace StatefulSession {
      19             : namespace Cookie {
      20             : 
      21             : using CookieBasedSessionStateProto =
      22             :     envoy::extensions::http::stateful_session::cookie::v3::CookieBasedSessionState;
      23             : 
      24             : class CookieBasedSessionStateFactory : public Envoy::Http::SessionStateFactory {
      25             : public:
      26             :   class SessionStateImpl : public Envoy::Http::SessionState {
      27             :   public:
      28             :     SessionStateImpl(absl::optional<std::string> address,
      29             :                      const CookieBasedSessionStateFactory& factory, TimeSource& time_source)
      30           0 :         : upstream_address_(std::move(address)), factory_(factory), time_source_(time_source) {}
      31             : 
      32           0 :     absl::optional<absl::string_view> upstreamAddress() const override { return upstream_address_; }
      33             :     void onUpdate(const Upstream::HostDescription& host,
      34             :                   Envoy::Http::ResponseHeaderMap& headers) override;
      35             : 
      36             :   private:
      37             :     absl::optional<std::string> upstream_address_;
      38             :     const CookieBasedSessionStateFactory& factory_;
      39             :     TimeSource& time_source_;
      40             :   };
      41             : 
      42             :   CookieBasedSessionStateFactory(const CookieBasedSessionStateProto& config,
      43             :                                  TimeSource& time_source);
      44             : 
      45           0 :   Envoy::Http::SessionStatePtr create(const Envoy::Http::RequestHeaderMap& headers) const override {
      46           0 :     if (!requestPathMatch(headers.getPathValue())) {
      47           0 :       return nullptr;
      48           0 :     }
      49             : 
      50           0 :     return std::make_unique<SessionStateImpl>(parseAddress(headers), *this, time_source_);
      51           0 :   }
      52             : 
      53           0 :   bool requestPathMatch(absl::string_view request_path) const {
      54           0 :     ASSERT(path_matcher_ != nullptr);
      55           0 :     return path_matcher_(request_path);
      56           0 :   }
      57             : 
      58             : private:
      59           0 :   absl::optional<std::string> parseAddress(const Envoy::Http::RequestHeaderMap& headers) const {
      60           0 :     const std::string cookie_value = Envoy::Http::Utility::parseCookieValue(headers, name_);
      61           0 :     if (cookie_value.empty()) {
      62           0 :       return absl::nullopt;
      63           0 :     }
      64           0 :     const std::string decoded_value = Envoy::Base64::decode(cookie_value);
      65           0 :     std::string address;
      66             : 
      67             :     // Try to interpret the cookie as proto payload.
      68             :     // Otherwise treat it as "old" style format, which is ip-address:port.
      69           0 :     envoy::Cookie cookie;
      70           0 :     if (cookie.ParseFromString(decoded_value)) {
      71           0 :       address = cookie.address();
      72           0 :       if (address.empty() || (cookie.expires() == 0)) {
      73           0 :         return absl::nullopt;
      74           0 :       }
      75             : 
      76           0 :       std::chrono::seconds expiry_time(cookie.expires());
      77           0 :       auto now = std::chrono::duration_cast<std::chrono::seconds>(
      78           0 :           (time_source_.monotonicTime()).time_since_epoch());
      79           0 :       if (now > expiry_time) {
      80             :         // Ignore the address extracted from the cookie. This will cause
      81             :         // upstream cluster to select a new host and new cookie will be generated.
      82           0 :         return absl::nullopt;
      83           0 :       }
      84           0 :     } else {
      85           0 :       ENVOY_LOG_ONCE_MISC(
      86           0 :           warn, "Non-proto cookie format detected. This format will be rejected in the future.");
      87           0 :       address = decoded_value;
      88           0 :     }
      89             : 
      90           0 :     return address.empty() ? absl::nullopt : absl::make_optional(std::move(address));
      91           0 :   }
      92             : 
      93           0 :   std::string makeSetCookie(const std::string& address) const {
      94           0 :     return Envoy::Http::Utility::makeSetCookieValue(name_, address, path_, ttl_, true, attributes_);
      95           0 :   }
      96             : 
      97             :   const std::string name_;
      98             :   const std::chrono::seconds ttl_;
      99             :   const std::string path_;
     100             :   const Envoy::Http::CookieAttributeRefVector attributes_;
     101             :   TimeSource& time_source_;
     102             : 
     103             :   std::function<bool(absl::string_view)> path_matcher_;
     104             : };
     105             : 
     106             : } // namespace Cookie
     107             : } // namespace StatefulSession
     108             : } // namespace Http
     109             : } // namespace Extensions
     110             : } // namespace Envoy

Generated by: LCOV version 1.15