// Copyright Epic Games, Inc. All Rights Reserved. #include #include #include #include #include #include namespace zen { HttpClient::HttpClient(std::string_view BaseUri) : m_BaseUri(BaseUri) { } HttpClient::~HttpClient() { } void HttpClient::TransactPackage(std::string_view Url, CbPackage Package) { cpr::Session Sess; Sess.SetUrl(m_BaseUri + std::string(Url)); // First, list of offered chunks for filtering on the server end std::vector AttachmentsToSend; std::span Attachments = Package.GetAttachments(); if (Attachments.empty() == false) { CbObjectWriter Writer; Writer.BeginArray("offer"); for (const CbAttachment& Attachment : Attachments) { IoHash Hash = Attachment.GetHash(); Writer.AddHash(Hash); } Writer.EndArray(); MemoryOutStream MemOut; BinaryWriter MemWriter(MemOut); Writer.Save(MemWriter); Sess.SetHeader({{"Content-Type", "application/x-ue-offer"}, {"UE-Session", "123456789012345678901234"}, {"UE-Request", "1"}}); Sess.SetBody(cpr::Body{(const char*)MemOut.Data(), MemOut.Size()}); cpr::Response FilterResponse = Sess.Post(); if (FilterResponse.status_code == 200) { IoBuffer ResponseBuffer(IoBuffer::Wrap, FilterResponse.text.data(), FilterResponse.text.size()); CbObject ResponseObject = LoadCompactBinaryObject(ResponseBuffer); for (auto& Entry : ResponseObject["need"]) { ZEN_ASSERT(Entry.IsHash()); AttachmentsToSend.push_back(Entry.AsHash()); } } } CbPackage SendPackage; SendPackage.SetObject(Package.GetObject(), Package.GetObjectHash()); ; for (const IoHash& AttachmentCid : AttachmentsToSend) { const CbAttachment* Attachment = Package.FindAttachment(AttachmentCid); if (Attachment) { SendPackage.AddAttachment(*Attachment); } else { // This should be an error -- server asked to have something we can't find } } { MemoryOutStream MemOut; BinaryWriter MemWriter(MemOut); SendPackage.Save(MemWriter); Sess.SetHeader({{"Content-Type", "application/x-ue-cbpkg"}, {"UE-Session", "123456789012345678901234"}, {"UE-Request", "1"}}); Sess.SetBody(cpr::Body{(const char*)MemOut.Data(), MemOut.Size()}); cpr::Response FilterResponse = Sess.Post(); } } ////////////////////////////////////////////////////////////////////////// TEST_CASE("httpclient") { using namespace std::literals; SUBCASE("client") {} } void httpclient_forcelink() { } } // namespace zen