// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include ZEN_THIRD_PARTY_INCLUDES_START #include ZEN_THIRD_PARTY_INCLUDES_END #include #include #include #include namespace zen { class HttpTrafficInspector { public: enum class Direction { Request, Response }; HttpTrafficInspector(Direction Dir, std::string_view SessionLabel); void Inspect(const char* Data, size_t Length); uint64_t GetMessageCount() const { return m_MessageCount.load(std::memory_order_relaxed); } bool IsUpgraded() const { return m_Upgraded.load(std::memory_order_relaxed); } Oid GetSessionId() const; bool HasSessionId() const; void SetObserver(class IHttpTrafficObserver* Observer) { m_Observer = Observer; } private: int OnUrl(const char* Data, size_t Length); int OnHeaderField(const char* Data, size_t Length); int OnHeaderValue(const char* Data, size_t Length); int OnHeadersComplete(); int OnMessageComplete(); void ResetMessageState(); static HttpTrafficInspector* GetThis(http_parser* Parser) { return static_cast(Parser->data); } static http_parser_settings s_RequestSettings; static http_parser_settings s_ResponseSettings; LoggerRef Log() { return m_Log; } LoggerRef m_Log; http_parser m_Parser; Direction m_Direction; std::string m_SessionLabel; bool m_Disabled = false; // Per-message state std::string m_Url; std::string m_Method; uint16_t m_StatusCode = 0; int64_t m_ContentLength = -1; std::string m_CurrentHeaderField; std::atomic m_MessageCount{0}; std::atomic m_Upgraded{false}; Oid m_SessionId = Oid::Zero; bool m_SessionIdCaptured = false; IHttpTrafficObserver* m_Observer = nullptr; }; class IHttpTrafficObserver { public: virtual ~IHttpTrafficObserver() = default; virtual void OnMessageComplete(HttpTrafficInspector::Direction Dir, std::string_view Method, std::string_view Url, uint16_t StatusCode, int64_t ContentLength) = 0; }; } // namespace zen