1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "httpclientcommon.h"
#include <zencore/logging.h>
#include <zenhttp/cprutils.h>
#include <zenhttp/httpclient.h>
ZEN_THIRD_PARTY_INCLUDES_START
#include <cpr/body.h>
#include <cpr/session.h>
ZEN_THIRD_PARTY_INCLUDES_END
namespace zen {
class CprHttpClient : public HttpClientBase
{
public:
CprHttpClient(std::string_view BaseUri, const HttpClientSettings& Connectionsettings, std::function<bool()>&& 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<cpr::HeaderCallback>&& 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<cpr::ReadCallback>&& 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<cpr::ReadCallback>&& 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<HttpClientAccessToken> AccessToken);
RwLock m_SessionLock;
std::vector<cpr::Session*> m_Sessions;
void ReleaseSession(cpr::Session*);
cpr::Response DoWithRetry(std::string_view SessionId,
std::function<cpr::Response()>&& Func,
std::unique_ptr<detail::TempPayloadFile>& PayloadFile);
cpr::Response DoWithRetry(
std::string_view SessionId,
std::function<cpr::Response()>&& Func,
std::function<bool(cpr::Response& Result)>&& Validate = [](cpr::Response&) { return true; });
bool ValidatePayload(cpr::Response& Response, std::unique_ptr<detail::TempPayloadFile>& PayloadFile);
HttpClient::Response CommonResponse(std::string_view SessionId,
cpr::Response&& HttpResponse,
IoBuffer&& Payload,
std::vector<HttpClient::Response::MultipartBoundary>&& BoundaryPositions = {});
HttpClient::Response ResponseWithPayload(std::string_view SessionId,
cpr::Response&& HttpResponse,
const HttpResponseCode WorkResponseCode,
IoBuffer&& Payload,
std::vector<HttpClient::Response::MultipartBoundary>&& BoundaryPositions);
};
} // namespace zen
|