aboutsummaryrefslogtreecommitdiff
path: root/src/zenhttp/clients/httpclientcommon.h
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-09-30 19:07:51 +0200
committerGitHub Enterprise <[email protected]>2025-09-30 19:07:51 +0200
commit634181a04efff90def7a98d98eac7078e1d4e62d (patch)
tree04678bba636a76d21f300ff6e73af4473274cf12 /src/zenhttp/clients/httpclientcommon.h
parentuse batching clang-format for quicker turnaround on validate actions (#529) (diff)
downloadzen-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.h147
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