diff options
| author | Stefan Boberg <[email protected]> | 2021-09-13 12:24:59 +0200 |
|---|---|---|
| committer | Stefan Boberg <[email protected]> | 2021-09-13 12:24:59 +0200 |
| commit | 4e2649977d034b913413d2cb35d4a88afc30393f (patch) | |
| tree | 9258d4329a2217d581aaedfb251a655692987d4d | |
| parent | Added Ref<>::Get to work around issue casting a pointer to a derived type to ... (diff) | |
| download | zen-4e2649977d034b913413d2cb35d4a88afc30393f.tar.xz zen-4e2649977d034b913413d2cb35d4a88afc30393f.zip | |
Changed interface for httpServerRequest::SessionId()/RequestId() so they share storage and lazy eval logic
They now call into ParseSessionId()/ParseRequestId() when required
Eliminates redundant logic in derived implementations
Also moved package transport code into httpshared.(cpp|h) for easier sharing with client code
Added some I/O error reporting in http.sys related code
Changed IHttpPackageHandler interface to support partially updated handling flow
| -rw-r--r-- | zenhttp/httpserver.cpp | 136 | ||||
| -rw-r--r-- | zenhttp/httpshared.cpp | 116 | ||||
| -rw-r--r-- | zenhttp/httpshared.h | 32 | ||||
| -rw-r--r-- | zenhttp/httpsys.cpp | 139 | ||||
| -rw-r--r-- | zenhttp/include/zenhttp/httpserver.h | 13 | ||||
| -rw-r--r-- | zenhttp/zenhttp.vcxproj | 2 | ||||
| -rw-r--r-- | zenhttp/zenhttp.vcxproj.filters | 2 | ||||
| -rw-r--r-- | zenserver/testing/httptest.cpp | 38 | ||||
| -rw-r--r-- | zenserver/testing/httptest.h | 17 |
9 files changed, 307 insertions, 188 deletions
diff --git a/zenhttp/httpserver.cpp b/zenhttp/httpserver.cpp index 39bec435d..50141167d 100644 --- a/zenhttp/httpserver.cpp +++ b/zenhttp/httpserver.cpp @@ -3,6 +3,7 @@ #include <zenhttp/httpserver.h> #include "httpnull.h" +#include "httpshared.h" #include "httpsys.h" #include "httpuws.h" @@ -262,72 +263,10 @@ HttpServerRequest::~HttpServerRequest() { } -struct CbPackageHeader -{ - uint32_t HeaderMagic; - uint32_t AttachmentCount; - uint32_t Reserved1; - uint32_t Reserved2; -}; - -static constinit uint32_t kCbPkgMagic = 0xaa77aacc; - -struct CbAttachmentEntry -{ - uint64_t AttachmentSize; - uint32_t Reserved1; - IoHash AttachmentHash; -}; - void HttpServerRequest::WriteResponse(HttpResponseCode ResponseCode, CbPackage Data) { - const std::span<const CbAttachment>& Attachments = Data.GetAttachments(); - - std::vector<IoBuffer> ResponseBuffers; - ResponseBuffers.reserve(3 + Attachments.size()); // TODO: may want to use an additional fudge factor here to avoid growing since each - // attachment is likely to consist of several buffers - - uint64_t TotalAttachmentsSize = 0; - - // Fixed size header - - CbPackageHeader Hdr{.HeaderMagic = kCbPkgMagic, .AttachmentCount = gsl::narrow<uint32_t>(Attachments.size())}; - - ResponseBuffers.push_back(IoBufferBuilder::MakeCloneFromMemory(&Hdr, sizeof Hdr)); - - // Attachment metadata array - - IoBuffer AttachmentMetadataBuffer = IoBuffer{sizeof(CbAttachmentEntry) * (Attachments.size() + /* root */ 1)}; - - CbAttachmentEntry* AttachmentInfo = reinterpret_cast<CbAttachmentEntry*>(AttachmentMetadataBuffer.MutableData()); - - ResponseBuffers.push_back(AttachmentMetadataBuffer); // Attachment metadata - - // Root object - - IoBuffer RootIoBuffer = Data.GetObject().GetBuffer().AsIoBuffer(); - ResponseBuffers.push_back(RootIoBuffer); // Root object - - *AttachmentInfo++ = {.AttachmentSize = RootIoBuffer.Size(), .AttachmentHash = Data.GetObjectHash()}; - - // Attachment payloads - - for (const CbAttachment& Attachment : Attachments) - { - CompressedBuffer AttachmentBuffer = Attachment.AsCompressedBinary(); - CompositeBuffer Compressed = AttachmentBuffer.GetCompressed(); - - *AttachmentInfo++ = {.AttachmentSize = AttachmentBuffer.GetCompressedSize(), - .AttachmentHash = IoHash::FromBLAKE3(AttachmentBuffer.GetRawHash())}; - - for (const SharedBuffer& Segment : Compressed.GetSegments()) - { - ResponseBuffers.push_back(Segment.AsIoBuffer()); - TotalAttachmentsSize += Segment.GetSize(); - } - } - + std::vector<IoBuffer> ResponseBuffers = FormatPackageMessage(Data); return WriteResponse(ResponseCode, HttpContentType::kCbPackage, ResponseBuffers); } @@ -400,13 +339,27 @@ HttpServerRequest::GetQueryParams() Oid HttpServerRequest::SessionId() const { - return {}; + if (m_Flags & kHaveSessionId) + { + return m_SessionId; + } + + m_SessionId = ParseSessionId(); + m_Flags |= kHaveSessionId; + return m_SessionId; } uint32_t HttpServerRequest::RequestId() const { - return {}; + if (m_Flags & kHaveRequestId) + { + return m_RequestId; + } + + m_RequestId = ParseRequestId(); + m_Flags |= kHaveRequestId; + return m_RequestId; } CbObject @@ -418,62 +371,19 @@ HttpServerRequest::ReadPayloadObject() { return LoadCompactBinaryObject(std::move(Payload)); } - else - { - return {}; - } + + return {}; } CbPackage HttpServerRequest::ReadPayloadPackage() { - // TODO: this should not read into a contiguous buffer! - - IoBuffer Payload = ReadPayload(); - MemoryInStream InStream(Payload); - BinaryReader Reader(InStream); - - if (!Payload) - { - return {}; - } - - CbPackage Package; - - CbPackageHeader Hdr; - Reader.Read(&Hdr, sizeof Hdr); - - if (Hdr.HeaderMagic != kCbPkgMagic) - { - // report error - return {}; - } - - uint32_t ChunkCount = Hdr.AttachmentCount + 1; - - std::unique_ptr<CbAttachmentEntry[]> AttachmentEntries{new CbAttachmentEntry[ChunkCount]}; - - Reader.Read(AttachmentEntries.get(), sizeof(CbAttachmentEntry) * ChunkCount); - - for (uint32_t i = 0; i < ChunkCount; ++i) + if (IoBuffer Payload = ReadPayload()) { - const uint64_t AttachmentSize = AttachmentEntries[i].AttachmentSize; - IoBuffer AttachmentBuffer{AttachmentSize}; - Reader.Read(AttachmentBuffer.MutableData(), AttachmentSize); - CompressedBuffer CompBuf(CompressedBuffer::FromCompressed(SharedBuffer(AttachmentBuffer))); - - if (i == 0) - { - Package.SetObject(LoadCompactBinaryObject(CompBuf)); - } - else - { - CbAttachment Attachment(CompBuf); - Package.AddAttachment(Attachment); - } + return ParsePackageMessage(Payload); } - return Package; + return {}; } ////////////////////////////////////////////////////////////////////////// diff --git a/zenhttp/httpshared.cpp b/zenhttp/httpshared.cpp new file mode 100644 index 000000000..f11f91fae --- /dev/null +++ b/zenhttp/httpshared.cpp @@ -0,0 +1,116 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "httpshared.h" + +#include <zencore/compactbinarypackage.h> +#include <zencore/iobuffer.h> +#include <zencore/iohash.h> +#include <zencore/stream.h> + +#include <span> +#include <vector> + +namespace zen { + +std::vector<IoBuffer> +FormatPackageMessage(const CbPackage& Data) +{ + const std::span<const CbAttachment>& Attachments = Data.GetAttachments(); + + std::vector<IoBuffer> ResponseBuffers; + ResponseBuffers.reserve(3 + Attachments.size()); // TODO: may want to use an additional fudge factor here to avoid growing since each + // attachment is likely to consist of several buffers + + uint64_t TotalAttachmentsSize = 0; + + // Fixed size header + + CbPackageHeader Hdr{.HeaderMagic = kCbPkgMagic, .AttachmentCount = gsl::narrow<uint32_t>(Attachments.size())}; + + ResponseBuffers.push_back(IoBufferBuilder::MakeCloneFromMemory(&Hdr, sizeof Hdr)); + + // Attachment metadata array + + IoBuffer AttachmentMetadataBuffer = IoBuffer{sizeof(CbAttachmentEntry) * (Attachments.size() + /* root */ 1)}; + + CbAttachmentEntry* AttachmentInfo = reinterpret_cast<CbAttachmentEntry*>(AttachmentMetadataBuffer.MutableData()); + + ResponseBuffers.push_back(AttachmentMetadataBuffer); // Attachment metadata + + // Root object + + IoBuffer RootIoBuffer = Data.GetObject().GetBuffer().AsIoBuffer(); + ResponseBuffers.push_back(RootIoBuffer); // Root object + + *AttachmentInfo++ = {.AttachmentSize = RootIoBuffer.Size(), .AttachmentHash = Data.GetObjectHash()}; + + // Attachment payloads + + for (const CbAttachment& Attachment : Attachments) + { + CompressedBuffer AttachmentBuffer = Attachment.AsCompressedBinary(); + CompositeBuffer Compressed = AttachmentBuffer.GetCompressed(); + + *AttachmentInfo++ = {.AttachmentSize = AttachmentBuffer.GetCompressedSize(), + .AttachmentHash = IoHash::FromBLAKE3(AttachmentBuffer.GetRawHash())}; + + for (const SharedBuffer& Segment : Compressed.GetSegments()) + { + ResponseBuffers.push_back(Segment.AsIoBuffer()); + TotalAttachmentsSize += Segment.GetSize(); + } + } + + return std::move(ResponseBuffers); +} + +CbPackage +ParsePackageMessage(IoBuffer Payload) +{ + MemoryInStream InStream(Payload); + BinaryReader Reader(InStream); + + if (!Payload) + { + return {}; + } + + CbPackage Package; + + CbPackageHeader Hdr; + Reader.Read(&Hdr, sizeof Hdr); + + if (Hdr.HeaderMagic != kCbPkgMagic) + { + // report error + return {}; + } + + uint32_t ChunkCount = Hdr.AttachmentCount + 1; + + std::unique_ptr<CbAttachmentEntry[]> AttachmentEntries{new CbAttachmentEntry[ChunkCount]}; + + Reader.Read(AttachmentEntries.get(), sizeof(CbAttachmentEntry) * ChunkCount); + + for (uint32_t i = 0; i < ChunkCount; ++i) + { + const uint64_t AttachmentSize = AttachmentEntries[i].AttachmentSize; + IoBuffer AttachmentBuffer{AttachmentSize}; + Reader.Read(AttachmentBuffer.MutableData(), AttachmentSize); + CompressedBuffer CompBuf(CompressedBuffer::FromCompressed(SharedBuffer(AttachmentBuffer))); + + if (i == 0) + { + Package.SetObject(LoadCompactBinaryObject(CompBuf)); + } + else + { + CbAttachment Attachment(CompBuf); + Package.AddAttachment(Attachment); + } + } + + return Package; +} + +} // namespace zen
\ No newline at end of file diff --git a/zenhttp/httpshared.h b/zenhttp/httpshared.h new file mode 100644 index 000000000..dbbebb348 --- /dev/null +++ b/zenhttp/httpshared.h @@ -0,0 +1,32 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zencore/iohash.h> + +namespace zen { + +class IoBuffer; +class CbPackage; + +struct CbPackageHeader +{ + uint32_t HeaderMagic; + uint32_t AttachmentCount; + uint32_t Reserved1; + uint32_t Reserved2; +}; + +static constinit uint32_t kCbPkgMagic = 0xaa77aacc; + +struct CbAttachmentEntry +{ + uint64_t AttachmentSize; + uint32_t Reserved1; + IoHash AttachmentHash; +}; + +std::vector<IoBuffer> FormatPackageMessage(const CbPackage& Data); +CbPackage ParsePackageMessage(IoBuffer Payload); + +} // namespace zen diff --git a/zenhttp/httpsys.cpp b/zenhttp/httpsys.cpp index f5f9d4249..cde371f2f 100644 --- a/zenhttp/httpsys.cpp +++ b/zenhttp/httpsys.cpp @@ -4,6 +4,7 @@ #include <zencore/compactbinary.h> #include <zencore/compactbinarybuilder.h> +#include <zencore/compactbinarypackage.h> #include <zencore/except.h> #include <zencore/logging.h> #include <zencore/scopeguard.h> @@ -145,7 +146,10 @@ private: /** * This is the handler for the initial HTTP I/O request which will receive the headers - * and however much of the remaining payload might fit in the embedded request buffer + * and however much of the remaining payload might fit in the embedded request buffer. + * + * It is also used to receive any entity body data relating to the request + * */ struct InitialRequestHandler : public HttpSysRequestHandler { @@ -176,8 +180,8 @@ public: HttpSysServerRequest(HttpSysTransaction& Tx, HttpService& Service, IoBuffer PayloadBuffer); ~HttpSysServerRequest() = default; - virtual Oid SessionId() const override; - virtual uint32_t RequestId() const override; + virtual Oid ParseSessionId() const override; + virtual uint32_t ParseRequestId() const override; virtual IoBuffer ReadPayload() override; virtual void WriteResponse(HttpResponseCode ResponseCode) override; @@ -409,7 +413,14 @@ HttpSysRequestHandler* HttpMessageResponseRequest::HandleCompletion(ULONG IoResult, ULONG_PTR NumberOfBytesTransferred) { ZEN_UNUSED(NumberOfBytesTransferred); - ZEN_UNUSED(IoResult); + + if (IoResult) + { + spdlog::warn("response aborted due to error: '{}'", GetWindowsErrorAsString(IoResult)); + + // if one transmit failed there's really no need to go on + return nullptr; + } if (m_RemainingChunkCount == 0) { @@ -438,6 +449,21 @@ HttpMessageResponseRequest::IssueRequest(std::error_code& ErrorCode) m_RemainingChunkCount -= ThisRequestChunkCount; m_NextDataChunkOffset += ThisRequestChunkCount; + /* Should this code also use HTTP_SEND_RESPONSE_FLAG_BUFFER_DATA? + + From the docs: + + This flag enables buffering of data in the kernel on a per-response basis. It should + be used by an application doing synchronous I/O, or by a an application doing + asynchronous I/O with no more than one send outstanding at a time. + + Applications using asynchronous I/O which may have more than one send outstanding at + a time should not use this flag. + + When this flag is set, it should be used consistently in calls to the + HttpSendHttpResponse function as well. + */ + ULONG SendFlags = 0; if (m_RemainingChunkCount) @@ -526,10 +552,14 @@ HttpMessageResponseRequest::IssueRequest(std::error_code& ErrorCode) CancelThreadpoolIo(Iocp); - spdlog::error("failed to send HTTP response (error: {}) URL: {}"sv, SendResult, HttpReq->pRawUrl); + spdlog::error("failed to send HTTP response (error: '{}'), request URL: {}"sv, SendResult, HttpReq->pRawUrl); ErrorCode = MakeWin32ErrorCode(SendResult); } + else + { + ErrorCode = {}; + } } /** @@ -926,53 +956,66 @@ HttpSysTransaction::InvokeRequestHandler(HttpService& Service, IoBuffer Payload) { HttpSysServerRequest& ThisRequest = m_HandlerRequest.emplace(*this, Service, Payload); - if ((ThisRequest.RequestContentType() == HttpContentType::kCbPackageOffer) && (ThisRequest.RequestVerb() == HttpVerb::kPost)) + if (ThisRequest.RequestVerb() == HttpVerb::kPost) { - // 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) + if (ThisRequest.RequestContentType() == HttpContentType::kCbPackageOffer) { - CbObject OfferMessage = LoadCompactBinaryObject(Payload); + // 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 - std::vector<IoHash> OfferCids; + m_PackageHandler = Service.HandlePackageRequest(ThisRequest); - for (auto& CidEntry : OfferMessage["offer"]) + if (m_PackageHandler) { - if (!CidEntry.IsHash()) + CbObject OfferMessage = LoadCompactBinaryObject(Payload); + + std::vector<IoHash> OfferCids; + + for (auto& CidEntry : OfferMessage["offer"]) { - // Should yield bad request response? + if (!CidEntry.IsHash()) + { + // Should yield bad request response? + + continue; + } - continue; + OfferCids.push_back(CidEntry.AsHash(IoHash::Zero)); } - OfferCids.push_back(CidEntry.AsHash(IoHash::Zero)); - } + m_PackageHandler->FilterOffer(OfferCids); - m_PackageHandler->FilterOffer(OfferCids); + CbObjectWriter ResponseWriter; + ResponseWriter.BeginArray("need"); - CbObjectWriter ResponseWriter; - ResponseWriter.BeginArray("need"); + for (const IoHash& Cid : OfferCids) + { + ResponseWriter.AddHash(Cid); + } - 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 - ResponseWriter.EndArray(); + m_PackageHandler = Service.HandlePackageRequest(ThisRequest); - // Emit filter response - ThisRequest.WriteResponse(HttpResponseCode::OK, ResponseWriter.Save()); + if (m_PackageHandler) + { + CbPackage Package; - return ThisRequest; + Package.TryLoad(ThisRequest.ReadPayload()); + } } } - else if ((ThisRequest.RequestContentType() == HttpContentType::kCbPackage) && (ThisRequest.RequestVerb() == HttpVerb::kPost)) - { - } // Default request handling @@ -1024,13 +1067,8 @@ HttpSysServerRequest::HttpSysServerRequest(HttpSysTransaction& Tx, HttpService& } Oid -HttpSysServerRequest::SessionId() const +HttpSysServerRequest::ParseSessionId() const { - if (m_Flags & kHaveSessionId) - { - return m_SessionId; - } - const HTTP_REQUEST* HttpRequestPtr = m_HttpTx.HttpRequest(); for (int i = 0; i < HttpRequestPtr->Headers.UnknownHeaderCount; ++i) @@ -1042,24 +1080,17 @@ HttpSysServerRequest::SessionId() const { if (Header.RawValueLength == Oid::StringLength) { - m_SessionId = Oid::FromHexString({Header.pRawValue, Header.RawValueLength}); + return Oid::FromHexString({Header.pRawValue, Header.RawValueLength}); } } } - m_Flags |= kHaveSessionId; - - return m_SessionId; + return {}; } uint32_t -HttpSysServerRequest::RequestId() const +HttpSysServerRequest::ParseRequestId() const { - if (m_Flags & kHaveRequestId) - { - return m_RequestId; - } - const HTTP_REQUEST* HttpRequestPtr = m_HttpTx.HttpRequest(); for (int i = 0; i < HttpRequestPtr->Headers.UnknownHeaderCount; ++i) @@ -1070,13 +1101,13 @@ HttpSysServerRequest::RequestId() const if (HeaderName == "UE-Request"sv) { std::string_view RequestValue{Header.pRawValue, Header.RawValueLength}; - std::from_chars(RequestValue.data(), RequestValue.data() + RequestValue.size(), m_RequestId); + uint32_t RequestId = 0; + std::from_chars(RequestValue.data(), RequestValue.data() + RequestValue.size(), RequestId); + return RequestId; } } - m_Flags |= kHaveRequestId; - - return m_RequestId; + return 0; } IoBuffer diff --git a/zenhttp/include/zenhttp/httpserver.h b/zenhttp/include/zenhttp/httpserver.h index f859eb038..44559db53 100644 --- a/zenhttp/include/zenhttp/httpserver.h +++ b/zenhttp/include/zenhttp/httpserver.h @@ -213,9 +213,9 @@ public: inline HttpContentType RequestContentType() { return m_ContentType; } inline HttpContentType AcceptContentType() { return m_AcceptType; } - inline uint64_t ContentLength() const { return m_ContentLength; } - virtual Oid SessionId() const; - virtual uint32_t RequestId() const; + inline uint64_t ContentLength() const { return m_ContentLength; } + Oid SessionId() const; + uint32_t RequestId() const; inline bool IsHandled() const { return !!(m_Flags & kIsHandled); } inline bool SuppressBody() const { return !!(m_Flags & kSuppressBody); } @@ -265,15 +265,18 @@ protected: mutable Oid m_SessionId = Oid::Zero; inline void SetIsHandled() { m_Flags |= kIsHandled; } + + virtual Oid ParseSessionId() const = 0; + virtual uint32_t ParseRequestId() const = 0; }; class IHttpPackageHandler : public RefCounted { public: virtual void FilterOffer(std::vector<IoHash>& OfferCids) = 0; - virtual void OnBeginChunks() = 0; + virtual void OnRequestBegin() = 0; virtual IoBuffer CreateTarget(const IoHash& Cid, uint64_t StorageSize) = 0; - virtual void OnEndChunks() = 0; + virtual void OnRequestComplete() = 0; }; /** diff --git a/zenhttp/zenhttp.vcxproj b/zenhttp/zenhttp.vcxproj index 34c83326e..722944b21 100644 --- a/zenhttp/zenhttp.vcxproj +++ b/zenhttp/zenhttp.vcxproj @@ -96,12 +96,14 @@ <ClCompile Include="httpclient.cpp" /> <ClCompile Include="httpnull.cpp" /> <ClCompile Include="httpserver.cpp" /> + <ClCompile Include="httpshared.cpp" /> <ClCompile Include="httpsys.cpp" /> <ClCompile Include="httpuws.cpp" /> <ClCompile Include="iothreadpool.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="httpnull.h" /> + <ClInclude Include="httpshared.h" /> <ClInclude Include="httpsys.h" /> <ClInclude Include="httpuws.h" /> <ClInclude Include="include\zenhttp\httpclient.h" /> diff --git a/zenhttp/zenhttp.vcxproj.filters b/zenhttp/zenhttp.vcxproj.filters index 9c2d05cd5..c05a8304e 100644 --- a/zenhttp/zenhttp.vcxproj.filters +++ b/zenhttp/zenhttp.vcxproj.filters @@ -7,6 +7,7 @@ <ClCompile Include="iothreadpool.cpp" /> <ClCompile Include="httpnull.cpp" /> <ClCompile Include="httpuws.cpp" /> + <ClCompile Include="httpshared.cpp" /> </ItemGroup> <ItemGroup> <ClInclude Include="include\zenhttp\httpclient.h" /> @@ -16,6 +17,7 @@ <ClInclude Include="include\zenhttp\zenhttp.h" /> <ClInclude Include="httpnull.h" /> <ClInclude Include="httpuws.h" /> + <ClInclude Include="httpshared.h" /> </ItemGroup> <ItemGroup> <None Include="xmake.lua" /> diff --git a/zenserver/testing/httptest.cpp b/zenserver/testing/httptest.cpp index d1955ca27..2d469c936 100644 --- a/zenserver/testing/httptest.cpp +++ b/zenserver/testing/httptest.cpp @@ -36,17 +36,33 @@ HttpTestingService::HandleRequest(HttpServerRequest& Request) m_Router.HandleRequest(Request); } -////////////////////////////////////////////////////////////////////////// - Ref<IHttpPackageHandler> HttpTestingService::HandlePackageRequest(HttpServerRequest& HttpServiceRequest) { - return new PackageHandler(HttpServiceRequest); + RwLock::ExclusiveLockScope _(m_RwLock); + + const uint32_t RequestId = HttpServiceRequest.RequestId(); + + if (auto It = m_HandlerMap.find(RequestId); It != m_HandlerMap.end()) + { + Ref<HttpTestingService::PackageHandler> Handler = std::move(It->second); + + m_HandlerMap.erase(It); + + return Handler.Get(); + } + + auto InsertResult = m_HandlerMap.insert({RequestId, nullptr}); + + _.ReleaseNow(); + + return (InsertResult.first->second = new PackageHandler(*this, RequestId)).Get(); } -HttpTestingService::PackageHandler::PackageHandler(const HttpServerRequest& Request) +////////////////////////////////////////////////////////////////////////// + +HttpTestingService::PackageHandler::PackageHandler(HttpTestingService& Svc, uint32_t RequestId) : m_Svc(Svc), m_RequestId(RequestId) { - ZEN_UNUSED(Request); } HttpTestingService::PackageHandler::~PackageHandler() @@ -61,7 +77,12 @@ HttpTestingService::PackageHandler::FilterOffer(std::vector<IoHash>& OfferCids) return; } void -HttpTestingService::PackageHandler::OnBeginChunks() +HttpTestingService::PackageHandler::OnRequestBegin() +{ +} + +void +HttpTestingService::PackageHandler::OnRequestComplete() { } @@ -73,9 +94,4 @@ HttpTestingService::PackageHandler::CreateTarget(const IoHash& Cid, uint64_t Sto return {}; } -void -HttpTestingService::PackageHandler::OnEndChunks() -{ -} - } // namespace zen diff --git a/zenserver/testing/httptest.h b/zenserver/testing/httptest.h index 2f3482abc..5809d4e2e 100644 --- a/zenserver/testing/httptest.h +++ b/zenserver/testing/httptest.h @@ -24,17 +24,24 @@ public: class PackageHandler : public IHttpPackageHandler { public: - PackageHandler(const HttpServerRequest& Request); + PackageHandler(HttpTestingService& Svc, uint32_t RequestId); ~PackageHandler(); - void FilterOffer(std::vector<IoHash>& OfferCids) override; - void OnBeginChunks() override; - IoBuffer CreateTarget(const IoHash& Cid, uint64_t StorageSize) override; - void OnEndChunks() override; + virtual void FilterOffer(std::vector<IoHash>& OfferCids) override; + virtual void OnRequestBegin() override; + virtual IoBuffer CreateTarget(const IoHash& Cid, uint64_t StorageSize) override; + virtual void OnRequestComplete() override; + + private: + HttpTestingService& m_Svc; + uint32_t m_RequestId; }; private: HttpRequestRouter m_Router; + + RwLock m_RwLock; + std::unordered_map<uint32_t, Ref<PackageHandler>> m_HandlerMap; }; } // namespace zen |