// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "httptrafficinspector.h" #include #include #include #include #include #include #include namespace zen { struct RecordedEntry { uint64_t ReqOffset = 0; uint64_t ReqSize = 0; uint64_t RespOffset = 0; uint64_t RespSize = 0; std::string Method; std::string Url; uint32_t Status = 0; }; class IHttpTrafficObserver; class HttpTrafficRecorder : public IHttpTrafficObserver { public: HttpTrafficRecorder(const std::filesystem::path& OutputDir, std::string_view ClientLabel, std::string_view TargetLabel); ~HttpTrafficRecorder(); bool IsValid() const { return m_Valid; } void WriteRequest(const char* Data, size_t Length); void WriteResponse(const char* Data, size_t Length); // IHttpTrafficObserver void OnMessageComplete(HttpTrafficInspector::Direction Dir, std::string_view Method, std::string_view Url, uint16_t StatusCode, int64_t ContentLength) override; void Finalize(bool WebSocket, const Oid& SessionId); private: LoggerRef Log() { return m_Log; } LoggerRef m_Log; std::filesystem::path m_Dir; std::string m_ClientLabel; std::string m_TargetLabel; uint64_t m_StartTimeMs = 0; bool m_Valid = false; bool m_Finalized = false; BasicFile m_RequestFile; BasicFile m_ResponseFile; uint64_t m_RequestOffset = 0; uint64_t m_ResponseOffset = 0; uint64_t m_CurrentRequestStart = 0; uint64_t m_CurrentResponseStart = 0; // Pending request metadata waiting for its paired response. std::string m_PendingMethod; std::string m_PendingUrl; uint64_t m_PendingReqOffset = 0; uint64_t m_PendingReqSize = 0; bool m_HasPendingRequest = false; std::vector m_Entries; }; } // namespace zen