// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "httpclientcommon.h" #include #include #include ZEN_THIRD_PARTY_INCLUDES_START #include #include ZEN_THIRD_PARTY_INCLUDES_END namespace zen { class CprHttpClient : public HttpClientBase { public: CprHttpClient(std::string_view BaseUri, const HttpClientSettings& Connectionsettings, std::function&& CheckIfAbortFunction); ~CprHttpClient(); // HttpClientBase [[nodiscard]] virtual Response Put(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response Put(std::string_view Url, const KeyValueMap& Parameters = {}) override; [[nodiscard]] virtual Response Get(std::string_view Url, const KeyValueMap& AdditionalHeader = {}, const KeyValueMap& Parameters = {}) override; [[nodiscard]] virtual Response Head(std::string_view Url, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response Delete(std::string_view Url, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response Post(std::string_view Url, const KeyValueMap& AdditionalHeader = {}, const KeyValueMap& Parameters = {}) override; [[nodiscard]] virtual Response Post(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response Post(std::string_view Url, const IoBuffer& Payload, ZenContentType ContentType, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response Post(std::string_view Url, CbObject Payload, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response Post(std::string_view Url, CbPackage Payload, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response Post(std::string_view Url, const CompositeBuffer& Payload, ZenContentType ContentType, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response Upload(std::string_view Url, const IoBuffer& Payload, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response Upload(std::string_view Url, const CompositeBuffer& Payload, ZenContentType ContentType, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response Download(std::string_view Url, const std::filesystem::path& TempFolderPath, const KeyValueMap& AdditionalHeader = {}) override; [[nodiscard]] virtual Response TransactPackage(std::string_view Url, CbPackage Package, const KeyValueMap& AdditionalHeader = {}) override; private: struct Session { Session(CprHttpClient* InOuter, cpr::Session* InSession) : Outer(InOuter), CprSession(InSession) {} ~Session() { Outer->ReleaseSession(CprSession); } inline cpr::Session* operator->() const { return CprSession; } inline cpr::Response Get() { ZEN_TRACE_CPU("HttpClient::Impl::Get"); cpr::Response Result = CprSession->Get(); ZEN_TRACE("GET {}", Result); return Result; } inline cpr::Response Download(cpr::WriteCallback&& Write, std::optional&& Header = {}) { ZEN_TRACE_CPU("HttpClient::Impl::Download"); if (Header) { CprSession->SetHeaderCallback(std::move(Header.value())); } cpr::Response Result = CprSession->Download(Write); ZEN_TRACE("GET {}", Result); CprSession->SetHeaderCallback({}); CprSession->SetWriteCallback({}); return Result; } inline cpr::Response Head() { ZEN_TRACE_CPU("HttpClient::Impl::Head"); cpr::Response Result = CprSession->Head(); ZEN_TRACE("HEAD {}", Result); return Result; } inline cpr::Response Put(std::optional&& Read = {}) { ZEN_TRACE_CPU("HttpClient::Impl::Put"); if (Read) { CprSession->SetReadCallback(std::move(Read.value())); } cpr::Response Result = CprSession->Put(); ZEN_TRACE("PUT {}", Result); CprSession->SetReadCallback({}); return Result; } inline cpr::Response Post(std::optional&& Read = {}) { ZEN_TRACE_CPU("HttpClient::Impl::Post"); if (Read) { CprSession->SetReadCallback(std::move(Read.value())); } cpr::Response Result = CprSession->Post(); ZEN_TRACE("POST {}", Result); CprSession->SetReadCallback({}); return Result; } inline cpr::Response Delete() { ZEN_TRACE_CPU("HttpClient::Impl::Delete"); cpr::Response Result = CprSession->Delete(); ZEN_TRACE("DELETE {}", Result); return Result; } LoggerRef Log() { return Outer->Log(); } private: CprHttpClient* Outer; cpr::Session* CprSession; Session(Session&&) = delete; Session& operator=(Session&&) = delete; }; Session AllocSession(const std::string_view BaseUrl, const std::string_view Url, const HttpClientSettings& ConnectionSettings, const KeyValueMap& AdditionalHeader, const KeyValueMap& Parameters, const std::string_view SessionId, std::optional AccessToken); RwLock m_SessionLock; std::vector m_Sessions; void ReleaseSession(cpr::Session*); cpr::Response DoWithRetry(std::string_view SessionId, std::function&& Func, std::unique_ptr& PayloadFile); cpr::Response DoWithRetry( std::string_view SessionId, std::function&& Func, std::function&& Validate = [](cpr::Response&) { return true; }); bool ValidatePayload(cpr::Response& Response, std::unique_ptr& PayloadFile); HttpClient::Response CommonResponse(std::string_view SessionId, cpr::Response&& HttpResponse, IoBuffer&& Payload, std::vector&& BoundaryPositions = {}); HttpClient::Response ResponseWithPayload(std::string_view SessionId, cpr::Response&& HttpResponse, const HttpResponseCode WorkResponseCode, IoBuffer&& Payload, std::vector&& BoundaryPositions); }; } // namespace zen