diff options
| author | Stefan Boberg <[email protected]> | 2025-09-30 19:07:51 +0200 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-09-30 19:07:51 +0200 |
| commit | 634181a04efff90def7a98d98eac7078e1d4e62d (patch) | |
| tree | 04678bba636a76d21f300ff6e73af4473274cf12 /src/zenhttp/clients/httpclientcommon.h | |
| parent | use batching clang-format for quicker turnaround on validate actions (#529) (diff) | |
| download | zen-634181a04efff90def7a98d98eac7078e1d4e62d.tar.xz zen-634181a04efff90def7a98d98eac7078e1d4e62d.zip | |
HttpClient support for pluggable back-ends (#532)
refactored HttpClient to separate out cpr implementation into separate classes, with an abstract base class to allow plugging in multiple implementations in the future
Diffstat (limited to 'src/zenhttp/clients/httpclientcommon.h')
| -rw-r--r-- | src/zenhttp/clients/httpclientcommon.h | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/src/zenhttp/clients/httpclientcommon.h b/src/zenhttp/clients/httpclientcommon.h new file mode 100644 index 000000000..9060cde48 --- /dev/null +++ b/src/zenhttp/clients/httpclientcommon.h @@ -0,0 +1,147 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zencore/compositebuffer.h> +#include <zencore/trace.h> + +#include <zenhttp/httpclient.h> + +namespace zen { + +using namespace std::literals; + +class HttpClientBase +{ +public: + HttpClientBase(std::string_view BaseUri, const HttpClientSettings& Connectionsettings = {}); + 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; + + const std::optional<HttpClientAccessToken> 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<BufferedReadFileStream> m_SegmentDiskBuffer; + MemoryView m_SegmentMemoryBuffer; + uint64_t m_BytesLeftInSegment; + }; + +} // namespace detail + +} // namespace zen |