// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include #include #include namespace zen { using namespace std::literals; class HttpClientBase { public: HttpClientBase(std::string_view BaseUri, const HttpClientSettings& Connectionsettings, std::function&& CheckIfAbortFunction); virtual ~HttpClientBase() = 0; using Response = HttpClient::Response; using KeyValueMap = HttpClient::KeyValueMap; [[nodiscard]] virtual Response Put(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response Put(std::string_view Url, const KeyValueMap& Parameters = {}) = 0; [[nodiscard]] virtual Response Get(std::string_view Url, const KeyValueMap& AdditionalHeader = {}, const KeyValueMap& Parameters = {}) = 0; [[nodiscard]] virtual Response Head(std::string_view Url, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response Delete(std::string_view Url, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response Post(std::string_view Url, const KeyValueMap& AdditionalHeader = {}, const KeyValueMap& Parameters = {}) = 0; [[nodiscard]] virtual Response Post(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response Post(std::string_view Url, const IoBuffer& Payload, ZenContentType ContentType, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response Post(std::string_view Url, CbObject Payload, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response Post(std::string_view Url, CbPackage Payload, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response Post(std::string_view Url, const CompositeBuffer& Payload, ZenContentType ContentType, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response Upload(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response Upload(std::string_view Url, const CompositeBuffer& Payload, ZenContentType ContentType, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response Download(std::string_view Url, const std::filesystem::path& TempFolderPath, const KeyValueMap& AdditionalHeader = {}) = 0; [[nodiscard]] virtual Response TransactPackage(std::string_view Url, CbPackage Package, const KeyValueMap& AdditionalHeader = {}) = 0; LoggerRef Log() { return m_Log; } std::string_view GetBaseUri() const { return m_BaseUri; } std::string_view GetSessionId() const { return m_SessionId; } bool Authenticate(); protected: LoggerRef m_Log; std::string m_BaseUri; std::string m_SessionId; const HttpClientSettings m_ConnectionSettings; std::function m_CheckIfAbortFunction; const std::optional GetAccessToken(); RwLock m_AccessTokenLock; HttpClientAccessToken m_CachedAccessToken; }; namespace detail { class TempPayloadFile { public: TempPayloadFile(const TempPayloadFile&) = delete; TempPayloadFile& operator=(const TempPayloadFile&) = delete; TempPayloadFile(); ~TempPayloadFile(); std::error_code Open(const std::filesystem::path& TempFolderPath, uint64_t FinalSize); std::error_code Write(std::string_view DataString); IoBuffer DetachToIoBuffer(); IoBuffer BorrowIoBuffer(); inline uint64_t GetSize() const { return m_WriteOffset; } void ResetWritePos(uint64_t WriteOffset); private: std::error_code Flush(); std::error_code AppendData(const void* Data, uint64_t Size); void* m_FileHandle; std::uint64_t m_WriteOffset; static constexpr uint64_t CacheBufferSize = 512u * 1024u; uint8_t m_CacheBuffer[CacheBufferSize]; std::uint64_t m_CacheBufferOffset = 0; }; class BufferedReadFileStream { public: BufferedReadFileStream(const BufferedReadFileStream&) = delete; BufferedReadFileStream& operator=(const BufferedReadFileStream&) = delete; BufferedReadFileStream(void* FileHandle, uint64_t FileOffset, uint64_t FileSize, uint64_t BufferSize); ~BufferedReadFileStream(); void Read(void* Data, uint64_t Size); private: void Read(void* Data, uint64_t BytesToRead, uint64_t FileOffset); void* m_FileHandle = nullptr; const uint64_t m_FileSize = 0; const uint64_t m_FileEnd = 0; uint64_t m_BufferSize = 0; uint8_t* m_Buffer = nullptr; uint64_t m_BufferStart = 0; uint64_t m_BufferEnd = 0; uint64_t m_FileOffset = 0; }; class CompositeBufferReadStream { public: CompositeBufferReadStream(const CompositeBufferReadStream&) = delete; CompositeBufferReadStream& operator=(const CompositeBufferReadStream&) = delete; CompositeBufferReadStream(const CompositeBuffer& Data, uint64_t BufferSize); uint64_t Read(void* Data, uint64_t Size); private: const CompositeBuffer& m_Data; const uint64_t m_BufferSize; size_t m_SegmentIndex; std::unique_ptr m_SegmentDiskBuffer; MemoryView m_SegmentMemoryBuffer; uint64_t m_BytesLeftInSegment; }; } // namespace detail } // namespace zen