aboutsummaryrefslogtreecommitdiff
path: root/zencore/httpserver.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2021-09-02 13:02:19 +0200
committerStefan Boberg <[email protected]>2021-09-02 13:02:19 +0200
commit6e28d78ff51bc2078830ef495cb0e27e8a868794 (patch)
treeaabf1ea25b3eb42c523c0a5aa35de34b3d920db5 /zencore/httpserver.cpp
parentIntroduced support for compressed buffer attachments (diff)
downloadzen-6e28d78ff51bc2078830ef495cb0e27e8a868794.tar.xz
zen-6e28d78ff51bc2078830ef495cb0e27e8a868794.zip
Initial implementation of CbPackage HTTP response writing
Diffstat (limited to 'zencore/httpserver.cpp')
-rw-r--r--zencore/httpserver.cpp107
1 files changed, 68 insertions, 39 deletions
diff --git a/zencore/httpserver.cpp b/zencore/httpserver.cpp
index eaa8bdfcd..587eab279 100644
--- a/zencore/httpserver.cpp
+++ b/zencore/httpserver.cpp
@@ -273,49 +273,78 @@ HttpServerRequest::~HttpServerRequest()
void
HttpServerRequest::WriteResponse(HttpResponse HttpResponseCode, CbPackage Data)
{
- // TODO: implement efficient version of this which can send package attachment
- // payloads directly from disk
- ZEN_UNUSED(HttpResponseCode, Data);
- ZEN_NOT_IMPLEMENTED();
+ const std::span<const CbAttachment>& Attachments = Data.GetAttachments();
+
+ struct CbPackageHeader
+ {
+ uint32_t HeaderMagic;
+ uint32_t AttachmentCount;
+ uint32_t Reserved1;
+ uint32_t Reserved2;
+ };
+
+ static constinit uint32_t kMagic = 0xaa77aacc;
+
+ struct CbAttachmentEntry
+ {
+ uint64_t AttachmentSize;
+ uint32_t Reserved1;
+ IoHash AttachmentHash;
+ };
+
+ 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 = kMagic, .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 WriteResponse(HttpResponseCode, HttpContentType::kCbPackage, ResponseBuffers);
}
void
HttpServerRequest::WriteResponse(HttpResponse HttpResponseCode, CbObject Data)
{
-#if 0
- struct Visitor : public ICbVisitor
- {
- virtual void SetName(std::string_view Name) override { OutText << '\'' << Name << "': "; }
- virtual void BeginObject() override { OutText << "{ "; }
- virtual void EndObject() override { OutText << "}"; }
- virtual void BeginArray() override { OutText << "[ "; }
- virtual void EndArray() override { OutText << " ]"; }
-
- virtual void VisitNull() override { OutText << "null"; }
- virtual void VisitBinary(SharedBuffer Value) override { ZEN_UNUSED(Value); }
- virtual void VisitString(std::string_view Value) override { ZEN_UNUSED(Value); }
- virtual void VisitInteger(int64_t Value) override { OutText << Value; }
- virtual void VisitInteger(uint64_t Value) override { OutText << Value; }
- virtual void VisitFloat(float Value) override { ZEN_UNUSED(Value); }
- virtual void VisitDouble(double Value) override { ZEN_UNUSED(Value); }
- virtual void VisitBool(bool Value) override { OutText << Value; }
- virtual void VisitCbAttachment(const IoHash& Value) override { ZEN_UNUSED(Value); }
- virtual void VisitBinaryAttachment(const IoHash& Value) override { ZEN_UNUSED(Value); }
- virtual void VisitHash(const IoHash& Value) override { ZEN_UNUSED(Value); }
- virtual void VisitUuid(const Guid& Value) override { ZEN_UNUSED(Value); }
- virtual void VisitObjectId(const Oid& Value) override { ZEN_UNUSED(Value); }
- virtual void VisitDateTime(DateTime Value) override { ZEN_UNUSED(Value); }
- virtual void VisitTimeSpan(TimeSpan Value) override { ZEN_UNUSED(Value); }
-
- ExtendableStringBuilder<256> OutText;
- } _;
- // Data.CreateRefIterator().VisitFields(_);
- return WriteResponse(HttpResponseCode, HttpContentType::kJSON, _.OutText);
-#else
SharedBuffer Buf = Data.GetBuffer();
- std::array<IoBuffer, 1> buffers{IoBufferBuilder::MakeCloneFromMemory(Buf.GetData(), Buf.GetSize())};
- return WriteResponse(HttpResponseCode, HttpContentType::kCbObject, buffers);
-#endif
+ std::array<IoBuffer, 1> Buffers{IoBufferBuilder::MakeCloneFromMemory(Buf.GetData(), Buf.GetSize())};
+ return WriteResponse(HttpResponseCode, HttpContentType::kCbObject, Buffers);
}
void
@@ -327,8 +356,8 @@ HttpServerRequest::WriteResponse(HttpResponse HttpResponseCode, HttpContentType
void
HttpServerRequest::WriteResponse(HttpResponse HttpResponseCode, HttpContentType ContentType, IoBuffer Blob)
{
- std::array<IoBuffer, 1> buffers{Blob};
- return WriteResponse(HttpResponseCode, ContentType, buffers);
+ std::array<IoBuffer, 1> Buffers{Blob};
+ return WriteResponse(HttpResponseCode, ContentType, Buffers);
}
HttpServerRequest::QueryParams