From 29476a989ac9a36d19a421b47a689a582f4ab244 Mon Sep 17 00:00:00 2001 From: Stefan Boberg Date: Mon, 6 Sep 2021 09:20:41 +0200 Subject: HTTP package handling updated (not final) --- zencore/httpserver.cpp | 103 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 76 insertions(+), 27 deletions(-) (limited to 'zencore/httpserver.cpp') diff --git a/zencore/httpserver.cpp b/zencore/httpserver.cpp index 587eab279..aa7d96772 100644 --- a/zencore/httpserver.cpp +++ b/zencore/httpserver.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -270,27 +271,27 @@ HttpServerRequest::~HttpServerRequest() { } -void -HttpServerRequest::WriteResponse(HttpResponse HttpResponseCode, CbPackage Data) +struct CbPackageHeader { - const std::span& Attachments = Data.GetAttachments(); + uint32_t HeaderMagic; + uint32_t AttachmentCount; + uint32_t Reserved1; + uint32_t Reserved2; +}; - struct CbPackageHeader - { - uint32_t HeaderMagic; - uint32_t AttachmentCount; - uint32_t Reserved1; - uint32_t Reserved2; - }; +static constinit uint32_t kCbPkgMagic = 0xaa77aacc; - static constinit uint32_t kMagic = 0xaa77aacc; +struct CbAttachmentEntry +{ + uint64_t AttachmentSize; + uint32_t Reserved1; + IoHash AttachmentHash; +}; - struct CbAttachmentEntry - { - uint64_t AttachmentSize; - uint32_t Reserved1; - IoHash AttachmentHash; - }; +void +HttpServerRequest::WriteResponse(HttpResponse HttpResponseCode, CbPackage Data) +{ + const std::span& Attachments = Data.GetAttachments(); std::vector ResponseBuffers; ResponseBuffers.reserve(3 + Attachments.size()); // TODO: may want to use an additional fudge factor here to avoid growing since each @@ -300,7 +301,7 @@ HttpServerRequest::WriteResponse(HttpResponse HttpResponseCode, CbPackage Data) // Fixed size header - CbPackageHeader Hdr{.HeaderMagic = kMagic, .AttachmentCount = gsl::narrow(Attachments.size())}; + CbPackageHeader Hdr{.HeaderMagic = kCbPkgMagic, .AttachmentCount = gsl::narrow(Attachments.size())}; ResponseBuffers.push_back(IoBufferBuilder::MakeCloneFromMemory(&Hdr, sizeof Hdr)); @@ -402,7 +403,7 @@ HttpServerRequest::GetQueryParams() QueryIt += DelimIndex; } - return std::move(Params); + return Params; } CbObject @@ -423,13 +424,50 @@ HttpServerRequest::ReadPayloadObject() CbPackage HttpServerRequest::ReadPayloadPackage() { - IoBuffer Payload = ReadPayload(); + // TODO: this should not read into a contiguous buffer! + + IoBuffer Payload = ReadPayload(); + MemoryInStream InStream(Payload); + BinaryReader Reader(InStream); + + if (!Payload) + { + return {}; + } CbPackage Package; - if (Payload) + CbPackageHeader Hdr; + Reader.Read(&Hdr, sizeof Hdr); + + if (Hdr.HeaderMagic != kCbPkgMagic) { - Package.TryLoad(Payload); + // report error + return {}; + } + + uint32_t ChunkCount = Hdr.AttachmentCount + 1; + + std::unique_ptr 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; @@ -930,8 +968,6 @@ HttpSysServer::Run(bool TestMode) printf("Zen Server running. Press ESC or Q to quit\n"); } - bool KeepRunning = true; - do { int WaitTimeout = -1; @@ -1425,10 +1461,8 @@ struct HttpServer::Impl : public RefCounted void AddEndpoint(const char* Endpoint, HttpService& Service) { m_HttpServer.AddEndpoint(Endpoint, Service); } - void AddEndpoint(const char* endpoint, std::function handler) + void AddEndpoint([[maybe_unused]] const char* endpoint, [[maybe_unused]] std::function handler) { - ZEN_UNUSED(endpoint, handler); - ZEN_NOT_IMPLEMENTED(); } }; @@ -1475,6 +1509,21 @@ HttpServer::RequestExit() ////////////////////////////////////////////////////////////////////////// +HttpServerException::HttpServerException(const char* Message, uint32_t Error) : m_ErrorCode(Error) +{ + using namespace fmt::literals; + + m_Message = "{} (HTTP error {})"_format(Message, m_ErrorCode); +} + +const char* +HttpServerException::what() const +{ + return m_Message.c_str(); +} + +////////////////////////////////////////////////////////////////////////// + void HttpRequestRouter::AddPattern(const char* Id, const char* Regex) { -- cgit v1.2.3