aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZousar Shaker <[email protected]>2021-11-25 14:24:37 -0700
committerZousar Shaker <[email protected]>2021-11-25 14:24:37 -0700
commit81dac5b9548d5f300d3a504b0db8a3623a65d2e5 (patch)
tree6e3fb718b79d4c6dcfcea0cc89368b2283d1e315
parentFix asio request routing so that a url of "/cas" will route to the service fo... (diff)
downloadzen-81dac5b9548d5f300d3a504b0db8a3623a65d2e5.tar.xz
zen-81dac5b9548d5f300d3a504b0db8a3623a65d2e5.zip
Fix handling of packages/offers in asio mode to match http.sys mode.
-rw-r--r--zenhttp/httpasio.cpp7
-rw-r--r--zenhttp/httpserver.cpp79
-rw-r--r--zenhttp/httpsys.cpp79
-rw-r--r--zenhttp/include/zenhttp/httpserver.h2
4 files changed, 91 insertions, 76 deletions
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp
index ad0f7fefa..c9432d197 100644
--- a/zenhttp/httpasio.cpp
+++ b/zenhttp/httpasio.cpp
@@ -318,6 +318,7 @@ private:
std::unique_ptr<asio::ip::tcp::socket> m_Socket;
std::atomic<uint32_t> m_RequestCounter{0};
uint32_t m_ConnectionId = 0;
+ Ref<IHttpPackageHandler> m_PackageHandler;
RwLock m_ResponsesLock;
std::deque<std::unique_ptr<HttpResponse>> m_Responses;
@@ -485,9 +486,13 @@ HttpServerConnection::HandleRequest()
{
HttpAsioServerRequest Request(m_RequestData, *Service, m_RequestData.Body());
+
ZEN_TRACE("handle request, connection '{}' request '{}'", m_ConnectionId, m_RequestCounter.load(std::memory_order_relaxed));
- Service->HandleRequest(Request);
+ if (!HandlePackageOffers(*Service, Request, m_PackageHandler))
+ {
+ Service->HandleRequest(Request);
+ }
if (std::unique_ptr<HttpResponse> Response = std::move(Request.m_Response))
{
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 <zencore/compactbinary.h>
+#include <zencore/compactbinarybuilder.h>
#include <zencore/compactbinarypackage.h>
#include <zencore/iobuffer.h>
#include <zencore/logging.h>
@@ -657,6 +658,84 @@ TEST_CASE("http.common")
}
}
+bool
+HandlePackageOffers(HttpService& Service, HttpServerRequest& Request, Ref<IHttpPackageHandler>& 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<IoHash> 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()
{
diff --git a/zenhttp/httpsys.cpp b/zenhttp/httpsys.cpp
index cdf9e0a39..15d7a9700 100644
--- a/zenhttp/httpsys.cpp
+++ b/zenhttp/httpsys.cpp
@@ -1131,83 +1131,12 @@ HttpSysTransaction::InvokeRequestHandler(HttpService& Service, IoBuffer Payload)
{
HttpSysServerRequest& ThisRequest = m_HandlerRequest.emplace(*this, Service, Payload);
- if (ThisRequest.RequestVerb() == HttpVerb::kPost)
- {
- if (ThisRequest.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
-
- m_PackageHandler = Service.HandlePackageRequest(ThisRequest);
-
- if (m_PackageHandler)
- {
- CbObject OfferMessage = LoadCompactBinaryObject(Payload);
-
- std::vector<IoHash> 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", ThisRequest.RequestId(), OfferCids.size());
-
- m_PackageHandler->FilterOffer(OfferCids);
-
- ZEN_TRACE("request #{} -> filtered to {} entries", ThisRequest.RequestId(), OfferCids.size());
-
- CbObjectWriter ResponseWriter;
- ResponseWriter.BeginArray("need");
-
- for (const IoHash& Cid : OfferCids)
- {
- ResponseWriter.AddHash(Cid);
- }
-
- ResponseWriter.EndArray();
-
- // Emit filter response
- ThisRequest.WriteResponse(HttpResponseCode::OK, ResponseWriter.Save());
-
- return ThisRequest;
- }
- }
- else if (ThisRequest.RequestContentType() == HttpContentType::kCbPackage)
- {
- // Process chunks in package request
-
- m_PackageHandler = Service.HandlePackageRequest(ThisRequest);
-
- // TODO: this should really be done in a streaming fashion, currently this emulates
- // the intended flow from an API perspective
-
- if (m_PackageHandler)
- {
- m_PackageHandler->OnRequestBegin();
-
- auto CreateBuffer = [&](const IoHash& Cid, uint64_t Size) -> IoBuffer { return m_PackageHandler->CreateTarget(Cid, Size); };
-
- CbPackage Package = ParsePackageMessage(ThisRequest.ReadPayload(), CreateBuffer);
-
- m_PackageHandler->OnRequestComplete();
- }
- }
- }
-
// Default request handling
- Service.HandleRequest(ThisRequest);
+ if (!HandlePackageOffers(Service, ThisRequest, m_PackageHandler))
+ {
+ Service.HandleRequest(ThisRequest);
+ }
return ThisRequest;
}
diff --git a/zenhttp/include/zenhttp/httpserver.h b/zenhttp/include/zenhttp/httpserver.h
index 93ba452c7..088028081 100644
--- a/zenhttp/include/zenhttp/httpserver.h
+++ b/zenhttp/include/zenhttp/httpserver.h
@@ -269,6 +269,8 @@ private:
std::unordered_map<std::string, std::string> m_PatternMap;
};
+bool HandlePackageOffers(HttpService& Service, HttpServerRequest& Request, Ref<IHttpPackageHandler>& PackageHandlerRef);
+
void http_forcelink(); // internal
} // namespace zen