From 81dac5b9548d5f300d3a504b0db8a3623a65d2e5 Mon Sep 17 00:00:00 2001 From: Zousar Shaker Date: Thu, 25 Nov 2021 14:24:37 -0700 Subject: Fix handling of packages/offers in asio mode to match http.sys mode. --- zenhttp/httpserver.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'zenhttp/httpserver.cpp') diff --git a/zenhttp/httpserver.cpp b/zenhttp/httpserver.cpp index f40836c4a..dcf0a2765 100644 --- a/zenhttp/httpserver.cpp +++ b/zenhttp/httpserver.cpp @@ -7,6 +7,7 @@ #include "httpsys.h" #include +#include #include #include #include @@ -657,6 +658,84 @@ TEST_CASE("http.common") } } +bool +HandlePackageOffers(HttpService& Service, HttpServerRequest& Request, Ref& PackageHandlerRef) +{ + if (Request.RequestVerb() == HttpVerb::kPost) + { + if (Request.RequestContentType() == HttpContentType::kCbPackageOffer) + { + // The client is presenting us with a package attachments offer, we need + // to filter it down to the list of attachments we need them to send in + // the follow-up request + + PackageHandlerRef = Service.HandlePackageRequest(Request); + + if (PackageHandlerRef) + { + CbObject OfferMessage = LoadCompactBinaryObject(Request.ReadPayload()); + + std::vector OfferCids; + + for (auto& CidEntry : OfferMessage["offer"]) + { + if (!CidEntry.IsHash()) + { + // Should yield bad request response? + + ZEN_WARN("found invalid entry in offer"); + + continue; + } + + OfferCids.push_back(CidEntry.AsHash()); + } + + ZEN_TRACE("request #{} -> filtering offer of {} entries", Request.RequestId(), OfferCids.size()); + + PackageHandlerRef->FilterOffer(OfferCids); + + ZEN_TRACE("request #{} -> filtered to {} entries", Request.RequestId(), OfferCids.size()); + + CbObjectWriter ResponseWriter; + ResponseWriter.BeginArray("need"); + + for (const IoHash& Cid : OfferCids) + { + ResponseWriter.AddHash(Cid); + } + + ResponseWriter.EndArray(); + + // Emit filter response + Request.WriteResponse(HttpResponseCode::OK, ResponseWriter.Save()); + return true; + } + } + else if (Request.RequestContentType() == HttpContentType::kCbPackage) + { + // Process chunks in package request + + PackageHandlerRef = Service.HandlePackageRequest(Request); + + // TODO: this should really be done in a streaming fashion, currently this emulates + // the intended flow from an API perspective + + if (PackageHandlerRef) + { + PackageHandlerRef->OnRequestBegin(); + + auto CreateBuffer = [&](const IoHash& Cid, uint64_t Size) -> IoBuffer { return PackageHandlerRef->CreateTarget(Cid, Size); }; + + CbPackage Package = ParsePackageMessage(Request.ReadPayload(), CreateBuffer); + + PackageHandlerRef->OnRequestComplete(); + } + } + } + return false; +} + void http_forcelink() { -- cgit v1.2.3