aboutsummaryrefslogtreecommitdiff
path: root/zencore/httpserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zencore/httpserver.cpp')
-rw-r--r--zencore/httpserver.cpp389
1 files changed, 0 insertions, 389 deletions
diff --git a/zencore/httpserver.cpp b/zencore/httpserver.cpp
deleted file mode 100644
index 4b6bd1c0a..000000000
--- a/zencore/httpserver.cpp
+++ /dev/null
@@ -1,389 +0,0 @@
-// Copyright Epic Games, Inc. All Rights Reserved.
-
-#include <zencore/httpserver.h>
-
-#include "httpsys.h"
-
-#include <zencore/compactbinary.h>
-#include <zencore/compactbinarypackage.h>
-#include <zencore/iobuffer.h>
-#include <zencore/logging.h>
-#include <zencore/refcount.h>
-#include <zencore/stream.h>
-#include <zencore/string.h>
-#include <zencore/thread.h>
-
-#include <conio.h>
-#include <new.h>
-#include <charconv>
-#include <span>
-#include <string_view>
-
-#include <doctest/doctest.h>
-
-namespace zen {
-
-HttpServerRequest::HttpServerRequest()
-{
-}
-
-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(HttpResponse HttpResponseCode, 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 WriteResponse(HttpResponseCode, HttpContentType::kCbPackage, ResponseBuffers);
-}
-
-void
-HttpServerRequest::WriteResponse(HttpResponse HttpResponseCode, CbObject Data)
-{
- SharedBuffer Buf = Data.GetBuffer();
- std::array<IoBuffer, 1> Buffers{IoBufferBuilder::MakeCloneFromMemory(Buf.GetData(), Buf.GetSize())};
- return WriteResponse(HttpResponseCode, HttpContentType::kCbObject, Buffers);
-}
-
-void
-HttpServerRequest::WriteResponse(HttpResponse HttpResponseCode, HttpContentType ContentType, std::string_view ResponseString)
-{
- return WriteResponse(HttpResponseCode, ContentType, std::u8string_view{(char8_t*)ResponseString.data(), ResponseString.size()});
-}
-
-void
-HttpServerRequest::WriteResponse(HttpResponse HttpResponseCode, HttpContentType ContentType, IoBuffer Blob)
-{
- std::array<IoBuffer, 1> Buffers{Blob};
- return WriteResponse(HttpResponseCode, ContentType, Buffers);
-}
-
-HttpServerRequest::QueryParams
-HttpServerRequest::GetQueryParams()
-{
- QueryParams Params;
-
- const std::string_view QStr = QueryString();
-
- const char* QueryIt = QStr.data();
- const char* QueryEnd = QueryIt + QStr.size();
-
- while (QueryIt != QueryEnd)
- {
- if (*QueryIt == '&')
- {
- ++QueryIt;
- continue;
- }
-
- const std::string_view Query{QueryIt, QueryEnd};
-
- size_t DelimIndex = Query.find('&', 0);
-
- if (DelimIndex == std::string_view::npos)
- {
- DelimIndex = Query.size();
- }
-
- std::string_view ThisQuery{QueryIt, DelimIndex};
-
- size_t EqIndex = ThisQuery.find('=', 0);
-
- if (EqIndex != std::string_view::npos)
- {
- std::string_view Parm{ThisQuery.data(), EqIndex};
- ThisQuery.remove_prefix(EqIndex + 1);
-
- Params.KvPairs.emplace_back(Parm, ThisQuery);
- }
-
- QueryIt += DelimIndex;
- }
-
- return Params;
-}
-
-CbObject
-HttpServerRequest::ReadPayloadObject()
-{
- IoBuffer Payload = ReadPayload();
-
- if (Payload)
- {
- return LoadCompactBinaryObject(std::move(Payload));
- }
- else
- {
- 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)
- {
- 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;
-}
-
-//////////////////////////////////////////////////////////////////////////
-
-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)
-{
- ZEN_ASSERT(m_PatternMap.find(Id) == m_PatternMap.end());
-
- m_PatternMap.insert({Id, Regex});
-}
-
-void
-HttpRequestRouter::RegisterRoute(const char* Regex, HttpRequestRouter::HandlerFunc_t&& HandlerFunc, HttpVerb SupportedVerbs)
-{
- ExtendableStringBuilder<128> ExpandedRegex;
- ProcessRegexSubstitutions(Regex, ExpandedRegex);
-
- m_Handlers.emplace_back(ExpandedRegex.c_str(), SupportedVerbs, std::move(HandlerFunc), Regex);
-}
-
-void
-HttpRequestRouter::RegisterRoute(const char* Regex, PackageEndpointHandler& Handler)
-{
- ExtendableStringBuilder<128> ExpandedRegex;
- ProcessRegexSubstitutions(Regex, ExpandedRegex);
-
- m_Handlers.emplace_back(
- ExpandedRegex.c_str(),
- HttpVerb::kPost,
- [&Handler](HttpRouterRequest& Request) { Handler.HandleRequest(Request); },
- Regex);
-}
-
-void
-HttpRequestRouter::ProcessRegexSubstitutions(const char* Regex, StringBuilderBase& OutExpandedRegex)
-{
- size_t RegexLen = strlen(Regex);
-
- for (size_t i = 0; i < RegexLen;)
- {
- bool matched = false;
-
- if (Regex[i] == '{' && ((i == 0) || (Regex[i - 1] != '\\')))
- {
- // Might have a pattern reference - find closing brace
-
- for (size_t j = i + 1; j < RegexLen; ++j)
- {
- if (Regex[j] == '}')
- {
- std::string Pattern(&Regex[i + 1], j - i - 1);
-
- if (auto it = m_PatternMap.find(Pattern); it != m_PatternMap.end())
- {
- OutExpandedRegex.Append(it->second.c_str());
- }
- else
- {
- // Default to anything goes (or should this just be an error?)
-
- OutExpandedRegex.Append("(.+?)");
- }
-
- // skip ahead
- i = j + 1;
-
- matched = true;
-
- break;
- }
- }
- }
-
- if (!matched)
- {
- OutExpandedRegex.Append(Regex[i++]);
- }
- }
-}
-
-bool
-HttpRequestRouter::HandleRequest(zen::HttpServerRequest& Request)
-{
- const HttpVerb Verb = Request.RequestVerb();
-
- std::string_view Uri = Request.RelativeUri();
- HttpRouterRequest RouterRequest(Request);
-
- for (const auto& Handler : m_Handlers)
- {
- if ((Handler.Verbs & Verb) == Verb && regex_match(begin(Uri), end(Uri), RouterRequest.m_Match, Handler.RegEx))
- {
- Handler.Handler(RouterRequest);
-
- return true; // Route matched
- }
- }
-
- return false; // No route matched
-}
-
-//////////////////////////////////////////////////////////////////////////
-
-Ref<HttpServer>
-CreateHttpServer()
-{
- return new HttpSysServer{32};
-}
-
-//////////////////////////////////////////////////////////////////////////
-
-TEST_CASE("http")
-{
- using namespace std::literals;
-
- SUBCASE("router")
- {
- HttpRequestRouter r;
- r.AddPattern("a", "[[:alpha:]]+");
- r.RegisterRoute(
- "{a}",
- [&](auto) {},
- HttpVerb::kGet);
-
- // struct TestHttpServerRequest : public HttpServerRequest
- //{
- // TestHttpServerRequest(std::string_view Uri) : m_uri{Uri} {}
- //};
-
- // TestHttpServerRequest req{};
- // r.HandleRequest(req);
- }
-}
-
-void
-http_forcelink()
-{
-}
-
-} // namespace zen