aboutsummaryrefslogtreecommitdiff
path: root/zenhttp/httpserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zenhttp/httpserver.cpp')
-rw-r--r--zenhttp/httpserver.cpp99
1 files changed, 65 insertions, 34 deletions
diff --git a/zenhttp/httpserver.cpp b/zenhttp/httpserver.cpp
index f97ac0067..5b5738fc4 100644
--- a/zenhttp/httpserver.cpp
+++ b/zenhttp/httpserver.cpp
@@ -19,6 +19,7 @@
#include <conio.h>
#include <new.h>
#include <charconv>
+#include <mutex>
#include <span>
#include <string_view>
@@ -53,59 +54,81 @@ MapContentTypeToString(HttpContentType ContentType)
case HttpContentType::kCbPackageOffer:
return "application/x-ue-offer"sv;
+ case HttpContentType::kCompressedBinary:
+ return "application/x-ue-comp"sv;
+
case HttpContentType::kYAML:
return "text/yaml"sv;
}
}
-static const uint32_t HashBinary = HashStringDjb2("application/octet-stream"sv);
-static const uint32_t HashJson = HashStringDjb2("application/json"sv);
-static const uint32_t HashYaml = HashStringDjb2("text/yaml"sv);
-static const uint32_t HashText = HashStringDjb2("text/plain"sv);
-static const uint32_t HashCompactBinary = HashStringDjb2("application/x-ue-cb"sv);
-static const uint32_t HashCompactBinaryPackage = HashStringDjb2("application/x-ue-cbpkg"sv);
-static const uint32_t HashCompactBinaryPackageOffer = HashStringDjb2("application/x-ue-offer"sv);
+//////////////////////////////////////////////////////////////////////////
+
+static constinit uint32_t HashBinary = HashStringDjb2("application/octet-stream"sv);
+static constinit uint32_t HashJson = HashStringDjb2("application/json"sv);
+static constinit uint32_t HashYaml = HashStringDjb2("text/yaml"sv);
+static constinit uint32_t HashText = HashStringDjb2("text/plain"sv);
+static constinit uint32_t HashCompactBinary = HashStringDjb2("application/x-ue-cb"sv);
+static constinit uint32_t HashCompactBinaryPackage = HashStringDjb2("application/x-ue-cbpkg"sv);
+static constinit uint32_t HashCompactBinaryPackageOffer = HashStringDjb2("application/x-ue-offer"sv);
+static constinit uint32_t HashCompressedBinary = HashStringDjb2("application/x-ue-comp"sv);
+
+std::once_flag InitContentTypeLookup;
+
+struct HashedTypeEntry
+{
+ uint32_t Hash;
+ HttpContentType Type;
+} TypeHashTable[] = {{HashBinary, HttpContentType::kBinary},
+ {HashCompactBinary, HttpContentType::kCbObject},
+ {HashCompactBinaryPackage, HttpContentType::kCbPackage},
+ {HashCompactBinaryPackageOffer, HttpContentType::kCbPackageOffer},
+ {HashJson, HttpContentType::kJSON},
+ {HashYaml, HttpContentType::kYAML},
+ {HashText, HttpContentType::kText},
+ {HashCompressedBinary, HttpContentType::kCompressedBinary}};
HttpContentType
-ParseContentType(const std::string_view& ContentTypeString)
+ParseContentTypeImpl(const std::string_view& ContentTypeString)
{
if (!ContentTypeString.empty())
{
const uint32_t CtHash = HashStringDjb2(ContentTypeString);
- if (CtHash == HashBinary)
- {
- return HttpContentType::kBinary;
- }
- else if (CtHash == HashCompactBinary)
- {
- return HttpContentType::kCbObject;
- }
- else if (CtHash == HashCompactBinaryPackage)
- {
- return HttpContentType::kCbPackage;
- }
- else if (CtHash == HashCompactBinaryPackageOffer)
- {
- return HttpContentType::kCbPackageOffer;
- }
- else if (CtHash == HashJson)
- {
- return HttpContentType::kJSON;
- }
- else if (CtHash == HashYaml)
- {
- return HttpContentType::kYAML;
- }
- else if (CtHash == HashText)
+ if (auto It = std::lower_bound(std::begin(TypeHashTable),
+ std::end(TypeHashTable),
+ CtHash,
+ [](const HashedTypeEntry& Lhs, const uint32_t Rhs) { return Lhs.Hash < Rhs; });
+ It != std::end(TypeHashTable))
{
- return HttpContentType::kText;
+ if (It->Hash == CtHash)
+ {
+ return It->Type;
+ }
}
}
return HttpContentType::kUnknownContentType;
}
+HttpContentType
+ParseContentTypeInit(const std::string_view& ContentTypeString)
+{
+ std::call_once(InitContentTypeLookup, [] {
+ std::sort(std::begin(TypeHashTable), std::end(TypeHashTable), [](const HashedTypeEntry& Lhs, const HashedTypeEntry& Rhs) {
+ return Lhs.Hash < Rhs.Hash;
+ });
+ });
+
+ ParseContentType = ParseContentTypeImpl;
+
+ return ParseContentTypeImpl(ContentTypeString);
+}
+
+HttpContentType (*ParseContentType)(const std::string_view& ContentTypeString) = &ParseContentTypeInit;
+
+//////////////////////////////////////////////////////////////////////////
+
const char*
ReasonStringForHttpResultCode(int HttpCode)
{
@@ -523,6 +546,14 @@ TEST_CASE("http")
// TestHttpServerRequest req{};
// r.HandleRequest(req);
}
+
+ SUBCASE("content-type")
+ {
+ for (uint8_t i = 0; i < uint8_t(HttpContentType::kCOUNT); ++i)
+ {
+ CHECK_EQ(HttpContentType(i), ParseContentType(MapContentTypeToString(HttpContentType(i))));
+ }
+ }
}
void