aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/zen/cmds/rpcreplay_cmd.cpp72
-rw-r--r--src/zen/zen.cpp90
-rw-r--r--src/zencore/include/zencore/string.h3
-rw-r--r--src/zencore/string.cpp55
-rw-r--r--src/zenhttp/auth/oidc.cpp40
-rw-r--r--src/zenhttp/httpclient.cpp70
-rw-r--r--src/zenhttp/httpclientauth.cpp18
-rw-r--r--src/zenhttp/include/zenhttp/cprutils.h86
-rw-r--r--src/zenhttp/include/zenhttp/formatters.h71
-rw-r--r--src/zenhttp/include/zenhttp/httpclient.h28
-rw-r--r--src/zenserver-test/projectclient.cpp160
-rw-r--r--src/zenserver-test/projectclient.h32
-rw-r--r--src/zenserver-test/zenserver-test.cpp944
-rw-r--r--src/zenserver/cache/httpstructuredcache.cpp14
-rw-r--r--src/zenserver/projectstore/buildsremoteprojectstore.cpp14
-rw-r--r--src/zenserver/projectstore/projectstore.cpp5
-rw-r--r--src/zenserver/upstream/zen.cpp226
-rw-r--r--src/zenserver/upstream/zen.h18
-rw-r--r--src/zenutil/zenserverprocess.cpp2
19 files changed, 854 insertions, 1094 deletions
diff --git a/src/zen/cmds/rpcreplay_cmd.cpp b/src/zen/cmds/rpcreplay_cmd.cpp
index fd6c80e98..0cf5e5b6d 100644
--- a/src/zen/cmds/rpcreplay_cmd.cpp
+++ b/src/zen/cmds/rpcreplay_cmd.cpp
@@ -12,13 +12,13 @@
#include <zencore/stream.h>
#include <zencore/timer.h>
#include <zencore/workthreadpool.h>
+#include <zenhttp/formatters.h>
#include <zenhttp/httpclient.h>
#include <zenhttp/httpcommon.h>
#include <zenhttp/packageformat.h>
#include <zenutil/cache/rpcrecording.h>
ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/cpr.h>
#include <fmt/format.h>
#include <gsl/gsl-lite.hpp>
ZEN_THIRD_PARTY_INCLUDES_END
@@ -27,54 +27,6 @@ ZEN_THIRD_PARTY_INCLUDES_END
namespace zen {
-namespace {
- // TODO: Convert direct use of cpr to HttpClient
-
- std::string FormatHttpResponse(const cpr::Response& Response)
- {
- if (Response.error.code != cpr::ErrorCode::OK)
- {
- if (Response.error.message.empty())
- {
- return fmt::format("Request '{}' failed, error code {}", Response.url.str(), static_cast<int>(Response.error.code));
- }
- return fmt::format("Request '{}' failed. Reason: '{}' ({})",
- Response.url.str(),
- Response.error.message,
- static_cast<int>(Response.error.code));
- }
-
- std::string Content;
- if (auto It = Response.header.find("Content-Type"); It != Response.header.end())
- {
- zen::HttpContentType ContentType = zen::ParseContentType(It->second);
- if (ContentType == zen::HttpContentType::kText)
- {
- Content = Response.text;
- }
- else if (ContentType == zen::HttpContentType::kJSON)
- {
- Content = fmt::format("\n{}", Response.text);
- }
- else if (!Response.text.empty())
- {
- Content = fmt::format("[{}]", MapContentTypeToString(ContentType));
- }
- }
-
- std::string_view ResponseString = zen::ReasonStringForHttpResultCode(
- Response.status_code == static_cast<long>(zen::HttpResponseCode::NoContent) ? static_cast<long>(zen::HttpResponseCode::OK)
- : Response.status_code);
- if (Content.empty())
- {
- return std::string(ResponseString);
- }
-
- return fmt::format("{}: {}", ResponseString, Content);
- }
-
-} // namespace
-
using namespace std::literals;
RpcStartRecordingCommand::RpcStartRecordingCommand()
@@ -341,8 +293,7 @@ RpcReplayCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
}
});
- cpr::Session Session;
- Session.SetUrl(fmt::format("{}/z$/$rpc"sv, m_HostName));
+ HttpClient Http{m_HostName};
uint64_t EntryIndex = EntryOffset.fetch_add(m_Stride);
while (EntryIndex < EntryCount)
@@ -473,9 +424,10 @@ RpcReplayCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
GetSessionId().ToString(SessionIdString);
}
- Session.SetHeader({{"Content-Type", std::string(MapContentTypeToString(RequestInfo.ContentType))},
- {"Accept", std::string(MapContentTypeToString(RequestInfo.AcceptType))},
- {"UE-Session", std::string(SessionIdString)}});
+ HttpClient::KeyValueMap HttpHeaders{
+ {"Content-Type", std::string(MapContentTypeToString(RequestInfo.ContentType))},
+ {"Accept", std::string(MapContentTypeToString(RequestInfo.AcceptType))},
+ {"UE-Session", std::string(SessionIdString)}};
uint64_t Offset = 0;
auto ReadCallback = [&Payload, &Offset](char* buffer, size_t& size, intptr_t) {
@@ -486,16 +438,16 @@ RpcReplayCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
Offset += size;
return true;
};
- Session.SetReadCallback(cpr::ReadCallback(gsl::narrow<cpr::cpr_off_t>(Payload.GetSize()), ReadCallback));
- cpr::Response Response = Session.Post();
+
+ HttpClient::Response Response = Http.Post("/z$/$rpc", Payload, HttpHeaders);
+
BytesSent.fetch_add(Payload.GetSize());
- if (Response.error || !(IsHttpSuccessCode(Response.status_code) ||
- Response.status_code == gsl::narrow<long>(HttpResponseCode::NotFound)))
+ if (!Response)
{
- ZEN_CONSOLE_ERROR("{}", FormatHttpResponse(Response));
+ ZEN_CONSOLE_ERROR("{}", Response);
break;
}
- BytesReceived.fetch_add(Response.downloaded_bytes);
+ BytesReceived.fetch_add(Response.DownloadedBytes);
}
}
diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp
index 0381dd15c..1d2faba7e 100644
--- a/src/zen/zen.cpp
+++ b/src/zen/zen.cpp
@@ -55,7 +55,6 @@
#endif
ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/cpr.h>
#include <spdlog/sinks/ansicolor_sink.h>
#include <spdlog/spdlog.h>
#include <gsl/gsl-lite.hpp>
@@ -275,66 +274,37 @@ ZenCmdBase::GetSubCommand(cxxopts::Options&,
}
static ReturnCode
-GetReturnCodeFromHttpResult(int Error, HttpResponseCode ResponseCode)
+GetReturnCodeFromHttpResult(const HttpClientError& Ex)
{
- if ((cpr::ErrorCode)Error != cpr::ErrorCode::OK)
- {
- switch ((cpr::ErrorCode)Error)
- {
- case cpr::ErrorCode::CONNECTION_FAILURE:
- return ReturnCode::kHttpCantConnectError;
- case cpr::ErrorCode::HOST_RESOLUTION_FAILURE:
- case cpr::ErrorCode::PROXY_RESOLUTION_FAILURE:
- return ReturnCode::kHttpNoHost;
- case cpr::ErrorCode::INTERNAL_ERROR:
- case cpr::ErrorCode::NETWORK_RECEIVE_ERROR:
- case cpr::ErrorCode::NETWORK_SEND_FAILURE:
- case cpr::ErrorCode::OPERATION_TIMEDOUT:
- return ReturnCode::kHttpTimeout;
- case cpr::ErrorCode::SSL_CONNECT_ERROR:
- case cpr::ErrorCode::SSL_LOCAL_CERTIFICATE_ERROR:
- case cpr::ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR:
- case cpr::ErrorCode::SSL_CACERT_ERROR:
- case cpr::ErrorCode::GENERIC_SSL_ERROR:
- return ReturnCode::kHttpSLLError;
- default:
- return ReturnCode::kHttpOtherClientError;
- }
- }
- else if (IsHttpSuccessCode(ResponseCode))
- {
+ HttpClientError::ResponseClass ResponseClass = Ex.GetResponseClass();
+
+ if (ResponseClass == HttpClientError::ResponseClass::kSuccess)
return ReturnCode::kSuccess;
- }
- else
+
+ switch (ResponseClass)
{
- switch (ResponseCode)
- {
- case HttpResponseCode::Unauthorized:
- return ReturnCode::kHttpUnauthorized;
- case HttpResponseCode::NotFound:
- return ReturnCode::kHttpNotFound;
- case HttpResponseCode::Forbidden:
- return ReturnCode::kHttpForbidden;
- case HttpResponseCode::Conflict:
- return ReturnCode::kHttpConflict;
- case HttpResponseCode::InternalServerError:
- return ReturnCode::kHttpInternalServerError;
- case HttpResponseCode::ServiceUnavailable:
- return ReturnCode::kHttpServiceUnavailable;
- case HttpResponseCode::BadGateway:
- return ReturnCode::kHttpBadGateway;
- case HttpResponseCode::GatewayTimeout:
- return ReturnCode::kHttpGatewayTimeout;
- default:
- if (ResponseCode >= HttpResponseCode::InternalServerError)
- {
- return ReturnCode::kHttpOtherServerError;
- }
- else
- {
- return ReturnCode::kHttpOtherClientError;
- }
- }
+#define HANDLE_CASE(ErrorClass) \
+ case HttpClientError::ResponseClass::ErrorClass: \
+ return ReturnCode::ErrorClass
+
+ HANDLE_CASE(kHttpOtherClientError);
+ HANDLE_CASE(kHttpCantConnectError);
+ HANDLE_CASE(kHttpNotFound);
+ HANDLE_CASE(kHttpUnauthorized);
+ HANDLE_CASE(kHttpSLLError);
+ HANDLE_CASE(kHttpForbidden);
+ HANDLE_CASE(kHttpTimeout);
+ HANDLE_CASE(kHttpConflict);
+ HANDLE_CASE(kHttpNoHost);
+ HANDLE_CASE(kHttpOtherServerError);
+ HANDLE_CASE(kHttpInternalServerError);
+ HANDLE_CASE(kHttpServiceUnavailable);
+ HANDLE_CASE(kHttpBadGateway);
+ HANDLE_CASE(kHttpGatewayTimeout);
+#undef HANDLE_CASE
+
+ default:
+ return ReturnCode::kOtherError;
}
}
@@ -1093,7 +1063,7 @@ main(int argc, char** argv)
catch (const HttpClientError& Ex)
{
ZEN_CONSOLE_ERROR("Operation failed due to a http error: {}", Ex.what());
- ReturnCode Result = GetReturnCodeFromHttpResult(Ex.m_Error, Ex.m_ResponseCode);
+ ReturnCode Result = GetReturnCodeFromHttpResult(Ex);
return (int)Result;
}
catch (const AssertException& Ex)
@@ -1144,7 +1114,7 @@ main(int argc, char** argv)
catch (const HttpClientError& Ex)
{
printf("Error: Operation failed due to a http error: %s", Ex.what());
- ReturnCode Result = GetReturnCodeFromHttpResult(Ex.m_Error, Ex.m_ResponseCode);
+ ReturnCode Result = GetReturnCodeFromHttpResult(Ex);
return (int)Result;
}
catch (const AssertException& Ex)
diff --git a/src/zencore/include/zencore/string.h b/src/zencore/include/zencore/string.h
index 68129b691..93f8add0a 100644
--- a/src/zencore/include/zencore/string.h
+++ b/src/zencore/include/zencore/string.h
@@ -679,6 +679,9 @@ ParseHexNumber(const std::string_view HexString, UnsignedIntegral auto& OutValue
return ParseHexNumber(HexString.data(), ExpectedCharacterCount, (uint8_t*)&OutValue);
}
+void UrlDecode(std::string_view InUrl, StringBuilderBase& OutUrl);
+std::string UrlDecode(std::string_view InUrl);
+
//////////////////////////////////////////////////////////////////////////
// Format numbers for humans
//
diff --git a/src/zencore/string.cpp b/src/zencore/string.cpp
index a0d8c927f..c8c7c2cde 100644
--- a/src/zencore/string.cpp
+++ b/src/zencore/string.cpp
@@ -483,12 +483,67 @@ template class StringBuilderImpl<char>;
template class StringBuilderImpl<wchar_t>;
//////////////////////////////////////////////////////////////////////////
+
+void
+UrlDecode(std::string_view InUrl, StringBuilderBase& OutUrl)
+{
+ std::string_view::size_type i = 0;
+
+ for (; i != InUrl.size();)
+ {
+ char c = InUrl[i];
+
+ if ((c == '%') && ((i + 2) < InUrl.size()))
+ {
+ char hex[2] = {InUrl[i + 1], InUrl[i + 2]};
+ uint8_t HexedChar;
+ if (ParseHexBytes(hex, 2, &HexedChar))
+ {
+ OutUrl.Append(HexedChar);
+ i += 3;
+
+ continue;
+ }
+ }
+
+ OutUrl.Append(c);
+ ++i;
+ }
+}
+
+std::string
+UrlDecode(std::string_view InUrl)
+{
+ ExtendableStringBuilder<128> Url;
+ UrlDecode(InUrl, Url);
+
+ return std::string(Url.ToView());
+}
+
+//////////////////////////////////////////////////////////////////////////
//
// Unit tests
//
#if ZEN_WITH_TESTS
+TEST_CASE("url")
+{
+ using namespace std::literals;
+
+ ExtendableStringBuilder<32> OutUrl;
+ UrlDecode("http://blah.com/foo?bar=hi%20ho", OutUrl);
+ CHECK_EQ(OutUrl.ToView(), "http://blah.com/foo?bar=hi ho"sv);
+
+ OutUrl.Reset();
+
+ UrlDecode("http://blah.com/foo?bar=hi%ho", OutUrl);
+ CHECK_EQ(OutUrl.ToView(), "http://blah.com/foo?bar=hi%ho"sv);
+
+ CHECK_EQ(UrlDecode("http://blah.com/foo?bar=hi%20ho"), "http://blah.com/foo?bar=hi ho"sv);
+ CHECK_EQ(UrlDecode("http://blah.com/foo?bar=hi%ho"), "http://blah.com/foo?bar=hi%ho"sv);
+}
+
TEST_CASE("niceNum")
{
char Buffer[16];
diff --git a/src/zenhttp/auth/oidc.cpp b/src/zenhttp/auth/oidc.cpp
index 318110c7d..38e7586ad 100644
--- a/src/zenhttp/auth/oidc.cpp
+++ b/src/zenhttp/auth/oidc.cpp
@@ -1,9 +1,9 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "zenhttp/auth/oidc.h"
+#include <zenhttp/httpclient.h>
ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/cpr.h>
#include <fmt/format.h>
#include <json11.hpp>
ZEN_THIRD_PARTY_INCLUDES_END
@@ -41,27 +41,21 @@ OidcClient::OidcClient(const OidcClient::Options& Options)
OidcClient::InitResult
OidcClient::Initialize()
{
- ExtendableStringBuilder<256> Uri;
- Uri << m_BaseUrl << "/.well-known/openid-configuration"sv;
+ HttpClient Http{m_BaseUrl};
+ HttpClient::Response Response = Http.Get("/.well-known/openid-configuration"sv);
- cpr::Session Session;
-
- Session.SetOption(cpr::Url{Uri.c_str()});
-
- cpr::Response Response = Session.Get();
-
- if (Response.error)
+ if (!Response)
{
- return {.Reason = std::move(Response.error.message)};
+ return {.Reason = Response.ErrorMessage("")};
}
- if (Response.status_code != 200)
+ if (Response.StatusCode != HttpResponseCode::OK)
{
- return {.Reason = std::move(Response.reason)};
+ return {.Reason = std::string{ToString(Response.StatusCode)}};
}
std::string JsonError;
- json11::Json Json = json11::Json::parse(Response.text, JsonError);
+ json11::Json Json = json11::Json::parse(std::string{Response.AsText()}, JsonError);
if (JsonError.empty() == false)
{
@@ -89,26 +83,24 @@ OidcClient::RefreshToken(std::string_view RefreshToken)
{
const std::string Body = fmt::format("grant_type=refresh_token&refresh_token={}&client_id={}", RefreshToken, m_ClientId);
- cpr::Session Session;
+ HttpClient Http{m_Config.TokenEndpoint};
- Session.SetOption(cpr::Url{m_Config.TokenEndpoint.c_str()});
- Session.SetOption(cpr::Header{{"Content-Type", "application/x-www-form-urlencoded"}});
- Session.SetBody(cpr::Body{Body.data(), Body.size()});
+ HttpClient::KeyValueMap Headers{{"Content-Type", "application/x-www-form-urlencoded"}};
- cpr::Response Response = Session.Post();
+ HttpClient::Response Response = Http.Post("", IoBufferBuilder::MakeFromMemory(MemoryView{Body.data(), Body.size()}), Headers);
- if (Response.error)
+ if (!Response)
{
- return {.Reason = std::move(Response.error.message)};
+ return {.Reason = std::string{Response.ErrorMessage("")}};
}
- if (Response.status_code != 200)
+ if (Response.StatusCode != HttpResponseCode::OK)
{
- return {.Reason = fmt::format("{} ({})", Response.reason, Response.text)};
+ return {.Reason = fmt::format("{} ({})", ToString(Response.StatusCode), Response.AsText())};
}
std::string JsonError;
- json11::Json Json = json11::Json::parse(Response.text, JsonError);
+ json11::Json Json = json11::Json::parse(std::string{Response.AsText()}, JsonError);
if (JsonError.empty() == false)
{
diff --git a/src/zenhttp/httpclient.cpp b/src/zenhttp/httpclient.cpp
index 9ee8cc05a..5981d449a 100644
--- a/src/zenhttp/httpclient.cpp
+++ b/src/zenhttp/httpclient.cpp
@@ -1,5 +1,6 @@
// Copyright Epic Games, Inc. All Rights Reserved.
+#include <zenhttp/cprutils.h>
#include <zenhttp/formatters.h>
#include <zenhttp/httpclient.h>
#include <zenhttp/httpserver.h>
@@ -27,7 +28,8 @@
#endif // ZEN_WITH_TESTS
ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/cpr.h>
+#include <cpr/body.h>
+#include <cpr/session.h>
ZEN_THIRD_PARTY_INCLUDES_END
#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
@@ -1660,6 +1662,72 @@ HttpClient::Response::ThrowError(std::string_view ErrorPrefix)
//////////////////////////////////////////////////////////////////////////
+HttpClientError::ResponseClass
+HttpClientError::GetResponseClass() const
+{
+ if ((cpr::ErrorCode)m_Error != cpr::ErrorCode::OK)
+ {
+ switch ((cpr::ErrorCode)m_Error)
+ {
+ case cpr::ErrorCode::CONNECTION_FAILURE:
+ return ResponseClass::kHttpCantConnectError;
+ case cpr::ErrorCode::HOST_RESOLUTION_FAILURE:
+ case cpr::ErrorCode::PROXY_RESOLUTION_FAILURE:
+ return ResponseClass::kHttpNoHost;
+ case cpr::ErrorCode::INTERNAL_ERROR:
+ case cpr::ErrorCode::NETWORK_RECEIVE_ERROR:
+ case cpr::ErrorCode::NETWORK_SEND_FAILURE:
+ case cpr::ErrorCode::OPERATION_TIMEDOUT:
+ return ResponseClass::kHttpTimeout;
+ case cpr::ErrorCode::SSL_CONNECT_ERROR:
+ case cpr::ErrorCode::SSL_LOCAL_CERTIFICATE_ERROR:
+ case cpr::ErrorCode::SSL_REMOTE_CERTIFICATE_ERROR:
+ case cpr::ErrorCode::SSL_CACERT_ERROR:
+ case cpr::ErrorCode::GENERIC_SSL_ERROR:
+ return ResponseClass::kHttpSLLError;
+ default:
+ return ResponseClass::kHttpOtherClientError;
+ }
+ }
+ else if (IsHttpSuccessCode(m_ResponseCode))
+ {
+ return ResponseClass::kSuccess;
+ }
+ else
+ {
+ switch (m_ResponseCode)
+ {
+ case HttpResponseCode::Unauthorized:
+ return ResponseClass::kHttpUnauthorized;
+ case HttpResponseCode::NotFound:
+ return ResponseClass::kHttpNotFound;
+ case HttpResponseCode::Forbidden:
+ return ResponseClass::kHttpForbidden;
+ case HttpResponseCode::Conflict:
+ return ResponseClass::kHttpConflict;
+ case HttpResponseCode::InternalServerError:
+ return ResponseClass::kHttpInternalServerError;
+ case HttpResponseCode::ServiceUnavailable:
+ return ResponseClass::kHttpServiceUnavailable;
+ case HttpResponseCode::BadGateway:
+ return ResponseClass::kHttpBadGateway;
+ case HttpResponseCode::GatewayTimeout:
+ return ResponseClass::kHttpGatewayTimeout;
+ default:
+ if (m_ResponseCode >= HttpResponseCode::InternalServerError)
+ {
+ return ResponseClass::kHttpOtherServerError;
+ }
+ else
+ {
+ return ResponseClass::kHttpOtherClientError;
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+
#if ZEN_WITH_TESTS
namespace testutil {
diff --git a/src/zenhttp/httpclientauth.cpp b/src/zenhttp/httpclientauth.cpp
index 4bbc6405b..4438fc137 100644
--- a/src/zenhttp/httpclientauth.cpp
+++ b/src/zenhttp/httpclientauth.cpp
@@ -9,11 +9,11 @@
#include <zencore/timer.h>
#include <zencore/uid.h>
#include <zenhttp/auth/authmgr.h>
+#include <zenhttp/httpclient.h>
#include <ctime>
ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/cpr.h>
#include <fmt/format.h>
#include <json11.hpp>
ZEN_THIRD_PARTY_INCLUDES_END
@@ -47,18 +47,22 @@ namespace zen { namespace httpclientauth {
OAuthParams.ClientId,
OAuthParams.ClientSecret);
- cpr::Response Response = cpr::Post(cpr::Url{OAuthParams.Url},
- cpr::Header{{"Content-Type", "application/x-www-form-urlencoded"}},
- cpr::Body{std::move(Body)});
+ HttpClient Http{OAuthParams.Url};
- if (Response.error || Response.status_code != 200)
+ IoBuffer Payload{IoBuffer::Wrap, Body.data(), Body.size()};
+
+ // TODO: ensure this gets the right Content-Type passed along
+
+ HttpClient::Response Response = Http.Post("", Payload, {{"Content-Type", "application/x-www-form-urlencoded"}});
+
+ if (!Response || Response.StatusCode != HttpResponseCode::OK)
{
- ZEN_WARN("Failed fetching OAuth access token {}. Reason: '{}'", OAuthParams.Url, Response.reason);
+ ZEN_WARN("Failed fetching OAuth access token {}. Reason: '{}'", OAuthParams.Url, Response.ErrorMessage(""));
return HttpClientAccessToken{};
}
std::string JsonError;
- json11::Json Json = json11::Json::parse(Response.text, JsonError);
+ json11::Json Json = json11::Json::parse(std::string{Response.AsText()}, JsonError);
if (JsonError.empty() == false)
{
diff --git a/src/zenhttp/include/zenhttp/cprutils.h b/src/zenhttp/include/zenhttp/cprutils.h
new file mode 100644
index 000000000..a3b870c0f
--- /dev/null
+++ b/src/zenhttp/include/zenhttp/cprutils.h
@@ -0,0 +1,86 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#pragma once
+
+#include <zencore/compactbinary.h>
+#include <zencore/compactbinaryvalidation.h>
+#include <zencore/iobuffer.h>
+#include <zencore/string.h>
+#include <zenhttp/formatters.h>
+#include <zenhttp/httpclient.h>
+#include <zenhttp/httpcommon.h>
+
+ZEN_THIRD_PARTY_INCLUDES_START
+#include <cpr/response.h>
+#include <fmt/format.h>
+ZEN_THIRD_PARTY_INCLUDES_END
+
+template<>
+struct fmt::formatter<cpr::Response>
+{
+ constexpr auto parse(format_parse_context& Ctx) -> decltype(Ctx.begin()) { return Ctx.end(); }
+
+ template<typename FormatContext>
+ auto format(const cpr::Response& Response, FormatContext& Ctx) const -> decltype(Ctx.out())
+ {
+ using namespace std::literals;
+
+ zen::NiceTimeSpanMs NiceResponseTime(uint64_t(Response.elapsed * 1000));
+
+ if (zen::IsHttpSuccessCode(Response.status_code))
+ {
+ return fmt::format_to(Ctx.out(),
+ "Url: {}, Status: {}, Error: '{}' ({}), Bytes: {}/{} (Up/Down), Elapsed: {}",
+ Response.url.str(),
+ Response.status_code,
+ Response.error.message,
+ int(Response.error.code),
+ Response.uploaded_bytes,
+ Response.downloaded_bytes,
+ NiceResponseTime.c_str());
+ }
+ else
+ {
+ const auto It = Response.header.find("Content-Type");
+ const std::string_view ContentType = It != Response.header.end() ? It->second : "<None>"sv;
+
+ if (ContentType == "application/x-ue-cb"sv)
+ {
+ zen::IoBuffer Body(zen::IoBuffer::Wrap, Response.text.data(), Response.text.size());
+ zen::CbObjectView Obj(Body.Data());
+ zen::ExtendableStringBuilder<256> Sb;
+ std::string_view Json = Obj.ToJson(Sb).ToView();
+
+ return fmt::format_to(
+ Ctx.out(),
+ "Url: {}, Status: {}, Error: '{}' ({}). Bytes: {}/{} (Up/Down), Elapsed: {}, Response: '{}', Reason: '{}'",
+ Response.url.str(),
+ Response.status_code,
+ Response.error.message,
+ int(Response.error.code),
+ Response.uploaded_bytes,
+ Response.downloaded_bytes,
+ NiceResponseTime.c_str(),
+ Json,
+ Response.reason);
+ }
+ else
+ {
+ zen::BodyLogFormatter Body(Response.text);
+
+ return fmt::format_to(
+ Ctx.out(),
+ "Url: {}, Status: {}, Error: '{}' ({}), Bytes: {}/{} (Up/Down), Elapsed: {}, Response: '{}', Reason: '{}'",
+ Response.url.str(),
+ Response.status_code,
+ Response.error.message,
+ int(Response.error.code),
+ Response.uploaded_bytes,
+ Response.downloaded_bytes,
+ NiceResponseTime.c_str(),
+ Body.GetText(),
+ Response.reason);
+ }
+ }
+ }
+};
diff --git a/src/zenhttp/include/zenhttp/formatters.h b/src/zenhttp/include/zenhttp/formatters.h
index 05a23d675..0af31fa30 100644
--- a/src/zenhttp/include/zenhttp/formatters.h
+++ b/src/zenhttp/include/zenhttp/formatters.h
@@ -10,7 +10,6 @@
#include <zenhttp/httpcommon.h>
ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/cpr.h>
#include <fmt/format.h>
ZEN_THIRD_PARTY_INCLUDES_END
@@ -59,76 +58,6 @@ public:
} // namespace zen
template<>
-struct fmt::formatter<cpr::Response>
-{
- constexpr auto parse(format_parse_context& Ctx) -> decltype(Ctx.begin()) { return Ctx.end(); }
-
- template<typename FormatContext>
- auto format(const cpr::Response& Response, FormatContext& Ctx) const -> decltype(Ctx.out())
- {
- using namespace std::literals;
-
- zen::NiceTimeSpanMs NiceResponseTime(uint64_t(Response.elapsed * 1000));
-
- if (zen::IsHttpSuccessCode(Response.status_code))
- {
- return fmt::format_to(Ctx.out(),
- "Url: {}, Status: {}, Error: '{}' ({}), Bytes: {}/{} (Up/Down), Elapsed: {}",
- Response.url.str(),
- Response.status_code,
- Response.error.message,
- int(Response.error.code),
- Response.uploaded_bytes,
- Response.downloaded_bytes,
- NiceResponseTime.c_str());
- }
- else
- {
- const auto It = Response.header.find("Content-Type");
- const std::string_view ContentType = It != Response.header.end() ? It->second : "<None>"sv;
-
- if (ContentType == "application/x-ue-cb"sv)
- {
- zen::IoBuffer Body(zen::IoBuffer::Wrap, Response.text.data(), Response.text.size());
- zen::CbObjectView Obj(Body.Data());
- zen::ExtendableStringBuilder<256> Sb;
- std::string_view Json = Obj.ToJson(Sb).ToView();
-
- return fmt::format_to(
- Ctx.out(),
- "Url: {}, Status: {}, Error: '{}' ({}). Bytes: {}/{} (Up/Down), Elapsed: {}, Response: '{}', Reason: '{}'",
- Response.url.str(),
- Response.status_code,
- Response.error.message,
- int(Response.error.code),
- Response.uploaded_bytes,
- Response.downloaded_bytes,
- NiceResponseTime.c_str(),
- Json,
- Response.reason);
- }
- else
- {
- zen::BodyLogFormatter Body(Response.text);
-
- return fmt::format_to(
- Ctx.out(),
- "Url: {}, Status: {}, Error: '{}' ({}), Bytes: {}/{} (Up/Down), Elapsed: {}, Response: '{}', Reason: '{}'",
- Response.url.str(),
- Response.status_code,
- Response.error.message,
- int(Response.error.code),
- Response.uploaded_bytes,
- Response.downloaded_bytes,
- NiceResponseTime.c_str(),
- Body.GetText(),
- Response.reason);
- }
- }
- }
-};
-
-template<>
struct fmt::formatter<zen::HttpClient::Response>
{
constexpr auto parse(format_parse_context& Ctx) -> decltype(Ctx.begin()) { return Ctx.end(); }
diff --git a/src/zenhttp/include/zenhttp/httpclient.h b/src/zenhttp/include/zenhttp/httpclient.h
index 50bd5b53a..ec06aa229 100644
--- a/src/zenhttp/include/zenhttp/httpclient.h
+++ b/src/zenhttp/include/zenhttp/httpclient.h
@@ -76,6 +76,34 @@ public:
{
}
+ inline int GetInternalErrorCode() const { return m_Error; }
+ inline HttpResponseCode GetHttpResponseCode() const { return m_ResponseCode; }
+
+ enum class ResponseClass : std::int8_t
+ {
+ kSuccess = 0,
+
+ kHttpOtherClientError = 80,
+ kHttpCantConnectError = 81, // CONNECTION_FAILURE
+ kHttpNotFound = 66, // NotFound(404)
+ kHttpUnauthorized = 77, // Unauthorized(401),
+ kHttpSLLError =
+ 82, // SSL_CONNECT_ERROR, SSL_LOCAL_CERTIFICATE_ERROR, SSL_REMOTE_CERTIFICATE_ERROR, SSL_CACERT_ERROR, GENERIC_SSL_ERROR
+ kHttpForbidden = 83, // Forbidden(403)
+ kHttpTimeout = 84, // NETWORK_RECEIVE_ERROR, NETWORK_SEND_FAILURE, OPERATION_TIMEDOUT, RequestTimeout(408)
+ kHttpConflict = 85, // Conflict(409)
+ kHttpNoHost = 86, // HOST_RESOLUTION_FAILURE, PROXY_RESOLUTION_FAILURE
+
+ kHttpOtherServerError = 90,
+ kHttpInternalServerError = 91, // InternalServerError(500)
+ kHttpServiceUnavailable = 69, // ServiceUnavailable(503)
+ kHttpBadGateway = 92, // BadGateway(502)
+ kHttpGatewayTimeout = 93, // GatewayTimeout(504)
+ };
+
+ ResponseClass GetResponseClass() const;
+
+private:
const int m_Error = 0;
const HttpResponseCode m_ResponseCode = HttpResponseCode::ImATeapot;
};
diff --git a/src/zenserver-test/projectclient.cpp b/src/zenserver-test/projectclient.cpp
deleted file mode 100644
index cb493be77..000000000
--- a/src/zenserver-test/projectclient.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright Epic Games, Inc. All Rights Reserved.
-
-#include "projectclient.h"
-
-#if 0
-
-# include <zencore/compactbinary.h>
-# include <zencore/logging.h>
-# include <zencore/sharedbuffer.h>
-# include <zencore/string.h>
-# include <zencore/zencore.h>
-
-# include <asio.hpp>
-# include <gsl/gsl-lite.hpp>
-
-namespace zen {
-
-struct ProjectClientConnection
-{
- ProjectClientConnection(int BasePort) { Connect(BasePort); }
-
- void Connect(int BasePort)
- {
- ZEN_UNUSED(BasePort);
-
- WideStringBuilder<64> PipeName;
- PipeName << "\\\\.\\pipe\\zenprj"; // TODO: this should use an instance-specific identifier!
-
- HANDLE hPipe = CreateFileW(PipeName.c_str(),
- GENERIC_READ | GENERIC_WRITE,
- 0, // Sharing doesn't make any sense
- nullptr, // No security attributes
- OPEN_EXISTING, // Open existing pipe
- 0, // Attributes
- nullptr // Template file
- );
-
- if (hPipe == INVALID_HANDLE_VALUE)
- {
- ZEN_WARN("failed while creating named pipe {}", WideToUtf8(PipeName));
-
- throw std::system_error(GetLastError(), std::system_category(), fmt::format("Failed to open named pipe '{}'", WideToUtf8(PipeName)));
- }
-
- // Change to message mode
- DWORD dwMode = PIPE_READMODE_MESSAGE;
- BOOL Success = SetNamedPipeHandleState(hPipe, &dwMode, nullptr, nullptr);
-
- if (!Success)
- {
- throw std::system_error(GetLastError(),
- std::system_category(),
- fmt::format("Failed to change named pipe '{}' to message mode", WideToUtf8(PipeName)));
- }
-
- m_hPipe.Attach(hPipe); // This now owns the handle and will close it
- }
-
- ~ProjectClientConnection() {}
-
- CbObject MessageTransaction(CbObject Request)
- {
- DWORD dwWrittenBytes = 0;
-
- MemoryView View = Request.GetView();
-
- BOOL Success = ::WriteFile(m_hPipe, View.GetData(), gsl::narrow_cast<DWORD>(View.GetSize()), &dwWrittenBytes, nullptr);
-
- if (!Success)
- {
- throw std::system_error(GetLastError(), std::system_category(), "Failed to write pipe message");
- }
-
- ZEN_ASSERT(dwWrittenBytes == View.GetSize());
-
- DWORD dwReadBytes = 0;
-
- Success = ReadFile(m_hPipe, m_Buffer, sizeof m_Buffer, &dwReadBytes, nullptr);
-
- if (!Success)
- {
- DWORD ErrorCode = GetLastError();
-
- if (ERROR_MORE_DATA == ErrorCode)
- {
- // Response message is larger than our buffer - handle it by allocating a larger
- // buffer on the heap and read the remainder into that buffer
-
- DWORD dwBytesAvail = 0, dwLeftThisMessage = 0;
-
- Success = PeekNamedPipe(m_hPipe, nullptr, 0, nullptr, &dwBytesAvail, &dwLeftThisMessage);
-
- if (Success)
- {
- UniqueBuffer MessageBuffer = UniqueBuffer::Alloc(dwReadBytes + dwLeftThisMessage);
-
- memcpy(MessageBuffer.GetData(), m_Buffer, dwReadBytes);
-
- Success = ReadFile(m_hPipe,
- reinterpret_cast<uint8_t*>(MessageBuffer.GetData()) + dwReadBytes,
- dwLeftThisMessage,
- &dwReadBytes,
- nullptr);
-
- if (Success)
- {
- return CbObject(SharedBuffer(std::move(MessageBuffer)));
- }
- }
- }
-
- throw std::system_error(GetLastError(), std::system_category(), "Failed to read pipe message");
- }
-
- return CbObject(SharedBuffer::MakeView(MakeMemoryView(m_Buffer)));
- }
-
-private:
- static const int kEmbeddedBufferSize = 512 - 16;
-
- CHandle m_hPipe;
- uint8_t m_Buffer[kEmbeddedBufferSize];
-};
-
-struct LocalProjectClient::ClientImpl
-{
- ClientImpl(int BasePort) : m_BasePort(BasePort) {}
- ~ClientImpl() {}
-
- void Start() {}
- void Stop() {}
-
- inline int BasePort() const { return m_BasePort; }
-
-private:
- int m_BasePort = 0;
-};
-
-LocalProjectClient::LocalProjectClient(int BasePort)
-{
- m_Impl = std::make_unique<ClientImpl>(BasePort);
- m_Impl->Start();
-}
-
-LocalProjectClient::~LocalProjectClient()
-{
- m_Impl->Stop();
-}
-
-CbObject
-LocalProjectClient::MessageTransaction(CbObject Request)
-{
- ProjectClientConnection Cx(m_Impl->BasePort());
-
- return Cx.MessageTransaction(Request);
-}
-
-} // namespace zen
-
-#endif // 0
diff --git a/src/zenserver-test/projectclient.h b/src/zenserver-test/projectclient.h
deleted file mode 100644
index 8362ee0ee..000000000
--- a/src/zenserver-test/projectclient.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright Epic Games, Inc. All Rights Reserved.
-
-#pragma once
-
-#include <memory>
-
-#include <zenbase/refcount.h>
-#include <zencore/compactbinary.h>
-
-namespace zen {
-
-/**
- * Client for communication with local project service
- *
- * This is WIP and not yet functional!
- */
-
-class LocalProjectClient : public RefCounted
-{
-public:
- LocalProjectClient(int BasePort = 0);
- ~LocalProjectClient();
-
- CbObject MessageTransaction(CbObject Request);
-
-private:
- struct ClientImpl;
-
- std::unique_ptr<ClientImpl> m_Impl;
-};
-
-} // namespace zen
diff --git a/src/zenserver-test/zenserver-test.cpp b/src/zenserver-test/zenserver-test.cpp
index 923d35d13..827a4eb5a 100644
--- a/src/zenserver-test/zenserver-test.cpp
+++ b/src/zenserver-test/zenserver-test.cpp
@@ -38,7 +38,6 @@
#endif
ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/cpr.h>
#include <tsl/robin_set.h>
#undef GetObject
ZEN_THIRD_PARTY_INCLUDES_END
@@ -61,10 +60,6 @@ ZEN_THIRD_PARTY_INCLUDES_END
//////////////////////////////////////////////////////////////////////////
-#include "projectclient.h"
-
-//////////////////////////////////////////////////////////////////////////
-
#if ZEN_WITH_TESTS
# define ZEN_TEST_WITH_RUNNER 1
# include <zencore/testing.h>
@@ -180,12 +175,12 @@ TEST_CASE("default.single")
const int ThreadId = zen::GetCurrentThreadId();
ZEN_INFO("query batch {} started (thread {})", BatchNo, ThreadId);
- cpr::Session cli;
- cli.SetUrl(cpr::Url{fmt::format("http://localhost:{}/test/hello", PortNumber)});
+
+ HttpClient Http{fmt::format("http://localhost:{}", PortNumber)};
for (int i = 0; i < 10000; ++i)
{
- auto res = cli.Get();
+ auto res = Http.Get("/test/hello"sv);
++RequestCount;
}
ZEN_INFO("query batch {} ended (thread {})", BatchNo, ThreadId);
@@ -224,18 +219,20 @@ TEST_CASE("default.loopback")
SUBCASE("ipv4 endpoint connectivity")
{
- cpr::Session cli;
- cli.SetUrl(cpr::Url{fmt::format("http://127.0.0.1:{}/test/hello", PortNumber)});
- auto res = cli.Get();
- CHECK(!res.error);
+ HttpClient Http{fmt::format("http://127.0.0.1:{}", PortNumber)};
+
+ auto res = Http.Get("/test/hello"sv);
+
+ CHECK(res);
}
SUBCASE("ipv6 endpoint connectivity")
{
- cpr::Session cli;
- cli.SetUrl(cpr::Url{fmt::format("http://[::1]:{}/test/hello", PortNumber)});
- auto res = cli.Get();
- CHECK(!res.error);
+ HttpClient Http{fmt::format("http://[::1]:{}", PortNumber)};
+
+ auto res = Http.Get("/test/hello"sv);
+
+ CHECK(res);
}
}
@@ -267,14 +264,14 @@ TEST_CASE("multi.basic")
ZEN_INFO("query batch {} started (thread {}) for port {}", BatchNo, ThreadId, PortNumber);
- cpr::Session cli;
- cli.SetUrl(cpr::Url{fmt::format("http://localhost:{}/test/hello", PortNumber)});
+ HttpClient Http{fmt::format("http://localhost:{}", PortNumber)};
for (int i = 0; i < 10000; ++i)
{
- auto res = cli.Get();
+ auto res = Http.Get("/test/hello"sv);
++RequestCount;
}
+
ZEN_INFO("query batch {} ended (thread {})", BatchNo, ThreadId);
};
@@ -306,14 +303,10 @@ TEST_CASE("project.basic")
const uint16_t PortNumber = Instance1.SpawnServerAndWaitUntilReady();
- std::atomic<uint64_t> RequestCount{0};
-
- zen::Stopwatch timer;
-
std::mt19937_64 mt;
zen::StringBuilder<64> BaseUri;
- BaseUri << fmt::format("http://localhost:{}/prj/test", PortNumber);
+ BaseUri << fmt::format("http://localhost:{}", PortNumber);
std::filesystem::path BinPath = zen::GetRunningExecutablePath();
std::filesystem::path RootPath = BinPath.parent_path().parent_path();
@@ -322,6 +315,8 @@ TEST_CASE("project.basic")
SUBCASE("build store init")
{
{
+ HttpClient Http{BaseUri};
+
{
zen::CbObjectWriter Body;
Body << "id"
@@ -333,38 +328,38 @@ TEST_CASE("project.basic")
<< "/zooom";
zen::BinaryWriter MemOut;
- Body.Save(MemOut);
+ IoBuffer BodyBuf = Body.Save().GetBuffer().AsIoBuffer();
- auto Response = cpr::Post(cpr::Url{BaseUri.c_str()}, cpr::Body{(const char*)MemOut.Data(), MemOut.Size()});
- CHECK(Response.status_code == 201);
+ auto Response = Http.Post("/prj/test"sv, BodyBuf);
+ CHECK(Response.StatusCode == HttpResponseCode::Created);
}
{
- auto Response = cpr::Get(cpr::Url{BaseUri.c_str()});
- CHECK(Response.status_code == 200);
+ auto Response = Http.Get("/prj/test"sv);
+ CHECK(Response.StatusCode == HttpResponseCode::OK);
- zen::CbObjectView ResponseObject = zen::CbFieldView(Response.text.data()).AsObjectView();
+ CbObject ResponseObject = Response.AsObject();
CHECK(ResponseObject["id"].AsString() == "test"sv);
CHECK(ResponseObject["root"].AsString() == PathToUtf8(RootPath.c_str()));
}
}
- BaseUri << "/oplog/foobar";
+ BaseUri << "/prj/test/oplog/foobar";
{
+ HttpClient Http{BaseUri};
+
{
- zen::StringBuilder<64> PostUri;
- PostUri << BaseUri;
- auto Response = cpr::Post(cpr::Url{PostUri.c_str()});
- CHECK(Response.status_code == 201);
+ auto Response = Http.Post(""sv);
+ CHECK(Response.StatusCode == HttpResponseCode::Created);
}
{
- auto Response = cpr::Get(cpr::Url{BaseUri.c_str()});
- CHECK(Response.status_code == 200);
+ auto Response = Http.Get(""sv);
+ CHECK(Response.StatusCode == HttpResponseCode::OK);
- zen::CbObjectView ResponseObject = zen::CbFieldView(Response.text.data()).AsObjectView();
+ CbObject ResponseObject = Response.AsObject();
CHECK(ResponseObject["id"].AsString() == "foobar"sv);
CHECK(ResponseObject["project"].AsString() == "test"sv);
@@ -406,34 +401,34 @@ TEST_CASE("project.basic")
zen::BinaryWriter MemOut;
legacy::SaveCbPackage(OpPackage, MemOut);
+ HttpClient Http{BaseUri};
+
{
- zen::StringBuilder<64> PostUri;
- PostUri << BaseUri << "/new";
- auto Response = cpr::Post(cpr::Url{PostUri.c_str()}, cpr::Body{(const char*)MemOut.Data(), MemOut.Size()});
+ auto Response = Http.Post("/new", IoBufferBuilder::MakeFromMemory(MemOut.GetView()));
- REQUIRE(!Response.error);
- CHECK(Response.status_code == 201);
+ REQUIRE(Response);
+ CHECK(Response.StatusCode == HttpResponseCode::Created);
}
// Read file data
{
zen::StringBuilder<128> ChunkGetUri;
- ChunkGetUri << BaseUri << "/" << ChunkId;
- auto Response = cpr::Get(cpr::Url{ChunkGetUri.c_str()});
+ ChunkGetUri << "/" << ChunkId;
+ auto Response = Http.Get(ChunkGetUri);
- REQUIRE(!Response.error);
- CHECK(Response.status_code == 200);
+ REQUIRE(Response);
+ CHECK(Response.StatusCode == HttpResponseCode::OK);
}
{
zen::StringBuilder<128> ChunkGetUri;
- ChunkGetUri << BaseUri << "/" << ChunkId << "?offset=1&size=10";
- auto Response = cpr::Get(cpr::Url{ChunkGetUri.c_str()});
+ ChunkGetUri << "/" << ChunkId << "?offset=1&size=10";
+ auto Response = Http.Get(ChunkGetUri);
- REQUIRE(!Response.error);
- CHECK(Response.status_code == 200);
- CHECK(Response.text.size() == 10);
+ REQUIRE(Response);
+ CHECK(Response.StatusCode == HttpResponseCode::OK);
+ CHECK(Response.ResponsePayload.GetSize() == 10);
}
ZEN_INFO("+++++++");
@@ -467,49 +462,47 @@ TEST_CASE("project.basic")
zen::BinaryWriter MemOut;
legacy::SaveCbPackage(OpPackage, MemOut);
+ HttpClient Http{BaseUri};
+
{
- zen::StringBuilder<64> PostUri;
- PostUri << BaseUri << "/new";
- auto Response = cpr::Post(cpr::Url{PostUri.c_str()}, cpr::Body{(const char*)MemOut.Data(), MemOut.Size()});
+ auto Response = Http.Post("/new", IoBufferBuilder::MakeFromMemory(MemOut.GetView()));
- REQUIRE(!Response.error);
- CHECK(Response.status_code == 201);
+ REQUIRE(Response);
+ CHECK(Response.StatusCode == HttpResponseCode::Created);
}
// Read file data, it is raw and uncompressed
{
zen::StringBuilder<128> ChunkGetUri;
- ChunkGetUri << BaseUri << "/" << ChunkId;
- auto Response = cpr::Get(cpr::Url{ChunkGetUri.c_str()});
+ ChunkGetUri << "/" << ChunkId;
+ auto Response = Http.Get(ChunkGetUri);
- REQUIRE(!Response.error);
- CHECK(Response.status_code == 200);
- IoBuffer Data(IoBuffer::Wrap, Response.text.data(), Response.text.length());
+ REQUIRE(Response);
+ CHECK(Response.StatusCode == HttpResponseCode::OK);
+
+ IoBuffer Data = Response.ResponsePayload;
IoBuffer ReferenceData = IoBufferBuilder::MakeFromFile(RootPath / BinPath);
CHECK(ReferenceData.GetSize() == Data.GetSize());
CHECK(ReferenceData.GetView().EqualBytes(Data.GetView()));
}
{
- IoBuffer Payload = MakeCbObjectPayload([&](CbObjectWriter& Writer) { Writer.AddString("method"sv, "snapshot"sv); });
- zen::StringBuilder<64> PostUri;
- PostUri << BaseUri << "/rpc";
- auto Response = cpr::Post(cpr::Url{PostUri.c_str()},
- cpr::Body{(const char*)Payload.Data(), Payload.Size()},
- cpr::Header{{"Content-Type", "application/x-ue-cb"}});
- REQUIRE(!Response.error);
- CHECK(Response.status_code == 200);
+ IoBuffer Payload = MakeCbObjectPayload([&](CbObjectWriter& Writer) { Writer.AddString("method"sv, "snapshot"sv); });
+ auto Response = Http.Post("/rpc"sv, Payload, {{"Content-Type", "application/x-ue-cb"}});
+ REQUIRE(Response);
+ CHECK(Response.StatusCode == HttpResponseCode::OK);
}
// Read chunk data, it is now compressed
{
zen::StringBuilder<128> ChunkGetUri;
- ChunkGetUri << BaseUri << "/" << ChunkId;
- auto Response = cpr::Get(cpr::Url{ChunkGetUri.c_str()}, cpr::Header{{"Accept-Type", "application/x-ue-comp"}});
+ ChunkGetUri << "/" << ChunkId;
+ auto Response = Http.Get(ChunkGetUri, {{"Accept-Type", "application/x-ue-comp"}});
+
+ REQUIRE(Response);
+ CHECK(Response.StatusCode == HttpResponseCode::OK);
- REQUIRE(!Response.error);
- CHECK(Response.status_code == 200);
- IoBuffer Data(IoBuffer::Wrap, Response.text.data(), Response.text.length());
+ IoBuffer Data = Response.ResponsePayload;
IoHash RawHash;
uint64_t RawSize;
CompressedBuffer Compressed = CompressedBuffer::FromCompressed(SharedBuffer(Data), RawHash, RawSize);
@@ -526,24 +519,19 @@ TEST_CASE("project.basic")
SUBCASE("test chunk not found error")
{
+ HttpClient Http{BaseUri};
+
for (size_t I = 0; I < 65; I++)
{
zen::StringBuilder<128> PostUri;
- PostUri << BaseUri << "/f77c781846caead318084604/info";
- auto Response = cpr::Get(cpr::Url{PostUri.c_str()});
+ PostUri << "/f77c781846caead318084604/info";
+ auto Response = Http.Get(PostUri);
- REQUIRE(!Response.error);
- CHECK(Response.status_code == 404);
+ REQUIRE(!Response.Error);
+ CHECK(Response.StatusCode == HttpResponseCode::NotFound);
}
}
}
-
- const uint64_t Elapsed = timer.GetElapsedTimeMs();
-
- ZEN_INFO("{} requests in {} ({})",
- RequestCount.load(),
- zen::NiceTimeSpanMs(Elapsed),
- zen::NiceRate(RequestCount, (uint32_t)Elapsed, "req"));
}
namespace utils {
@@ -664,33 +652,32 @@ TEST_CASE("zcache.basic")
// Populate with some simple data
+ HttpClient Http{BaseUri};
+
for (int i = 0; i < kIterationCount; ++i)
{
zen::CbObjectWriter Cbo;
Cbo << "index" << i;
- zen::BinaryWriter MemOut;
- Cbo.Save(MemOut);
+ IoBuffer Payload = Cbo.Save().GetBuffer().AsIoBuffer();
+ Payload.SetContentType(HttpContentType::kCbObject);
zen::IoHash Key = HashKey(i);
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}", BaseUri, "test", Key)},
- cpr::Body{(const char*)MemOut.Data(), MemOut.Size()},
- cpr::Header{{"Content-Type", "application/x-ue-cb"}});
+ HttpClient::Response Result = Http.Put(fmt::format("/test/{}", Key), Payload);
- CHECK(Result.status_code == 201);
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
// Retrieve data
for (int i = 0; i < kIterationCount; ++i)
{
- zen::IoHash Key = zen::IoHash::HashBuffer(&i, sizeof i);
+ zen::IoHash Key = HashKey(i);
- cpr::Response Result =
- cpr::Get(cpr::Url{fmt::format("{}/{}/{}", BaseUri, "test", Key)}, cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
+ HttpClient::Response Result = Http.Get(fmt::format("/test/{}", Key), {{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
}
// Ensure bad bucket identifiers are rejected
@@ -699,16 +686,14 @@ TEST_CASE("zcache.basic")
zen::CbObjectWriter Cbo;
Cbo << "index" << 42;
- zen::BinaryWriter MemOut;
- Cbo.Save(MemOut);
+ IoBuffer Payload = Cbo.Save().GetBuffer().AsIoBuffer();
+ Payload.SetContentType(HttpContentType::kCbObject);
zen::IoHash Key = HashKey(442);
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}", BaseUri, "te!st", Key)},
- cpr::Body{(const char*)MemOut.Data(), MemOut.Size()},
- cpr::Header{{"Content-Type", "application/x-ue-cb"}});
+ HttpClient::Response Result = Http.Put(fmt::format("/te!st/{}", Key), Payload);
- CHECK(Result.status_code == 400);
+ CHECK(Result.StatusCode == HttpResponseCode::BadRequest);
}
}
@@ -721,20 +706,33 @@ TEST_CASE("zcache.basic")
const std::string BaseUri = fmt::format("http://localhost:{}/z$", PortNumber);
+ HttpClient Http{BaseUri};
+
// Retrieve data again
for (int i = 0; i < kIterationCount; ++i)
{
zen::IoHash Key = HashKey(i);
- cpr::Response Result =
- cpr::Get(cpr::Url{fmt::format("{}/{}/{}", BaseUri, "test", Key)}, cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
+ HttpClient::Response Result = Http.Get(fmt::format("/{}/{}", "test", Key), {{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
}
}
}
+IoBuffer
+SerializeToBuffer(const zen::CbPackage& Package)
+{
+ BinaryWriter MemStream;
+
+ Package.Save(MemStream);
+
+ IoBuffer Buffer = zen::IoBuffer(zen::IoBuffer::Clone, MemStream.Data(), MemStream.Size());
+ Buffer.SetContentType(HttpContentType::kCbPackage);
+ return Buffer;
+};
+
TEST_CASE("zcache.cbpackage")
{
using namespace std::literals;
@@ -757,14 +755,6 @@ TEST_CASE("zcache.cbpackage")
return Package;
};
- auto SerializeToBuffer = [](zen::CbPackage Package) -> zen::IoBuffer {
- zen::BinaryWriter MemStream;
-
- Package.Save(MemStream);
-
- return zen::IoBuffer(zen::IoBuffer::Clone, MemStream.Data(), MemStream.Size());
- };
-
auto IsEqual = [](zen::CbPackage Lhs, zen::CbPackage Rhs) -> bool {
std::span<const zen::CbAttachment> LhsAttachments = Lhs.GetAttachments();
std::span<const zen::CbAttachment> RhsAttachments = Rhs.GetAttachments();
@@ -803,29 +793,26 @@ TEST_CASE("zcache.cbpackage")
const uint16_t PortNumber = Instance1.SpawnServerAndWaitUntilReady();
const std::string BaseUri = fmt::format("http://localhost:{}/z$", PortNumber);
+ HttpClient Http{BaseUri};
+
const std::string_view Bucket = "mosdef"sv;
zen::IoHash Key;
zen::CbPackage ExpectedPackage = CreateTestPackage(Key);
// PUT
{
- zen::IoBuffer Body = SerializeToBuffer(ExpectedPackage);
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}", BaseUri, Bucket, Key)},
- cpr::Body{(const char*)Body.Data(), Body.Size()},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 201);
+ zen::IoBuffer Body = SerializeToBuffer(ExpectedPackage);
+ HttpClient::Response Result = Http.Put(fmt::format("/{}/{}", Bucket, Key), Body);
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
// GET
{
- cpr::Response Result =
- cpr::Get(cpr::Url{fmt::format("{}/{}/{}", BaseUri, Bucket, Key)}, cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
-
- zen::IoBuffer Response(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size());
+ HttpClient::Response Result = Http.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
zen::CbPackage Package;
- const bool Ok = Package.TryLoad(Response);
+ const bool Ok = Package.TryLoad(Result.ResponsePayload);
CHECK(Ok);
CHECK(IsEqual(Package, ExpectedPackage));
}
@@ -855,38 +842,35 @@ TEST_CASE("zcache.cbpackage")
zen::IoHash Key;
zen::CbPackage ExpectedPackage = CreateTestPackage(Key);
+ HttpClient LocalHttp{LocalBaseUri};
+ HttpClient RemoteHttp{RemoteBaseUri};
+
// Store the cache record package in the local instance
{
- zen::IoBuffer Body = SerializeToBuffer(ExpectedPackage);
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}", LocalBaseUri, Bucket, Key)},
- cpr::Body{(const char*)Body.Data(), Body.Size()},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}});
+ zen::IoBuffer Body = SerializeToBuffer(ExpectedPackage);
+ HttpClient::Response Result = LocalHttp.Put(fmt::format("/{}/{}", Bucket, Key), Body);
- CHECK(Result.status_code == 201);
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
// The cache record can be retrieved as a package from the local instance
{
- cpr::Response Result =
- cpr::Get(cpr::Url{fmt::format("{}/{}/{}", LocalBaseUri, Bucket, Key)}, cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result = LocalHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
- zen::IoBuffer Body(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size());
zen::CbPackage Package;
- const bool Ok = Package.TryLoad(Body);
+ const bool Ok = Package.TryLoad(Result.ResponsePayload);
CHECK(Ok);
CHECK(IsEqual(Package, ExpectedPackage));
}
// The cache record can be retrieved as a package from the remote instance
{
- cpr::Response Result =
- cpr::Get(cpr::Url{fmt::format("{}/{}/{}", RemoteBaseUri, Bucket, Key)}, cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result = RemoteHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
- zen::IoBuffer Body(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size());
zen::CbPackage Package;
- const bool Ok = Package.TryLoad(Body);
+ const bool Ok = Package.TryLoad(Result.ResponsePayload);
CHECK(Ok);
CHECK(IsEqual(Package, ExpectedPackage));
}
@@ -912,29 +896,28 @@ TEST_CASE("zcache.cbpackage")
const auto LocalBaseUri = fmt::format("http://localhost:{}/z$", LocalPortNumber);
const auto RemoteBaseUri = fmt::format("http://localhost:{}/z$", RemotePortNumber);
+ HttpClient LocalHttp{LocalBaseUri};
+ HttpClient RemoteHttp{RemoteBaseUri};
+
const std::string_view Bucket = "mosdef"sv;
zen::IoHash Key;
zen::CbPackage ExpectedPackage = CreateTestPackage(Key);
// Store the cache record package in upstream cache
{
- zen::IoBuffer Body = SerializeToBuffer(ExpectedPackage);
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}", RemoteBaseUri, Bucket, Key)},
- cpr::Body{(const char*)Body.Data(), Body.Size()},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}});
+ zen::IoBuffer Body = SerializeToBuffer(ExpectedPackage);
+ HttpClient::Response Result = RemoteHttp.Put(fmt::format("/{}/{}", Bucket, Key), Body);
- CHECK(Result.status_code == 201);
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
// The cache record can be retrieved as a package from the local cache
{
- cpr::Response Result =
- cpr::Get(cpr::Url{fmt::format("{}/{}/{}", LocalBaseUri, Bucket, Key)}, cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result = LocalHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
- zen::IoBuffer Body(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size());
zen::CbPackage Package;
- const bool Ok = Package.TryLoad(Body);
+ const bool Ok = Package.TryLoad(Result.ResponsePayload);
CHECK(Ok);
CHECK(IsEqual(Package, ExpectedPackage));
}
@@ -946,7 +929,7 @@ TEST_CASE("zcache.policy")
using namespace std::literals;
using namespace utils;
- auto GenerateData = [](uint64_t Size, zen::IoHash& OutHash) -> zen::UniqueBuffer {
+ auto GenerateData = [](uint64_t Size, zen::IoHash& OutHash) -> zen::IoBuffer {
auto Buf = zen::UniqueBuffer::Alloc(Size);
uint8_t* Data = reinterpret_cast<uint8_t*>(Buf.GetData());
for (uint64_t Idx = 0; Idx < Size; Idx++)
@@ -954,7 +937,7 @@ TEST_CASE("zcache.policy")
Data[Idx] = Idx % 256;
}
OutHash = zen::IoHash::HashBuffer(Data, Size);
- return Buf;
+ return Buf.MoveToShared().AsIoBuffer();
};
auto GeneratePackage = [](zen::IoHash& OutRecordKey, zen::IoHash& OutAttachmentKey) -> zen::CbPackage {
@@ -977,13 +960,6 @@ TEST_CASE("zcache.policy")
return Package;
};
- auto ToBuffer = [](zen::CbPackage Package) -> zen::IoBuffer {
- zen::BinaryWriter MemStream;
- Package.Save(MemStream);
-
- return zen::IoBuffer(zen::IoBuffer::Clone, MemStream.Data(), MemStream.Size());
- };
-
SUBCASE("query - 'local' does not query upstream (binary)")
{
ZenConfig UpstreamCfg = ZenConfig::New(TestEnv.GetNewPortNumber());
@@ -998,26 +974,26 @@ TEST_CASE("zcache.policy")
const std::string_view Bucket = "legacy"sv;
zen::IoHash Key;
- auto BinaryValue = GenerateData(1024, Key);
+ IoBuffer BinaryValue = GenerateData(1024, Key);
+
+ HttpClient LocalHttp{LocalCfg.BaseUri};
+ HttpClient RemoteHttp{UpstreamCfg.BaseUri};
- // Store binary cache value upstream
{
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}", UpstreamCfg.BaseUri, Bucket, Key)},
- cpr::Body{(const char*)BinaryValue.GetData(), BinaryValue.GetSize()},
- cpr::Header{{"Content-Type", "application/octet-stream"}});
- CHECK(Result.status_code == 201);
+ HttpClient::Response Result = RemoteHttp.Put(fmt::format("/{}/{}", Bucket, Key), BinaryValue);
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}?Policy=QueryLocal,Store", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/octet-stream"}});
- CHECK(Result.status_code == 404);
+ HttpClient::Response Result =
+ LocalHttp.Get(fmt::format("/{}/{}?Policy=QueryLocal,Store", Bucket, Key), {{"Accept", "application/octet-stream"}});
+ CHECK(Result.StatusCode == HttpResponseCode::NotFound);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}?Policy=Query,Store", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/octet-stream"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result =
+ LocalHttp.Get(fmt::format("/{}/{}?Policy=Query,Store", Bucket, Key), {{"Accept", "application/octet-stream"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
}
}
@@ -1035,26 +1011,27 @@ TEST_CASE("zcache.policy")
const auto Bucket = "legacy"sv;
zen::IoHash Key;
- auto BinaryValue = GenerateData(1024, Key);
+ IoBuffer BinaryValue = GenerateData(1024, Key);
+
+ HttpClient LocalHttp{LocalCfg.BaseUri};
+ HttpClient RemoteHttp{UpstreamCfg.BaseUri};
// Store binary cache value locally
{
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}?Policy=Query,StoreLocal", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Body{(const char*)BinaryValue.GetData(), BinaryValue.GetSize()},
- cpr::Header{{"Content-Type", "application/octet-stream"}});
- CHECK(Result.status_code == 201);
+ HttpClient::Response Result = LocalHttp.Put(fmt::format("/{}/{}?Policy=Query,StoreLocal", Bucket, Key),
+ BinaryValue,
+ {{"Content-Type", "application/octet-stream"}});
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}", UpstreamCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/octet-stream"}});
- CHECK(Result.status_code == 404);
+ HttpClient::Response Result = RemoteHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/octet-stream"}});
+ CHECK(Result.StatusCode == HttpResponseCode::NotFound);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/octet-stream"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result = LocalHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/octet-stream"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
}
}
@@ -1071,30 +1048,31 @@ TEST_CASE("zcache.policy")
const auto Bucket = "legacy"sv;
zen::IoHash Key;
- auto BinaryValue = GenerateData(1024, Key);
+ IoBuffer BinaryValue = GenerateData(1024, Key);
+
+ HttpClient LocalHttp{LocalCfg.BaseUri};
+ HttpClient RemoteHttp{UpstreamCfg.BaseUri};
// Store binary cache value locally and upstream
{
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}?Policy=Query,Store", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Body{(const char*)BinaryValue.GetData(), BinaryValue.GetSize()},
- cpr::Header{{"Content-Type", "application/octet-stream"}});
- CHECK(Result.status_code == 201);
+ HttpClient::Response Result = LocalHttp.Put(fmt::format("/{}/{}?Policy=Query,Store", Bucket, Key),
+ BinaryValue,
+ {{"Content-Type", "application/octet-stream"}});
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}", UpstreamCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/octet-stream"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result = RemoteHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/octet-stream"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/octet-stream"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result = LocalHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/octet-stream"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
}
}
- SUBCASE("query - 'local' does not query upstream (cppackage)")
+ SUBCASE("query - 'local' does not query upstream (cbpackage)")
{
ZenConfig UpstreamCfg = ZenConfig::New(TestEnv.GetNewPortNumber());
ZenServerInstance UpstreamInst(TestEnv);
@@ -1109,30 +1087,31 @@ TEST_CASE("zcache.policy")
zen::IoHash Key;
zen::IoHash PayloadId;
zen::CbPackage Package = GeneratePackage(Key, PayloadId);
- auto Buf = ToBuffer(Package);
+ IoBuffer Buf = SerializeToBuffer(Package);
+
+ HttpClient LocalHttp{LocalCfg.BaseUri};
+ HttpClient RemoteHttp{UpstreamCfg.BaseUri};
// Store package upstream
{
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}", UpstreamCfg.BaseUri, Bucket, Key)},
- cpr::Body{(const char*)Buf.GetData(), Buf.GetSize()},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 201);
+ HttpClient::Response Result = RemoteHttp.Put(fmt::format("/{}/{}", Bucket, Key), Buf);
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}?Policy=QueryLocal,Store", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 404);
+ HttpClient::Response Result =
+ LocalHttp.Get(fmt::format("/{}/{}?Policy=QueryLocal,Store", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result.StatusCode == HttpResponseCode::NotFound);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}?Policy=Query,Store", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result =
+ LocalHttp.Get(fmt::format("/{}/{}?Policy=Query,Store", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
}
}
- SUBCASE("store - 'local' does not store upstream (cbpackge)")
+ SUBCASE("store - 'local' does not store upstream (cbpackage)")
{
ZenConfig UpstreamCfg = ZenConfig::New(TestEnv.GetNewPortNumber());
ZenServerInstance UpstreamInst(TestEnv);
@@ -1147,26 +1126,25 @@ TEST_CASE("zcache.policy")
zen::IoHash Key;
zen::IoHash PayloadId;
zen::CbPackage Package = GeneratePackage(Key, PayloadId);
- auto Buf = ToBuffer(Package);
+ IoBuffer Buf = SerializeToBuffer(Package);
- // Store packge locally
+ HttpClient LocalHttp{LocalCfg.BaseUri};
+ HttpClient RemoteHttp{UpstreamCfg.BaseUri};
+
+ // Store package locally
{
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}?Policy=Query,StoreLocal", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Body{(const char*)Buf.GetData(), Buf.GetSize()},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 201);
+ HttpClient::Response Result = LocalHttp.Put(fmt::format("/{}/{}?Policy=Query,StoreLocal", Bucket, Key), Buf);
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}", UpstreamCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 404);
+ HttpClient::Response Result = RemoteHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result.StatusCode == HttpResponseCode::NotFound);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result = LocalHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
}
}
@@ -1185,26 +1163,25 @@ TEST_CASE("zcache.policy")
zen::IoHash Key;
zen::IoHash PayloadId;
zen::CbPackage Package = GeneratePackage(Key, PayloadId);
- auto Buf = ToBuffer(Package);
+ IoBuffer Buf = SerializeToBuffer(Package);
+
+ HttpClient LocalHttp{LocalCfg.BaseUri};
+ HttpClient RemoteHttp{UpstreamCfg.BaseUri};
// Store package locally and upstream
{
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}?Policy=Query,Store", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Body{(const char*)Buf.GetData(), Buf.GetSize()},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 201);
+ HttpClient::Response Result = LocalHttp.Put(fmt::format("/{}/{}?Policy=Query,Store", Bucket, Key), Buf);
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}", UpstreamCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result = RemoteHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
}
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}", LocalCfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result = LocalHttp.Get(fmt::format("/{}/{}", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
}
}
@@ -1219,44 +1196,41 @@ TEST_CASE("zcache.policy")
zen::IoHash Key;
zen::IoHash PayloadId;
zen::CbPackage Package = GeneratePackage(Key, PayloadId);
- auto Buf = ToBuffer(Package);
+ IoBuffer Buf = SerializeToBuffer(Package);
+
+ HttpClient Http{Cfg.BaseUri};
// Store package
{
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}", Cfg.BaseUri, Bucket, Key)},
- cpr::Body{(const char*)Buf.GetData(), Buf.GetSize()},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 201);
+ HttpClient::Response Result = Http.Put(fmt::format("/{}/{}", Bucket, Key), Buf);
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
// Get package
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}?Policy=Default,SkipData", Cfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/x-ue-cbpkg"}});
- CHECK(IsHttpSuccessCode(Result.status_code));
- IoBuffer Buffer(IoBuffer::Wrap, Result.text.c_str(), Result.text.size());
+ HttpClient::Response Result =
+ Http.Get(fmt::format("/{}/{}?Policy=Default,SkipData", Bucket, Key), {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Result);
CbPackage ResponsePackage;
- CHECK(ResponsePackage.TryLoad(Buffer));
+ CHECK(ResponsePackage.TryLoad(Result.ResponsePayload));
CHECK(ResponsePackage.GetAttachments().size() == 0);
}
// Get record
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}?Policy=Default,SkipData", Cfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/x-ue-cb"}});
- CHECK(IsHttpSuccessCode(Result.status_code));
- IoBuffer Buffer(IoBuffer::Wrap, Result.text.c_str(), Result.text.size());
- CbObject ResponseObject = zen::LoadCompactBinaryObject(Buffer);
- CHECK((bool)ResponseObject);
+ HttpClient::Response Result =
+ Http.Get(fmt::format("/{}/{}?Policy=Default,SkipData", Bucket, Key), {{"Accept", "application/x-ue-cb"}});
+ CHECK(Result);
+ CbObject ResponseObject = zen::LoadCompactBinaryObject(Result.ResponsePayload);
+ CHECK(ResponseObject);
}
// Get payload
{
- cpr::Response Result =
- cpr::Get(cpr::Url{fmt::format("{}/{}/{}/{}?Policy=Default,SkipData", Cfg.BaseUri, Bucket, Key, PayloadId)},
- cpr::Header{{"Accept", "application/x-ue-comp"}});
- CHECK(IsHttpSuccessCode(Result.status_code));
- CHECK(Result.text.size() == 0);
+ HttpClient::Response Result =
+ Http.Get(fmt::format("/{}/{}/{}?Policy=Default,SkipData", Bucket, Key, PayloadId), {{"Accept", "application/x-ue-comp"}});
+ CHECK(Result);
+ CHECK(Result.ResponsePayload.GetSize() == 0);
}
}
@@ -1269,22 +1243,22 @@ TEST_CASE("zcache.policy")
const auto Bucket = "test"sv;
zen::IoHash Key;
- auto BinaryValue = GenerateData(1024, Key);
+ IoBuffer BinaryValue = GenerateData(1024, Key);
+
+ HttpClient Http{Cfg.BaseUri};
// Store binary cache value
{
- cpr::Response Result = cpr::Put(cpr::Url{fmt::format("{}/{}/{}", Cfg.BaseUri, Bucket, Key)},
- cpr::Body{(const char*)BinaryValue.GetData(), BinaryValue.GetSize()},
- cpr::Header{{"Content-Type", "application/octet-stream"}});
- CHECK(Result.status_code == 201);
+ HttpClient::Response Result = Http.Put(fmt::format("/{}/{}", Bucket, Key), BinaryValue);
+ CHECK(Result.StatusCode == HttpResponseCode::Created);
}
// Get package
{
- cpr::Response Result = cpr::Get(cpr::Url{fmt::format("{}/{}/{}?Policy=Default,SkipData", Cfg.BaseUri, Bucket, Key)},
- cpr::Header{{"Accept", "application/octet-stream"}});
- CHECK(IsHttpSuccessCode(Result.status_code));
- CHECK(Result.text.size() == 0);
+ HttpClient::Response Result =
+ Http.Get(fmt::format("/{}/{}?Policy=Default,SkipData", Bucket, Key), {{"Accept", "application/octet-stream"}});
+ CHECK(Result);
+ CHECK(Result.ResponsePayload.GetSize() == 0);
}
}
}
@@ -1323,6 +1297,8 @@ TEST_CASE("zcache.rpc")
std::vector<CbPackage>* OutPackages = nullptr) -> std::vector<CacheKey> {
std::vector<zen::CacheKey> OutKeys;
+ HttpClient Http{BaseUri};
+
for (uint32_t Key = 1; Key <= Num; ++Key)
{
zen::IoHash KeyHash;
@@ -1336,12 +1312,11 @@ TEST_CASE("zcache.rpc")
CbPackage Package;
CHECK(Request.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
+ Body.SetContentType(HttpContentType::kCbPackage);
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
if (OutPackages)
{
OutPackages->emplace_back(std::move(Package));
@@ -1377,18 +1352,18 @@ TEST_CASE("zcache.rpc")
CbObjectWriter RequestWriter;
CHECK(Request.Format(RequestWriter));
- BinaryWriter Body;
- RequestWriter.Save(Body);
+ IoBuffer Body = RequestWriter.Save().GetBuffer().AsIoBuffer();
+ Body.SetContentType(HttpContentType::kCbObject);
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cb"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ HttpClient Http{BaseUri};
+
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
GetCacheRecordResult OutResult;
- if (Result.status_code == 200)
+ if (Result.StatusCode == HttpResponseCode::OK)
{
- CbPackage Response = ParsePackageMessage(zen::IoBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size()));
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
CHECK(!Response.IsNull());
OutResult.Response = std::move(Response);
CHECK(OutResult.Result.Parse(OutResult.Response));
@@ -1542,6 +1517,9 @@ TEST_CASE("zcache.rpc")
const size_t NumRecords = 4;
std::vector<zen::CacheKey> Keys = PutCacheRecords(LocalCfg.BaseUri, Namespace, Bucket, NumRecords, PayloadSize);
+ HttpClient LocalHttp{LocalCfg.BaseUri};
+ HttpClient UpstreamHttp{UpstreamCfg.BaseUri};
+
for (const zen::CacheKey& CacheKey : Keys)
{
cacherequests::PutCacheRecordsRequest Request = {.AcceptMagic = kCbPkgMagic, .Namespace = std::string(Namespace)};
@@ -1550,14 +1528,13 @@ TEST_CASE("zcache.rpc")
CbPackage Package;
CHECK(Request.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", LocalCfg.BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
+ Body.SetContentType(HttpContentType::kCbPackage);
+ HttpClient::Response Result = LocalHttp.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
cacherequests::PutCacheRecordsResult ParsedResult;
- CbPackage Response = ParsePackageMessage(zen::IoBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size()));
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
CHECK(!Response.IsNull());
CHECK(ParsedResult.Parse(Response));
for (bool ResponseSuccess : ParsedResult.Success)
@@ -1610,6 +1587,9 @@ TEST_CASE("zcache.rpc")
const size_t NumRecords = 4;
std::vector<zen::CacheKey> Keys = PutCacheRecords(LocalCfg.BaseUri, Namespace, Bucket, NumRecords, PayloadSize);
+ HttpClient LocalHttp{LocalCfg.BaseUri};
+ HttpClient UpstreamHttp{UpstreamCfg.BaseUri};
+
for (const zen::CacheKey& CacheKey : Keys)
{
cacherequests::PutCacheRecordsRequest Request = {.AcceptMagic = kCbPkgMagic, .Namespace = std::string(Namespace)};
@@ -1618,14 +1598,14 @@ TEST_CASE("zcache.rpc")
CbPackage Package;
CHECK(Request.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", LocalCfg.BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
+ Body.SetContentType(HttpContentType::kCbPackage);
+
+ HttpClient::Response Result = LocalHttp.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
cacherequests::PutCacheRecordsResult ParsedResult;
- CbPackage Response = ParsePackageMessage(zen::IoBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size()));
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
CHECK(!Response.IsNull());
CHECK(ParsedResult.Parse(Response));
CHECK(Request.Requests.size() == ParsedResult.Success.size());
@@ -1680,6 +1660,9 @@ TEST_CASE("zcache.rpc")
ZenServerInstance LocalServer(TestEnv);
SpawnServer(LocalServer, LocalCfg);
+ HttpClient LocalHttp{LocalCfg.BaseUri};
+ HttpClient UpstreamHttp{UpstreamCfg.BaseUri};
+
size_t PayloadSize = 1024;
std::string_view Namespace("ue4.ddc"sv);
std::string_view Bucket("mastodon"sv);
@@ -1694,14 +1677,13 @@ TEST_CASE("zcache.rpc")
CbPackage Package;
CHECK(Request.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", LocalCfg.BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
+ Body.SetContentType(HttpContentType::kCbPackage);
+ HttpClient::Response Result = LocalHttp.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
cacherequests::PutCacheRecordsResult ParsedResult;
- CbPackage Response = ParsePackageMessage(zen::IoBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size()));
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
CHECK(!Response.IsNull());
CHECK(ParsedResult.Parse(Response));
for (bool ResponseSuccess : ParsedResult.Success)
@@ -1748,6 +1730,9 @@ TEST_CASE("zcache.rpc")
ZenServerInstance LocalServer(TestEnv);
SpawnServer(LocalServer, LocalCfg);
+ HttpClient LocalHttp{LocalCfg.BaseUri};
+ HttpClient UpstreamHttp{UpstreamCfg.BaseUri};
+
size_t PayloadSize = 1024;
std::string_view Namespace("ue4.ddc"sv);
std::string_view Bucket("mastodon"sv);
@@ -1758,14 +1743,13 @@ TEST_CASE("zcache.rpc")
for (const CbPackage& Package : Packages)
{
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", LocalCfg.BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
+ Body.SetContentType(HttpContentType::kCbPackage);
+ HttpClient::Response Result = LocalHttp.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
- CHECK(Result.status_code == 200);
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
cacherequests::PutCacheRecordsResult ParsedResult;
- CbPackage Response = ParsePackageMessage(zen::IoBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size()));
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
CHECK(!Response.IsNull());
CHECK(ParsedResult.Parse(Response));
for (bool ResponseSuccess : ParsedResult.Success)
@@ -2082,14 +2066,14 @@ TEST_CASE("zcache.failing.upstream")
CbPackage Package;
CHECK(Request.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ HttpClient Http{BaseUri};
+
+ IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
- if (Result.status_code != 200)
+ if (Result.StatusCode != HttpResponseCode::OK)
{
- ZEN_DEBUG("PutCacheRecords failed with {}, reason '{}'", Result.status_code, Result.reason);
+ ZEN_DEBUG("PutCacheRecords failed with {}, reason '{}'", ToString(Result.StatusCode), Result.ErrorMessage(""));
OutKeys.clear();
}
@@ -2118,18 +2102,18 @@ TEST_CASE("zcache.failing.upstream")
CbObjectWriter RequestWriter;
CHECK(Request.Format(RequestWriter));
- BinaryWriter Body;
- RequestWriter.Save(Body);
+ IoBuffer Body = RequestWriter.Save().GetBuffer().AsIoBuffer();
+ Body.SetContentType(HttpContentType::kCbObject);
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cb"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ HttpClient Http{BaseUri};
+
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
GetCacheRecordResult OutResult;
- if (Result.status_code == 200)
+ if (Result.StatusCode == HttpResponseCode::OK)
{
- CbPackage Response = ParsePackageMessage(zen::IoBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size()));
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
if (!Response.IsNull())
{
OutResult.Response = std::move(Response);
@@ -2139,7 +2123,7 @@ TEST_CASE("zcache.failing.upstream")
}
else
{
- ZEN_DEBUG("GetCacheRecords with {}, reason '{}'", Result.reason, Result.status_code);
+ ZEN_DEBUG("GetCacheRecords with {}, reason '{}'", ToString(Result.StatusCode), Result.ErrorMessage(""));
}
return OutResult;
@@ -2339,14 +2323,16 @@ TEST_CASE("zcache.rpc.partialchunks")
CbPackage Package;
CHECK(Request.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ HttpClient Http{BaseUri};
+
+ IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
+ Body.SetContentType(HttpContentType::kCbPackage);
- if (Result.status_code != 200)
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
+
+ if (Result.StatusCode != HttpResponseCode::OK)
{
- ZEN_DEBUG("PutCacheRecords failed with {}, reason '{}'", Result.status_code, Result.reason);
+ ZEN_DEBUG("PutCacheRecords failed with {}, reason '{}'", ToString(Result.StatusCode), Result.ErrorMessage(""));
Keys.clear();
}
@@ -2379,14 +2365,16 @@ TEST_CASE("zcache.rpc.partialchunks")
.Requests = {{.Key = Key, .ValueId = ValueId, .RawOffset = Options.Offset, .RawSize = Options.Size}}};
CbPackage Package;
CHECK(Request.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
+ IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
+ Body.SetContentType(HttpContentType::kCbPackage);
+
+ HttpClient Http{BaseUri};
- CHECK(Result.status_code == 200);
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
- CbPackage Response = ParsePackageMessage(zen::IoBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size()));
+ CHECK(Result.StatusCode == HttpResponseCode::OK);
+
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
bool Loaded = !Response.IsNull();
CHECK_MESSAGE(Loaded, "GetCacheChunks response failed to load.");
cacherequests::GetCacheChunksResult GetCacheChunksResult;
@@ -2481,6 +2469,14 @@ TEST_CASE("zcache.rpc.partialchunks")
RpcAcceptOptions::kAllowPartialCacheChunks});
}
+IoBuffer
+FormatPackageBody(const CbPackage& Package)
+{
+ IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
+ Body.SetContentType(HttpContentType::kCbPackage);
+ return Body;
+}
+
TEST_CASE("zcache.rpc.allpolicies")
{
using namespace std::literals;
@@ -2495,6 +2491,7 @@ TEST_CASE("zcache.rpc.allpolicies")
SpawnServer(LocalServer, LocalCfg);
const auto BaseUri = fmt::format("http://localhost:{}/z$", LocalServer.GetBasePort());
+ HttpClient Http{BaseUri};
std::string_view TestVersion = "F72150A02AE34B57A9EC91D36BA1CE08"sv;
std::string_view TestBucket = "allpoliciestest"sv;
@@ -2711,11 +2708,9 @@ TEST_CASE("zcache.rpc.allpolicies")
CbPackage Package;
CHECK(Request.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
- CHECK_MESSAGE(Result.status_code == 200, "PutCacheRecords unexpectedly failed.");
+ IoBuffer Body = FormatPackageBody(Package);
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK_MESSAGE(Result.StatusCode == HttpResponseCode::OK, "PutCacheRecords unexpectedly failed.");
}
// PutCacheValues
@@ -2735,11 +2730,9 @@ TEST_CASE("zcache.rpc.allpolicies")
CbPackage Package;
CHECK(Request.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
- CHECK_MESSAGE(Result.status_code == 200, "PutCacheValues unexpectedly failed.");
+ IoBuffer Body = FormatPackageBody(Package);
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK_MESSAGE(Result.StatusCode == HttpResponseCode::OK, "PutCacheValues unexpectedly failed.");
}
for (KeyData& KeyData : KeyDatas)
@@ -2772,12 +2765,10 @@ TEST_CASE("zcache.rpc.allpolicies")
CbPackage Package;
CHECK(Request.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
- CHECK_MESSAGE(Result.status_code == 200, "GetCacheRecords unexpectedly failed.");
- CbPackage Response = ParsePackageMessage(zen::IoBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size()));
+ IoBuffer Body = FormatPackageBody(Package);
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK_MESSAGE(Result.StatusCode == HttpResponseCode::OK, "GetCacheRecords unexpectedly failed.");
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
bool Loaded = !Response.IsNull();
CHECK_MESSAGE(Loaded, "GetCacheRecords response failed to load.");
cacherequests::GetCacheRecordsResult RequestResult;
@@ -2852,12 +2843,10 @@ TEST_CASE("zcache.rpc.allpolicies")
CbPackage Package;
CHECK(GetCacheValuesRequest.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
- CHECK_MESSAGE(Result.status_code == 200, "GetCacheValues unexpectedly failed.");
- IoBuffer MessageBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size());
+ IoBuffer Body = FormatPackageBody(Package);
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK_MESSAGE(Result.StatusCode == HttpResponseCode::OK, "GetCacheValues unexpectedly failed.");
+ IoBuffer MessageBuffer(Result.ResponsePayload);
CbPackage Response = ParsePackageMessage(MessageBuffer);
bool Loaded = !Response.IsNull();
CHECK_MESSAGE(Loaded, "GetCacheValues response failed to load.");
@@ -2922,12 +2911,10 @@ TEST_CASE("zcache.rpc.allpolicies")
CbPackage Package;
CHECK(GetCacheChunksRequest.Format(Package));
- IoBuffer Body = FormatPackageMessageBuffer(Package).Flatten().AsIoBuffer();
- cpr::Response Result = cpr::Post(cpr::Url{fmt::format("{}/$rpc", BaseUri)},
- cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}},
- cpr::Body{(const char*)Body.GetData(), Body.GetSize()});
- CHECK_MESSAGE(Result.status_code == 200, "GetCacheChunks unexpectedly failed.");
- CbPackage Response = ParsePackageMessage(zen::IoBuffer(zen::IoBuffer::Wrap, Result.text.data(), Result.text.size()));
+ IoBuffer Body = FormatPackageBody(Package);
+ HttpClient::Response Result = Http.Post("/$rpc", Body, {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK_MESSAGE(Result.StatusCode == HttpResponseCode::OK, "GetCacheChunks unexpectedly failed.");
+ CbPackage Response = ParsePackageMessage(Result.ResponsePayload);
bool Loaded = !Response.IsNull();
CHECK_MESSAGE(Loaded, "GetCacheChunks response failed to load.");
cacherequests::GetCacheChunksResult GetCacheChunksResult;
@@ -3058,20 +3045,23 @@ TEST_CASE("http.basics")
ZenServerInstance& Instance = Servers.GetInstance(0);
const std::string BaseUri = Instance.GetBaseUri();
+ HttpClient Http{BaseUri};
+
{
- cpr::Response r = cpr::Get(cpr::Url{fmt::format("{}/testing/hello", BaseUri)});
- CHECK(IsHttpSuccessCode(r.status_code));
+ HttpClient::Response r = Http.Get("/testing/hello");
+ CHECK(r);
}
{
- cpr::Response r = cpr::Post(cpr::Url{fmt::format("{}/testing/hello", BaseUri)});
- CHECK_EQ(r.status_code, 404);
+ HttpClient::Response r = Http.Post("/testing/hello");
+ CHECK_EQ(r.StatusCode, HttpResponseCode::NotFound);
}
{
- cpr::Response r = cpr::Post(cpr::Url{fmt::format("{}/testing/echo", BaseUri)}, cpr::Body{"yoyoyoyo"});
- CHECK_EQ(r.status_code, 200);
- CHECK_EQ(r.text, "yoyoyoyo");
+ IoBuffer Body{IoBuffer::Wrap, "yoyoyoyo", 8};
+ HttpClient::Response r = Http.Post("/testing/echo", Body);
+ CHECK_EQ(r.StatusCode, HttpResponseCode::OK);
+ CHECK(r.ResponsePayload.GetView().EqualBytes(Body.GetView()));
}
}
@@ -3178,12 +3168,6 @@ CreateOplogOp(const Oid& Id, const std::span<const std::pair<Oid, CompressedBuff
return Object.Save();
};
-cpr::Body
-AsBody(const IoBuffer& Payload)
-{
- return cpr::Body{(const char*)Payload.GetData(), Payload.Size()};
-};
-
enum CbWriterMeta
{
BeginObject,
@@ -3286,46 +3270,40 @@ TEST_CASE("project.remote")
Ops.insert({Id, OpCoreHash});
};
- auto MakeProject = [](cpr::Session& Session, std::string_view UrlBase, std::string_view ProjectName) {
+ auto MakeProject = [](std::string_view UrlBase, std::string_view ProjectName) {
CbObjectWriter Project;
Project.AddString("id"sv, ProjectName);
Project.AddString("root"sv, ""sv);
Project.AddString("engine"sv, ""sv);
Project.AddString("project"sv, ""sv);
Project.AddString("projectfile"sv, ""sv);
- IoBuffer ProjectPayload = Project.Save().GetBuffer().AsIoBuffer();
- std::string ProjectRequest = fmt::format("{}/prj/{}", UrlBase, ProjectName);
- Session.SetUrl({ProjectRequest});
- Session.SetBody(cpr::Body{(const char*)ProjectPayload.GetData(), ProjectPayload.GetSize()});
- cpr::Response Response = Session.Post();
- CHECK(IsHttpSuccessCode(Response.status_code));
+ IoBuffer ProjectPayload = Project.Save().GetBuffer().AsIoBuffer();
+ ProjectPayload.SetContentType(HttpContentType::kCbObject);
+
+ HttpClient Http{UrlBase};
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}", ProjectName), ProjectPayload);
+ CHECK(Response);
};
- auto MakeOplog = [](cpr::Session& Session, std::string_view UrlBase, std::string_view ProjectName, std::string_view OplogName) {
- std::string CreateOplogRequest = fmt::format("{}/prj/{}/oplog/{}", UrlBase, ProjectName, OplogName);
- Session.SetUrl({CreateOplogRequest});
- Session.SetBody(cpr::Body{});
- cpr::Response Response = Session.Post();
- CHECK(IsHttpSuccessCode(Response.status_code));
+ auto MakeOplog = [](std::string_view UrlBase, std::string_view ProjectName, std::string_view OplogName) {
+ HttpClient Http{UrlBase};
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}", ProjectName, OplogName), IoBuffer{});
+ CHECK(Response);
};
- auto MakeOp = [](cpr::Session& Session,
- std::string_view UrlBase,
- std::string_view ProjectName,
- std::string_view OplogName,
- const CbPackage& OpPackage) {
- std::string CreateOpRequest = fmt::format("{}/prj/{}/oplog/{}/new", UrlBase, ProjectName, OplogName);
- Session.SetUrl({CreateOpRequest});
+ auto MakeOp = [](std::string_view UrlBase, std::string_view ProjectName, std::string_view OplogName, const CbPackage& OpPackage) {
zen::BinaryWriter MemOut;
legacy::SaveCbPackage(OpPackage, MemOut);
- Session.SetBody(cpr::Body{(const char*)MemOut.Data(), MemOut.Size()});
- cpr::Response Response = Session.Post();
- CHECK(IsHttpSuccessCode(Response.status_code));
+ IoBuffer Body{IoBuffer::Wrap, MemOut.GetData(), MemOut.GetSize()};
+ Body.SetContentType(HttpContentType::kCbPackage);
+
+ HttpClient Http{UrlBase};
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}/new", ProjectName, OplogName), Body);
+ CHECK(Response);
};
- cpr::Session Session;
- MakeProject(Session, Servers.GetInstance(0).GetBaseUri(), "proj0");
- MakeOplog(Session, Servers.GetInstance(0).GetBaseUri(), "proj0", "oplog0");
+ MakeProject(Servers.GetInstance(0).GetBaseUri(), "proj0");
+ MakeOplog(Servers.GetInstance(0).GetBaseUri(), "proj0", "oplog0");
std::unordered_map<Oid, uint32_t, Oid::Hasher> SourceOps;
for (const Oid& OpId : OpIds)
@@ -3333,7 +3311,7 @@ TEST_CASE("project.remote")
CbPackage OpPackage = CreateOplogPackage(OpId, Attachments[OpId]);
CHECK(OpPackage.GetAttachments().size() == Attachments[OpId].size());
AddOp(OpPackage.GetObject(), SourceOps);
- MakeOp(Session, Servers.GetInstance(0).GetBaseUri(), "proj0", "oplog0", OpPackage);
+ MakeOp(Servers.GetInstance(0).GetBaseUri(), "proj0", "oplog0", OpPackage);
}
std::vector<IoHash> AttachmentHashes;
@@ -3351,47 +3329,45 @@ TEST_CASE("project.remote")
Write(Writer);
IoBuffer Result = Writer.Save().GetBuffer().AsIoBuffer();
Result.MakeOwned();
+ Result.SetContentType(HttpContentType::kCbObject);
return Result;
};
- auto ValidateAttachments = [&MakeCbObjectPayload, &AttachmentHashes, &Servers, &Session](int ServerIndex,
- std::string_view Project,
- std::string_view Oplog) {
- std::string GetChunksRequest = fmt::format("{}/prj/{}/oplog/{}/rpc", Servers.GetInstance(ServerIndex).GetBaseUri(), Project, Oplog);
- Session.SetUrl({GetChunksRequest});
- IoBuffer Payload = MakeCbObjectPayload([&AttachmentHashes](CbObjectWriter& Writer) {
- Writer << "method"sv
- << "getchunks"sv;
- Writer << "chunks"sv << BeginArray;
- for (const IoHash& Chunk : AttachmentHashes)
+ auto ValidateAttachments =
+ [&MakeCbObjectPayload, &AttachmentHashes, &Servers](int ServerIndex, std::string_view Project, std::string_view Oplog) {
+ HttpClient Http{Servers.GetInstance(ServerIndex).GetBaseUri()};
+
+ IoBuffer Payload = MakeCbObjectPayload([&AttachmentHashes](CbObjectWriter& Writer) {
+ Writer << "method"sv
+ << "getchunks"sv;
+ Writer << "chunks"sv << BeginArray;
+ for (const IoHash& Chunk : AttachmentHashes)
+ {
+ Writer << Chunk;
+ }
+ Writer << EndArray; // chunks
+ });
+
+ HttpClient::Response Response =
+ Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", Project, Oplog), Payload, {{"Accept", "application/x-ue-cbpkg"}});
+ CHECK(Response);
+ CbPackage ResponsePackage = ParsePackageMessage(Response.ResponsePayload);
+ CHECK(ResponsePackage.GetAttachments().size() == AttachmentHashes.size());
+ for (auto A : ResponsePackage.GetAttachments())
{
- Writer << Chunk;
+ CHECK(IoHash::HashBuffer(A.AsCompressedBinary().DecompressToComposite()) == A.GetHash());
}
- Writer << EndArray; // chunks
- });
- Session.SetBody(AsBody(Payload));
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cb"}, {"Accept", "application/x-ue-cbpkg"}});
- cpr::Response Response = Session.Post();
- CHECK(IsHttpSuccessCode(Response.status_code));
- CbPackage ResponsePackage = ParsePackageMessage(IoBuffer(IoBuffer::Wrap, Response.text.data(), Response.text.size()));
- CHECK(ResponsePackage.GetAttachments().size() == AttachmentHashes.size());
- for (auto A : ResponsePackage.GetAttachments())
- {
- CHECK(IoHash::HashBuffer(A.AsCompressedBinary().DecompressToComposite()) == A.GetHash());
- }
- };
+ };
- auto ValidateOplog = [&SourceOps, &AddOp, &Servers, &Session](int ServerIndex, std::string_view Project, std::string_view Oplog) {
+ auto ValidateOplog = [&SourceOps, &AddOp, &Servers](int ServerIndex, std::string_view Project, std::string_view Oplog) {
std::unordered_map<Oid, uint32_t, Oid::Hasher> TargetOps;
std::vector<CbObject> ResultingOplog;
- std::string GetOpsRequest =
- fmt::format("{}/prj/{}/oplog/{}/entries", Servers.GetInstance(ServerIndex).GetBaseUri(), Project, Oplog);
- Session.SetUrl({GetOpsRequest});
- cpr::Response Response = Session.Get();
- CHECK(IsHttpSuccessCode(Response.status_code));
+ HttpClient Http{Servers.GetInstance(ServerIndex).GetBaseUri()};
+ HttpClient::Response Response = Http.Get(fmt::format("/prj/{}/oplog/{}/entries", Project, Oplog));
+ CHECK(Response);
- IoBuffer Payload(IoBuffer::Wrap, Response.text.data(), Response.text.size());
+ IoBuffer Payload(Response.ResponsePayload);
CbObject OplogResonse = LoadCompactBinaryObject(Payload);
CbArrayView EntriesArray = OplogResonse["entries"sv].AsArrayView();
@@ -3408,19 +3384,20 @@ TEST_CASE("project.remote")
CHECK(SourceOps == TargetOps);
};
- auto WaitForCompletion = [&Session](ZenServerInstance& Server, const cpr::Response& Response) {
- CHECK(IsHttpSuccessCode(Response.status_code));
- uint64_t JobId = ParseInt<uint64_t>(Response.text).value_or(0);
+ auto HttpWaitForCompletion = [](ZenServerInstance& Server, const HttpClient::Response& Response) {
+ REQUIRE(Response);
+ const uint64_t JobId = ParseInt<uint64_t>(Response.AsText()).value_or(0);
CHECK(JobId != 0);
- Session.SetUrl(fmt::format("{}/admin/jobs/{}", Server.GetBaseUri(), JobId));
- Session.SetHeader(cpr::Header{{"Accept", std::string(ToString(ZenContentType::kCbObject))}});
+
+ HttpClient Http{Server.GetBaseUri()};
+
while (true)
{
- cpr::Response StatusResponse = Session.Get();
- CHECK(IsHttpSuccessCode(StatusResponse.status_code));
- CbObject ResponseObject =
- LoadCompactBinaryObject(IoBuffer(IoBuffer::Wrap, StatusResponse.text.data(), StatusResponse.text.size()));
- std::string_view Status = ResponseObject["Status"sv].AsString();
+ HttpClient::Response StatusResponse =
+ Http.Get(fmt::format("/admin/jobs/{}", JobId), {{"Accept", ToString(ZenContentType::kCbObject)}});
+ CHECK(StatusResponse);
+ CbObject ResponseObject = StatusResponse.AsObject();
+ std::string_view Status = ResponseObject["Status"sv].AsString();
CHECK(Status != "Aborted"sv);
if (Status == "Complete"sv)
{
@@ -3434,9 +3411,6 @@ TEST_CASE("project.remote")
{
ScopedTemporaryDirectory TempDir;
{
- std::string SaveOplogRequest = fmt::format("{}/prj/{}/oplog/{}/rpc", Servers.GetInstance(0).GetBaseUri(), "proj0", "oplog0");
- Session.SetUrl({SaveOplogRequest});
-
IoBuffer Payload = MakeCbObjectPayload([&AttachmentHashes, path = TempDir.Path().string()](CbObjectWriter& Writer) {
Writer << "method"sv
<< "export"sv;
@@ -3456,17 +3430,15 @@ TEST_CASE("project.remote")
}
Writer << EndObject; // "params"
});
- Session.SetBody(AsBody(Payload));
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cb"}});
- cpr::Response Response = Session.Post();
- WaitForCompletion(Servers.GetInstance(0), Response);
+
+ HttpClient Http{Servers.GetInstance(0).GetBaseUri()};
+
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", "proj0", "oplog0"), Payload);
+ HttpWaitForCompletion(Servers.GetInstance(0), Response);
}
{
- MakeProject(Session, Servers.GetInstance(1).GetBaseUri(), "proj0_copy");
- MakeOplog(Session, Servers.GetInstance(1).GetBaseUri(), "proj0_copy", "oplog0_copy");
- std::string LoadOplogRequest =
- fmt::format("{}/prj/{}/oplog/{}/rpc", Servers.GetInstance(1).GetBaseUri(), "proj0_copy", "oplog0_copy");
- Session.SetUrl({LoadOplogRequest});
+ MakeProject(Servers.GetInstance(1).GetBaseUri(), "proj0_copy");
+ MakeOplog(Servers.GetInstance(1).GetBaseUri(), "proj0_copy", "oplog0_copy");
IoBuffer Payload = MakeCbObjectPayload([&AttachmentHashes, path = TempDir.Path().string()](CbObjectWriter& Writer) {
Writer << "method"sv
@@ -3484,11 +3456,11 @@ TEST_CASE("project.remote")
}
Writer << EndObject; // "params"
});
- Session.SetBody(AsBody(Payload));
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cb"}});
- cpr::Response Response = Session.Post();
- WaitForCompletion(Servers.GetInstance(1), Response);
+ HttpClient Http{Servers.GetInstance(1).GetBaseUri()};
+
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", "proj0_copy", "oplog0_copy"), Payload);
+ HttpWaitForCompletion(Servers.GetInstance(1), Response);
}
ValidateAttachments(1, "proj0_copy", "oplog0_copy");
ValidateOplog(1, "proj0_copy", "oplog0_copy");
@@ -3498,9 +3470,6 @@ TEST_CASE("project.remote")
{
ScopedTemporaryDirectory TempDir;
{
- std::string SaveOplogRequest = fmt::format("{}/prj/{}/oplog/{}/rpc", Servers.GetInstance(0).GetBaseUri(), "proj0", "oplog0");
- Session.SetUrl({SaveOplogRequest});
-
IoBuffer Payload = MakeCbObjectPayload([&](CbObjectWriter& Writer) {
Writer << "method"sv
<< "export"sv;
@@ -3521,17 +3490,15 @@ TEST_CASE("project.remote")
}
Writer << EndObject; // "params"
});
- Session.SetBody(AsBody(Payload));
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cb"}});
- cpr::Response Response = Session.Post();
- WaitForCompletion(Servers.GetInstance(0), Response);
+
+ HttpClient Http{Servers.GetInstance(0).GetBaseUri()};
+
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", "proj0", "oplog0"), Payload);
+ HttpWaitForCompletion(Servers.GetInstance(0), Response);
}
{
- MakeProject(Session, Servers.GetInstance(1).GetBaseUri(), "proj0_copy");
- MakeOplog(Session, Servers.GetInstance(1).GetBaseUri(), "proj0_copy", "oplog0_copy");
- std::string LoadOplogRequest =
- fmt::format("{}/prj/{}/oplog/{}/rpc", Servers.GetInstance(1).GetBaseUri(), "proj0_copy", "oplog0_copy");
- Session.SetUrl({LoadOplogRequest});
+ MakeProject(Servers.GetInstance(1).GetBaseUri(), "proj0_copy");
+ MakeOplog(Servers.GetInstance(1).GetBaseUri(), "proj0_copy", "oplog0_copy");
IoBuffer Payload = MakeCbObjectPayload([&](CbObjectWriter& Writer) {
Writer << "method"sv
<< "import"sv;
@@ -3548,10 +3515,11 @@ TEST_CASE("project.remote")
}
Writer << EndObject; // "params"
});
- Session.SetBody(AsBody(Payload));
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cb"}});
- cpr::Response Response = Session.Post();
- WaitForCompletion(Servers.GetInstance(1), Response);
+
+ HttpClient Http{Servers.GetInstance(1).GetBaseUri()};
+
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", "proj0_copy", "oplog0_copy"), Payload);
+ HttpWaitForCompletion(Servers.GetInstance(1), Response);
}
ValidateAttachments(1, "proj0_copy", "oplog0_copy");
ValidateOplog(1, "proj0_copy", "oplog0_copy");
@@ -3561,8 +3529,6 @@ TEST_CASE("project.remote")
{
ScopedTemporaryDirectory TempDir;
{
- std::string SaveOplogRequest = fmt::format("{}/prj/{}/oplog/{}/rpc", Servers.GetInstance(0).GetBaseUri(), "proj0", "oplog0");
- Session.SetUrl({SaveOplogRequest});
IoBuffer Payload = MakeCbObjectPayload([&](CbObjectWriter& Writer) {
Writer << "method"sv
<< "export"sv;
@@ -3583,17 +3549,14 @@ TEST_CASE("project.remote")
}
Writer << EndObject; // "params"
});
- Session.SetBody(AsBody(Payload));
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cb"}});
- cpr::Response Response = Session.Post();
- WaitForCompletion(Servers.GetInstance(0), Response);
+
+ HttpClient Http{Servers.GetInstance(0).GetBaseUri()};
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", "proj0", "oplog0"), Payload);
+ HttpWaitForCompletion(Servers.GetInstance(0), Response);
}
{
- MakeProject(Session, Servers.GetInstance(1).GetBaseUri(), "proj0_copy");
- MakeOplog(Session, Servers.GetInstance(1).GetBaseUri(), "proj0_copy", "oplog0_copy");
- std::string LoadOplogRequest =
- fmt::format("{}/prj/{}/oplog/{}/rpc", Servers.GetInstance(1).GetBaseUri(), "proj0_copy", "oplog0_copy");
- Session.SetUrl({LoadOplogRequest});
+ MakeProject(Servers.GetInstance(1).GetBaseUri(), "proj0_copy");
+ MakeOplog(Servers.GetInstance(1).GetBaseUri(), "proj0_copy", "oplog0_copy");
IoBuffer Payload = MakeCbObjectPayload([&](CbObjectWriter& Writer) {
Writer << "method"sv
<< "import"sv;
@@ -3610,10 +3573,10 @@ TEST_CASE("project.remote")
}
Writer << EndObject; // "params"
});
- Session.SetBody(AsBody(Payload));
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cb"}});
- cpr::Response Response = Session.Post();
- WaitForCompletion(Servers.GetInstance(1), Response);
+
+ HttpClient Http{Servers.GetInstance(1).GetBaseUri()};
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", "proj0_copy", "oplog0_copy"), Payload);
+ HttpWaitForCompletion(Servers.GetInstance(1), Response);
}
ValidateAttachments(1, "proj0_copy", "oplog0_copy");
ValidateOplog(1, "proj0_copy", "oplog0_copy");
@@ -3625,11 +3588,8 @@ TEST_CASE("project.remote")
{
std::string ExportSourceUri = Servers.GetInstance(0).GetBaseUri();
std::string ExportTargetUri = Servers.GetInstance(1).GetBaseUri();
- MakeProject(Session, ExportTargetUri, "proj0_copy");
- MakeOplog(Session, ExportTargetUri, "proj0_copy", "oplog0_copy");
-
- std::string SaveOplogRequest = fmt::format("{}/prj/{}/oplog/{}/rpc", ExportSourceUri, "proj0", "oplog0");
- Session.SetUrl({SaveOplogRequest});
+ MakeProject(ExportTargetUri, "proj0_copy");
+ MakeOplog(ExportTargetUri, "proj0_copy", "oplog0_copy");
IoBuffer Payload = MakeCbObjectPayload([&](CbObjectWriter& Writer) {
Writer << "method"sv
@@ -3652,10 +3612,10 @@ TEST_CASE("project.remote")
}
Writer << EndObject; // "params"
});
- Session.SetBody(AsBody(Payload));
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cb"}});
- cpr::Response Response = Session.Post();
- WaitForCompletion(Servers.GetInstance(0), Response);
+
+ HttpClient Http{Servers.GetInstance(0).GetBaseUri()};
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", "proj0", "oplog0"), Payload);
+ HttpWaitForCompletion(Servers.GetInstance(0), Response);
}
ValidateAttachments(1, "proj0_copy", "oplog0_copy");
ValidateOplog(1, "proj0_copy", "oplog0_copy");
@@ -3663,10 +3623,8 @@ TEST_CASE("project.remote")
{
std::string ImportSourceUri = Servers.GetInstance(1).GetBaseUri();
std::string ImportTargetUri = Servers.GetInstance(2).GetBaseUri();
- MakeProject(Session, ImportTargetUri, "proj1");
- MakeOplog(Session, ImportTargetUri, "proj1", "oplog1");
- std::string LoadOplogRequest = fmt::format("{}/prj/{}/oplog/{}/rpc", ImportTargetUri, "proj1", "oplog1");
- Session.SetUrl({LoadOplogRequest});
+ MakeProject(ImportTargetUri, "proj1");
+ MakeOplog(ImportTargetUri, "proj1", "oplog1");
IoBuffer Payload = MakeCbObjectPayload([&](CbObjectWriter& Writer) {
Writer << "method"sv
@@ -3686,10 +3644,10 @@ TEST_CASE("project.remote")
}
Writer << EndObject; // "params"
});
- Session.SetBody(AsBody(Payload));
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cb"}});
- cpr::Response Response = Session.Post();
- WaitForCompletion(Servers.GetInstance(2), Response);
+
+ HttpClient Http{Servers.GetInstance(2).GetBaseUri()};
+ HttpClient::Response Response = Http.Post(fmt::format("/prj/{}/oplog/{}/rpc", "proj1", "oplog1"), Payload);
+ HttpWaitForCompletion(Servers.GetInstance(2), Response);
}
ValidateAttachments(2, "proj1", "oplog1");
ValidateOplog(2, "proj1", "oplog1");
diff --git a/src/zenserver/cache/httpstructuredcache.cpp b/src/zenserver/cache/httpstructuredcache.cpp
index bc3f4ee20..dad4ed803 100644
--- a/src/zenserver/cache/httpstructuredcache.cpp
+++ b/src/zenserver/cache/httpstructuredcache.cpp
@@ -40,7 +40,6 @@
#include <queue>
#include <thread>
-#include <cpr/cpr.h>
#include <gsl/gsl-lite.hpp>
namespace zen {
@@ -391,8 +390,9 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request)
if (Key == HttpZCacheUtilStartRecording)
{
- HttpServerRequest::QueryParams Params = Request.GetQueryParams();
- std::string RecordPath = cpr::util::urlDecode(std::string(Params.GetValue("path")));
+ HttpServerRequest::QueryParams Params = Request.GetQueryParams();
+
+ std::string RecordPath = UrlDecode(Params.GetValue("path"));
{
RwLock::ExclusiveLockScope _(m_RequestRecordingLock);
@@ -429,9 +429,11 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request)
m_RequestRecorder.reset();
}
- HttpServerRequest::QueryParams Params = Request.GetQueryParams();
- std::string RecordPath = cpr::util::urlDecode(std::string(Params.GetValue("path")));
- uint32_t ThreadCount = std::thread::hardware_concurrency();
+ HttpServerRequest::QueryParams Params = Request.GetQueryParams();
+
+ std::string RecordPath = UrlDecode(Params.GetValue("path"));
+
+ uint32_t ThreadCount = std::thread::hardware_concurrency();
if (auto Param = Params.GetValue("thread_count"); Param.empty() == false)
{
if (auto Value = ParseInt<uint64_t>(Param))
diff --git a/src/zenserver/projectstore/buildsremoteprojectstore.cpp b/src/zenserver/projectstore/buildsremoteprojectstore.cpp
index 0b0d8ccd0..b8b499f7f 100644
--- a/src/zenserver/projectstore/buildsremoteprojectstore.cpp
+++ b/src/zenserver/projectstore/buildsremoteprojectstore.cpp
@@ -255,7 +255,9 @@ public:
}
catch (const HttpClientError& Ex)
{
- Result.ErrorCode = Ex.m_Error != 0 ? Ex.m_Error : Ex.m_ResponseCode != HttpResponseCode::ImATeapot ? (int)Ex.m_ResponseCode : 0;
+ Result.ErrorCode = Ex.GetInternalErrorCode() != 0 ? Ex.GetInternalErrorCode()
+ : Ex.GetHttpResponseCode() != HttpResponseCode::ImATeapot ? (int)Ex.GetHttpResponseCode()
+ : 0;
Result.Reason = fmt::format("Failed finalizing oplog container build part to {}/{}/{}/{}/{}. Reason: '{}'",
m_Url,
m_Namespace,
@@ -284,9 +286,9 @@ public:
}
catch (const HttpClientError& Ex)
{
- Result.ErrorCode = Ex.m_Error != 0 ? Ex.m_Error
- : Ex.m_ResponseCode != HttpResponseCode::ImATeapot ? (int)Ex.m_ResponseCode
- : 0;
+ Result.ErrorCode = Ex.GetInternalErrorCode() != 0 ? Ex.GetInternalErrorCode()
+ : Ex.GetHttpResponseCode() != HttpResponseCode::ImATeapot ? (int)Ex.GetHttpResponseCode()
+ : 0;
Result.Reason = fmt::format("Failed finalizing oplog container build to {}/{}/{}/{}. Reason: '{}'",
m_Url,
m_Namespace,
@@ -452,7 +454,9 @@ public:
private:
static int MakeErrorCode(const HttpClientError& Ex)
{
- return Ex.m_Error != 0 ? Ex.m_Error : Ex.m_ResponseCode != HttpResponseCode::ImATeapot ? (int)Ex.m_ResponseCode : 0;
+ return Ex.GetInternalErrorCode() != 0 ? Ex.GetInternalErrorCode()
+ : Ex.GetHttpResponseCode() != HttpResponseCode::ImATeapot ? (int)Ex.GetHttpResponseCode()
+ : 0;
}
std::unique_ptr<BuildStorage::Statistics> m_BuildStorageStats;
diff --git a/src/zenserver/projectstore/projectstore.cpp b/src/zenserver/projectstore/projectstore.cpp
index 262b35ea2..690f697d0 100644
--- a/src/zenserver/projectstore/projectstore.cpp
+++ b/src/zenserver/projectstore/projectstore.cpp
@@ -34,7 +34,6 @@
#include "zenremoteprojectstore.h"
ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/cpr.h>
#include <tsl/robin_set.h>
#include <xxh3.h>
ZEN_THIRD_PARTY_INCLUDES_END
@@ -192,7 +191,7 @@ namespace {
return {nullptr, "Missing service url"};
}
- std::string Url = cpr::util::urlDecode(std::string(CloudServiceUrl));
+ std::string Url = UrlDecode(CloudServiceUrl);
std::string_view Namespace = Cloud["namespace"sv].AsString();
if (Namespace.empty())
{
@@ -302,7 +301,7 @@ namespace {
return {nullptr, "Missing service url"};
}
- std::string Url = cpr::util::urlDecode(std::string(BuildsServiceUrl));
+ std::string Url = UrlDecode(BuildsServiceUrl);
std::string_view Namespace = Builds["namespace"sv].AsString();
if (Namespace.empty())
{
diff --git a/src/zenserver/upstream/zen.cpp b/src/zenserver/upstream/zen.cpp
index 7494ae379..25fd3a3bb 100644
--- a/src/zenserver/upstream/zen.cpp
+++ b/src/zenserver/upstream/zen.cpp
@@ -9,44 +9,18 @@
#include <zencore/session.h>
#include <zencore/stream.h>
#include <zenhttp/formatters.h>
+#include <zenhttp/httpclient.h>
#include <zenhttp/httpcommon.h>
#include <zenhttp/packageformat.h>
#include <zenstore/cache/structuredcachestore.h>
#include "diag/logging.h"
-ZEN_THIRD_PARTY_INCLUDES_START
-#include <cpr/cpr.h>
-ZEN_THIRD_PARTY_INCLUDES_END
-
#include <xxhash.h>
#include <gsl/gsl-lite.hpp>
namespace zen {
-namespace detail {
- struct ZenCacheSessionState
- {
- ZenCacheSessionState(ZenStructuredCacheClient& Client) : OwnerClient(Client) {}
- ~ZenCacheSessionState() {}
-
- void Reset(std::chrono::milliseconds ConnectTimeout, std::chrono::milliseconds Timeout)
- {
- Session.SetBody({});
- Session.SetHeader({});
- Session.SetConnectTimeout(ConnectTimeout);
- Session.SetTimeout(Timeout);
- }
-
- cpr::Session& GetSession() { return Session; }
-
- private:
- ZenStructuredCacheClient& OwnerClient;
- cpr::Session Session;
- };
-
-} // namespace detail
-
//////////////////////////////////////////////////////////////////////////
ZenStructuredCacheClient::ZenStructuredCacheClient(const ZenStructuredCacheClientOptions& Options)
@@ -59,39 +33,6 @@ ZenStructuredCacheClient::ZenStructuredCacheClient(const ZenStructuredCacheClien
ZenStructuredCacheClient::~ZenStructuredCacheClient()
{
- RwLock::ExclusiveLockScope _(m_SessionStateLock);
- for (auto& CacheEntry : m_SessionStateCache)
- {
- delete CacheEntry;
- }
-}
-
-detail::ZenCacheSessionState*
-ZenStructuredCacheClient::AllocSessionState()
-{
- detail::ZenCacheSessionState* State = nullptr;
-
- if (RwLock::ExclusiveLockScope _(m_SessionStateLock); !m_SessionStateCache.empty())
- {
- State = m_SessionStateCache.front();
- m_SessionStateCache.pop_front();
- }
-
- if (State == nullptr)
- {
- State = new detail::ZenCacheSessionState(*this);
- }
-
- State->Reset(m_ConnectTimeout, m_Timeout);
-
- return State;
-}
-
-void
-ZenStructuredCacheClient::FreeSessionState(detail::ZenCacheSessionState* State)
-{
- RwLock::ExclusiveLockScope _(m_SessionStateLock);
- m_SessionStateCache.push_front(State);
}
//////////////////////////////////////////////////////////////////////////
@@ -102,59 +43,54 @@ ZenStructuredCacheSession::ZenStructuredCacheSession(Ref<ZenStructuredCacheClien
: m_Log(OuterClient->Log())
, m_Client(std::move(OuterClient))
{
- m_SessionState = m_Client->AllocSessionState();
}
ZenStructuredCacheSession::~ZenStructuredCacheSession()
{
- m_Client->FreeSessionState(m_SessionState);
}
ZenCacheResult
ZenStructuredCacheSession::CheckHealth()
{
- ExtendableStringBuilder<256> Uri;
- Uri << m_Client->ServiceUrl() << "/health/check";
+ HttpClient Http{m_Client->ServiceUrl()};
- cpr::Session& Session = m_SessionState->GetSession();
- Session.SetOption(cpr::Url{Uri.c_str()});
- cpr::Response Response = Session.Get();
+ HttpClient::Response Response = Http.Get("/health/check"sv);
- if (Response.error)
+ if (auto& Error = Response.Error; Error)
{
- return {.ErrorCode = static_cast<int32_t>(Response.error.code), .Reason = std::move(Response.error.message)};
+ return {.ErrorCode = static_cast<int32_t>(Error->ErrorCode), .Reason = std::move(Error->ErrorMessage)};
}
- return {.Bytes = Response.downloaded_bytes, .ElapsedSeconds = Response.elapsed, .Success = Response.status_code == 200};
+ return {.Bytes = Response.DownloadedBytes,
+ .ElapsedSeconds = Response.ElapsedSeconds,
+ .Success = Response.StatusCode == HttpResponseCode::OK};
}
ZenCacheResult
ZenStructuredCacheSession::GetCacheRecord(std::string_view Namespace, std::string_view BucketId, const IoHash& Key, ZenContentType Type)
{
+ HttpClient Http{m_Client->ServiceUrl()};
+
ExtendableStringBuilder<256> Uri;
- Uri << m_Client->ServiceUrl() << "/z$/";
+ Uri << "/z$/";
if (Namespace != ZenCacheStore::DefaultNamespace)
{
Uri << Namespace << "/";
}
Uri << BucketId << "/" << Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
-
- Session.SetOption(cpr::Url{Uri.c_str()});
- Session.SetHeader(cpr::Header{{"Accept", std::string{MapContentTypeToString(Type)}}});
- cpr::Response Response = Session.Get();
+ HttpClient::Response Response = Http.Get(Uri, {{"Accept", std::string{MapContentTypeToString(Type)}}});
ZEN_DEBUG("GET {}", Response);
- if (Response.error)
+ if (auto& Error = Response.Error; Error)
{
- return {.ErrorCode = static_cast<int32_t>(Response.error.code), .Reason = std::move(Response.error.message)};
+ return {.ErrorCode = static_cast<int32_t>(Error->ErrorCode), .Reason = std::move(Error->ErrorMessage)};
}
- const bool Success = Response.status_code == 200;
- const IoBuffer Buffer = Success ? IoBufferBuilder::MakeCloneFromMemory(Response.text.data(), Response.text.size()) : IoBuffer();
+ const bool Success = Response.StatusCode == HttpResponseCode::OK;
+ const IoBuffer Buffer = Success ? Response.ResponsePayload : IoBuffer{};
- return {.Response = Buffer, .Bytes = Response.downloaded_bytes, .ElapsedSeconds = Response.elapsed, .Success = Success};
+ return {.Response = Buffer, .Bytes = Response.DownloadedBytes, .ElapsedSeconds = Response.ElapsedSeconds, .Success = Success};
}
ZenCacheResult
@@ -163,35 +99,28 @@ ZenStructuredCacheSession::GetCacheChunk(std::string_view Namespace,
const IoHash& Key,
const IoHash& ValueContentId)
{
+ HttpClient Http{m_Client->ServiceUrl()};
+
ExtendableStringBuilder<256> Uri;
- Uri << m_Client->ServiceUrl() << "/z$/";
+ Uri << "/z$/";
if (Namespace != ZenCacheStore::DefaultNamespace)
{
Uri << Namespace << "/";
}
Uri << BucketId << "/" << Key.ToHexString() << "/" << ValueContentId.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
-
- Session.SetOption(cpr::Url{Uri.c_str()});
- Session.SetHeader(cpr::Header{{"Accept", "application/x-ue-comp"}});
-
- cpr::Response Response = Session.Get();
+ HttpClient::Response Response = Http.Get(Uri, {{"Accept", "application/x-ue-comp"}});
ZEN_DEBUG("GET {}", Response);
- if (Response.error)
+ if (auto& Error = Response.Error; Error)
{
- return {.ErrorCode = static_cast<int32_t>(Response.error.code), .Reason = std::move(Response.error.message)};
+ return {.ErrorCode = static_cast<int32_t>(Error->ErrorCode), .Reason = std::move(Error->ErrorMessage)};
}
- const bool Success = Response.status_code == 200;
- const IoBuffer Buffer = Success ? IoBufferBuilder::MakeCloneFromMemory(Response.text.data(), Response.text.size()) : IoBuffer();
+ const bool Success = Response.StatusCode == HttpResponseCode::OK;
+ const IoBuffer Buffer = Success ? Response.ResponsePayload : IoBuffer{};
- return {.Response = Buffer,
- .Bytes = Response.downloaded_bytes,
- .ElapsedSeconds = Response.elapsed,
- .Reason = Response.reason,
- .Success = Success};
+ return {.Response = Buffer, .Bytes = Response.DownloadedBytes, .ElapsedSeconds = Response.ElapsedSeconds, .Success = Success};
}
ZenCacheResult
@@ -201,33 +130,29 @@ ZenStructuredCacheSession::PutCacheRecord(std::string_view Namespace,
IoBuffer Value,
ZenContentType Type)
{
+ HttpClient Http{m_Client->ServiceUrl()};
+
ExtendableStringBuilder<256> Uri;
- Uri << m_Client->ServiceUrl() << "/z$/";
+ Uri << "/z$/";
if (Namespace != ZenCacheStore::DefaultNamespace)
{
Uri << Namespace << "/";
}
Uri << BucketId << "/" << Key.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
-
- Session.SetOption(cpr::Url{Uri.c_str()});
- Session.SetHeader(cpr::Header{{"Content-Type",
- Type == ZenContentType::kCbPackage ? "application/x-ue-cbpkg"
- : Type == ZenContentType::kCbObject ? "application/x-ue-cb"
- : "application/octet-stream"}});
- Session.SetBody(cpr::Body{static_cast<const char*>(Value.Data()), Value.Size()});
+ Value.SetContentType(Type);
- cpr::Response Response = Session.Put();
+ HttpClient::Response Response = Http.Put(Uri, Value);
ZEN_DEBUG("PUT {}", Response);
- if (Response.error)
+ if (auto& Error = Response.Error; Error)
{
- return {.ErrorCode = static_cast<int32_t>(Response.error.code), .Reason = std::move(Response.error.message)};
+ return {.ErrorCode = static_cast<int32_t>(Error->ErrorCode), .Reason = std::move(Error->ErrorMessage)};
}
- const bool Success = Response.status_code == 200 || Response.status_code == 201;
- return {.Bytes = Response.uploaded_bytes, .ElapsedSeconds = Response.elapsed, .Reason = Response.reason, .Success = Success};
+ const bool Success = Response.StatusCode == HttpResponseCode::OK || Response.StatusCode == HttpResponseCode::Created;
+
+ return {.Bytes = Response.DownloadedBytes, .ElapsedSeconds = Response.ElapsedSeconds, .Success = Success};
}
ZenCacheResult
@@ -237,94 +162,89 @@ ZenStructuredCacheSession::PutCacheValue(std::string_view Namespace,
const IoHash& ValueContentId,
IoBuffer Payload)
{
+ HttpClient Http{m_Client->ServiceUrl()};
+
ExtendableStringBuilder<256> Uri;
- Uri << m_Client->ServiceUrl() << "/z$/";
+ Uri << "/z$/";
if (Namespace != ZenCacheStore::DefaultNamespace)
{
Uri << Namespace << "/";
}
Uri << BucketId << "/" << Key.ToHexString() << "/" << ValueContentId.ToHexString();
- cpr::Session& Session = m_SessionState->GetSession();
-
- Session.SetOption(cpr::Url{Uri.c_str()});
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-comp"}});
- Session.SetBody(cpr::Body{static_cast<const char*>(Payload.Data()), Payload.Size()});
+ Payload.SetContentType(HttpContentType::kCompressedBinary);
- cpr::Response Response = Session.Put();
+ HttpClient::Response Response = Http.Put(Uri, Payload);
ZEN_DEBUG("PUT {}", Response);
- if (Response.error)
+ if (auto& Error = Response.Error; Error)
{
- return {.ErrorCode = static_cast<int32_t>(Response.error.code), .Reason = std::move(Response.error.message)};
+ return {.ErrorCode = static_cast<int32_t>(Error->ErrorCode), .Reason = std::move(Error->ErrorMessage)};
}
- const bool Success = Response.status_code == 200 || Response.status_code == 201;
- return {.Bytes = Response.uploaded_bytes, .ElapsedSeconds = Response.elapsed, .Reason = Response.reason, .Success = Success};
+ const bool Success = Response.StatusCode == HttpResponseCode::OK || Response.StatusCode == HttpResponseCode::Created;
+
+ return {.Bytes = Response.DownloadedBytes, .ElapsedSeconds = Response.ElapsedSeconds, .Success = Success};
}
ZenCacheResult
ZenStructuredCacheSession::InvokeRpc(const CbObjectView& Request)
{
+ HttpClient Http{m_Client->ServiceUrl()};
+
ExtendableStringBuilder<256> Uri;
- Uri << m_Client->ServiceUrl() << "/z$/$rpc";
+ Uri << "/z$/$rpc";
- BinaryWriter Body;
- Request.CopyTo(Body);
+ // TODO: this seems redundant, we should be able to send the data more directly, without the BinaryWriter
- cpr::Session& Session = m_SessionState->GetSession();
+ BinaryWriter BodyWriter;
+ Request.CopyTo(BodyWriter);
- Session.SetOption(cpr::Url{Uri.c_str()});
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cb"}, {"Accept", "application/x-ue-cbpkg"}});
- Session.SetBody(cpr::Body{reinterpret_cast<const char*>(Body.GetData()), Body.GetSize()});
+ IoBuffer Body{IoBuffer::Wrap, BodyWriter.GetData(), BodyWriter.GetSize()};
+ Body.SetContentType(HttpContentType::kCbObject);
- cpr::Response Response = Session.Post();
+ HttpClient::Response Response = Http.Post(Uri, Body, {{"Accept", "application/x-ue-cbpkg"}});
ZEN_DEBUG("POST {}", Response);
- if (Response.error)
+ if (auto& Error = Response.Error; Error)
{
- return {.ErrorCode = static_cast<int32_t>(Response.error.code), .Reason = std::move(Response.error.message)};
+ return {.ErrorCode = static_cast<int32_t>(Error->ErrorCode), .Reason = std::move(Error->ErrorMessage)};
}
- const bool Success = Response.status_code == 200;
- const IoBuffer Buffer = Success ? IoBufferBuilder::MakeCloneFromMemory(Response.text.data(), Response.text.size()) : IoBuffer();
+ const bool Success = Response.StatusCode == HttpResponseCode::OK;
+ const IoBuffer Buffer = Success ? Response.ResponsePayload : IoBuffer{};
return {.Response = std::move(Buffer),
- .Bytes = Response.uploaded_bytes,
- .ElapsedSeconds = Response.elapsed,
- .Reason = Response.reason,
+ .Bytes = Response.DownloadedBytes,
+ .ElapsedSeconds = Response.ElapsedSeconds,
.Success = Success};
}
ZenCacheResult
ZenStructuredCacheSession::InvokeRpc(const CbPackage& Request)
{
- ExtendableStringBuilder<256> Uri;
- Uri << m_Client->ServiceUrl() << "/z$/$rpc";
+ HttpClient Http{m_Client->ServiceUrl()};
- SharedBuffer Message = FormatPackageMessageBuffer(Request).Flatten();
-
- cpr::Session& Session = m_SessionState->GetSession();
+ ExtendableStringBuilder<256> Uri;
+ Uri << "/z$/$rpc";
- Session.SetOption(cpr::Url{Uri.c_str()});
- Session.SetHeader(cpr::Header{{"Content-Type", "application/x-ue-cbpkg"}, {"Accept", "application/x-ue-cbpkg"}});
- Session.SetBody(cpr::Body{reinterpret_cast<const char*>(Message.GetData()), Message.GetSize()});
+ IoBuffer Message = FormatPackageMessageBuffer(Request).Flatten().AsIoBuffer();
+ Message.SetContentType(HttpContentType::kCbPackage);
- cpr::Response Response = Session.Post();
+ HttpClient::Response Response = Http.Post(Uri, Message, {{"Accept", "application/x-ue-cbpkg"}});
ZEN_DEBUG("POST {}", Response);
- if (Response.error)
+ if (auto& Error = Response.Error; Error)
{
- return {.ErrorCode = static_cast<int32_t>(Response.error.code), .Reason = std::move(Response.error.message)};
+ return {.ErrorCode = static_cast<int32_t>(Error->ErrorCode), .Reason = std::move(Error->ErrorMessage)};
}
- const bool Success = Response.status_code == 200;
- const IoBuffer Buffer = Success ? IoBufferBuilder::MakeCloneFromMemory(Response.text.data(), Response.text.size()) : IoBuffer();
+ const bool Success = Response.StatusCode == HttpResponseCode::OK;
+ const IoBuffer Buffer = Success ? Response.ResponsePayload : IoBuffer{};
return {.Response = std::move(Buffer),
- .Bytes = Response.uploaded_bytes,
- .ElapsedSeconds = Response.elapsed,
- .Reason = Response.reason,
+ .Bytes = Response.DownloadedBytes,
+ .ElapsedSeconds = Response.ElapsedSeconds,
.Success = Success};
}
diff --git a/src/zenserver/upstream/zen.h b/src/zenserver/upstream/zen.h
index 78b6bc589..6321b46b1 100644
--- a/src/zenserver/upstream/zen.h
+++ b/src/zenserver/upstream/zen.h
@@ -6,17 +6,10 @@
#include <zencore/iohash.h>
#include <zencore/logging.h>
#include <zencore/memoryview.h>
-#include <zencore/thread.h>
#include <zencore/uid.h>
#include <zencore/zencore.h>
-ZEN_THIRD_PARTY_INCLUDES_START
-#include <tsl/robin_map.h>
-#include <asio.hpp>
-ZEN_THIRD_PARTY_INCLUDES_END
-
#include <chrono>
-#include <list>
struct ZenCacheValue;
@@ -29,10 +22,6 @@ class ZenStructuredCacheClient;
//////////////////////////////////////////////////////////////////////////
-namespace detail {
- struct ZenCacheSessionState;
-}
-
struct ZenCacheResult
{
IoBuffer Response;
@@ -85,7 +74,6 @@ private:
LoggerRef m_Log;
Ref<ZenStructuredCacheClient> m_Client;
- detail::ZenCacheSessionState* m_SessionState;
};
/** Zen Structured Cache client
@@ -109,12 +97,6 @@ private:
std::chrono::milliseconds m_ConnectTimeout;
std::chrono::milliseconds m_Timeout;
- RwLock m_SessionStateLock;
- std::list<detail::ZenCacheSessionState*> m_SessionStateCache;
-
- detail::ZenCacheSessionState* AllocSessionState();
- void FreeSessionState(detail::ZenCacheSessionState*);
-
friend class ZenStructuredCacheSession;
};
diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp
index 3f71c1357..36211263a 100644
--- a/src/zenutil/zenserverprocess.cpp
+++ b/src/zenutil/zenserverprocess.cpp
@@ -656,7 +656,7 @@ ZenServerInstance::Shutdown()
}
else if (Ec)
{
- ZEN_WARN("Terminating zenserver proces as we failed to signal zenserver process {} ({}) to shut down. Reason: '{}'",
+ ZEN_WARN("Terminating zenserver process as we failed to signal zenserver process {} ({}) to shut down. Reason: '{}'",
m_Name,
m_Process.Pid(),
Ec.message());