aboutsummaryrefslogtreecommitdiff
path: root/zenhttp/include
diff options
context:
space:
mode:
Diffstat (limited to 'zenhttp/include')
-rw-r--r--zenhttp/include/zenhttp/httpshared.h62
1 files changed, 54 insertions, 8 deletions
diff --git a/zenhttp/include/zenhttp/httpshared.h b/zenhttp/include/zenhttp/httpshared.h
index a6a61485f..24ce0c85a 100644
--- a/zenhttp/include/zenhttp/httpshared.h
+++ b/zenhttp/include/zenhttp/httpshared.h
@@ -2,10 +2,12 @@
#pragma once
+#include <zencore/compactbinarypackage.h>
#include <zencore/iobuffer.h>
#include <zencore/iohash.h>
#include <functional>
+#include <gsl/gsl-lite.hpp>
namespace zen {
@@ -24,6 +26,13 @@ class CompositeBuffer;
Structures and code related to handling CbPackage transactions
+ CbPackage instances are marshaled across the wire using a distinct message
+ format. We don't use the CbPackage serialization format provided by the
+ CbPackage implementation itself since that does not provide much flexibility
+ in how the attachment payloads are transmitted. The scheme below separates
+ metadata cleanly from payloads and this enables us to more efficiently
+ transmit them either via sendfile/TransmitFile like mechanisms, or by
+ reference/memory mapping in the local case.
*/
struct CbPackageHeader
@@ -43,33 +52,59 @@ enum : uint32_t
struct CbAttachmentEntry
{
- uint64_t PayloadSize;
- uint32_t Flags;
- IoHash AttachmentHash;
+ uint64_t PayloadSize; // Size of the associated payload data in the message
+ uint32_t Flags; // See flags below
+ IoHash AttachmentHash; // Content Id for the attachment
enum
{
kIsCompressed = (1u << 0), // Is marshaled using compressed buffer storage format
kIsObject = (1u << 1), // Is compact binary object
kIsError = (1u << 2), // Is error (compact binary formatted) object
+ kIsLocalRef = (1u << 3), // Is "local reference"
};
};
+struct CbAttachmentReferenceHeader
+{
+ uint64_t PayloadByteOffset = 0;
+ uint64_t PayloadByteSize = ~0u;
+ uint16_t AbsolutePathLength = 0;
+
+ // This header will be followed by UTF8 encoded absolute path to backing file
+};
+
static_assert(sizeof(CbAttachmentEntry) == 32);
-std::vector<IoBuffer> FormatPackageMessage(const CbPackage& Data);
-CompositeBuffer FormatPackageMessageBuffer(const CbPackage& Data);
+enum class FormatFlags
+{
+ kDefault = 0,
+ kAllowLocalReferences = (1u << 0)
+};
+
+gsl_DEFINE_ENUM_BITMASK_OPERATORS(FormatFlags);
+
+std::vector<IoBuffer> FormatPackageMessage(const CbPackage& Data, FormatFlags Flags);
+CompositeBuffer FormatPackageMessageBuffer(const CbPackage& Data, FormatFlags Flags);
CbPackage ParsePackageMessage(
IoBuffer Payload,
std::function<IoBuffer(const IoHash& Cid, uint64_t Size)> CreateBuffer = [](const IoHash&, uint64_t Size) -> IoBuffer {
return IoBuffer{Size};
});
+bool IsPackageMessage(IoBuffer Payload);
+
+std::vector<IoBuffer> FormatPackageMessage(const CbPackage& Data);
+CompositeBuffer FormatPackageMessageBuffer(const CbPackage& Data);
/** Streaming reader for compact binary packages
The goal is to ultimately support zero-copy I/O, but for now there'll be some
copying involved on some platforms at least.
+ This approach to deserializing CbPackage data is more efficient than
+ `ParsePackageMessage` since it does not require the entire message to
+ be resident in a memory buffer
+
*/
class CbPackageReader
{
@@ -79,11 +114,18 @@ public:
void SetPayloadBufferCreator(std::function<IoBuffer(const IoHash& Cid, uint64_t Size)> CreateBuffer);
- /** Process header data
+ /** Process compact binary package data stream
+
+ The data stream must be in the serialization format produced by FormatPackageMessage
+
+ \return How many bytes must be fed to this function in the next call
*/
- uint64_t ProcessHeaderData(const void* Data, uint64_t DataBytes);
+ uint64_t ProcessPackageHeaderData(const void* Data, uint64_t DataBytes);
- std::span<IoBuffer> GetPayloadBuffers() { return m_PayloadBuffers; }
+ void Finalize();
+ const std::vector<CbAttachment>& GetAttachments() { return m_Attachments; }
+ CbObject GetRootObject() { return m_RootObject; }
+ std::span<IoBuffer> GetPayloadBuffers() { return m_PayloadBuffers; }
private:
enum class State
@@ -97,7 +139,11 @@ private:
std::function<IoBuffer(const IoHash& Cid, uint64_t Size)> m_CreateBuffer;
std::vector<IoBuffer> m_PayloadBuffers;
std::vector<CbAttachmentEntry> m_AttachmentEntries;
+ std::vector<CbAttachment> m_Attachments;
+ CbObject m_RootObject;
CbPackageHeader m_PackageHeader;
+
+ IoBuffer MarshalLocalChunkReference(IoBuffer AttachmentBuffer);
};
void forcelink_httpshared();