aboutsummaryrefslogtreecommitdiff
path: root/zenserver
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-05-12 13:48:45 +0200
committerDan Engelbrecht <[email protected]>2022-05-12 13:48:45 +0200
commit1274f92cf7ce890b7aa1fc9354503e2508c185eb (patch)
treebae3d3d1b14009972503652b3c40fde41081c127 /zenserver
parentAdd support for /api/v2/ URI requests with namespace support (diff)
downloadzen-1274f92cf7ce890b7aa1fc9354503e2508c185eb.tar.xz
zen-1274f92cf7ce890b7aa1fc9354503e2508c185eb.zip
Tests for HttpRequestParseRelativeUri
Diffstat (limited to 'zenserver')
-rw-r--r--zenserver/cache/structuredcache.cpp168
-rw-r--r--zenserver/cache/structuredcache.h2
-rw-r--r--zenserver/cache/structuredcachestore.cpp11
-rw-r--r--zenserver/cache/structuredcachestore.h1
-rw-r--r--zenserver/zenserver.cpp1
5 files changed, 151 insertions, 32 deletions
diff --git a/zenserver/cache/structuredcache.cpp b/zenserver/cache/structuredcache.cpp
index 691da36fa..9299911cf 100644
--- a/zenserver/cache/structuredcache.cpp
+++ b/zenserver/cache/structuredcache.cpp
@@ -35,6 +35,11 @@
#include <gsl/gsl-lite.hpp>
+#if ZEN_WITH_TESTS
+# include <zencore/testing.h>
+# include <zencore/testutils.h>
+#endif
+
namespace zen {
using namespace std::literals;
@@ -135,32 +140,51 @@ struct HttpRequestData
static bool
HttpRequestParseRelativeUri(std::string_view Key, HttpRequestData& Data)
{
- std::string_view Namespace = ZenCacheStore::DefaultNamespace;
if (Key.starts_with(HttpZCacheAPIV2Prefix))
{
- std::string_view::size_type NamespaceSplitOffset = Key.find_first_of('/', HttpZCacheAPIV2Prefix.length());
+ Key = Key.substr(HttpZCacheAPIV2Prefix.length());
+ // Namespace reference
+ if (!Key.starts_with(ZenCacheStore::NamespacePrefix))
+ {
+ return false;
+ }
+ Key = Key.substr(ZenCacheStore::NamespacePrefix.length());
+ std::string_view::size_type NamespaceSplitOffset = Key.find_first_of('/');
+
+ std::string_view Namespace = Key.substr(0, NamespaceSplitOffset);
+ if (!std::all_of(begin(Namespace), end(Namespace), [](const char c) { return std::isalnum(c); }))
+ {
+ return false;
+ }
+ Data.Namespace = ToLower(Namespace);
+
if (NamespaceSplitOffset == std::string_view::npos)
{
- // Namespace reference
- if (!std::all_of(begin(Key), end(Key), [](const char c) { return std::isalnum(c); }))
- {
- return false;
- }
- Data.Namespace = ToLower(Key);
return true;
}
- Data.Namespace = Key.substr(0, NamespaceSplitOffset);
- Key = Key.substr(NamespaceSplitOffset + 1);
+
+ Key = Key.substr(NamespaceSplitOffset + 1);
+ }
+ else
+ {
+ Data.Namespace = ZenCacheStore::DefaultNamespace;
}
std::string_view::size_type BucketSplitOffset = Key.find_first_of('/');
+ std::string_view Bucket = Key.substr(0, BucketSplitOffset);
+ if (Bucket.empty())
+ {
+ return false;
+ }
+ if (!std::all_of(begin(Bucket), end(Bucket), [](const char c) { return std::isalnum(c); }))
+ {
+ return false;
+ }
+ Data.Bucket = ToLower(Bucket);
+
if (BucketSplitOffset == std::string_view::npos)
{
- if (!std::all_of(begin(Key), end(Key), [](const char c) { return std::isalnum(c); }))
- {
- return false;
- }
- Data.Bucket = ToLower(Key);
+ // Bucket reference
return true;
}
@@ -193,20 +217,22 @@ HttpRequestParseRelativeUri(std::string_view Key, HttpRequestData& Data)
Data.HashKey = KeyHash;
- if (!ValueSegment.empty())
+ if (ValueSegment.empty())
{
- if (ValueSegment.size() != IoHash::StringLength)
- {
- return false;
- }
+ return true;
+ }
- IoHash ValueHash;
- if (!ParseHexBytes(ValueSegment.data(), ValueSegment.size(), ValueHash.Hash))
- {
- return false;
- }
- Data.ValueContentId = ValueHash;
+ if (ValueSegment.size() != IoHash::StringLength)
+ {
+ return false;
+ }
+
+ IoHash ValueHash;
+ if (!ParseHexBytes(ValueSegment.data(), ValueSegment.size(), ValueHash.Hash))
+ {
+ return false;
}
+ Data.ValueContentId = ValueHash;
return true;
}
@@ -2330,4 +2356,94 @@ HttpStructuredCacheService::HandleStatusRequest(zen::HttpServerRequest& Request)
Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
}
+#if ZEN_WITH_TESTS
+
+TEST_CASE("z$service.parse.relative.Uri")
+{
+ HttpRequestData LegacyBucketRequest;
+ CHECK(HttpRequestParseRelativeUri("test", LegacyBucketRequest));
+ CHECK(LegacyBucketRequest.Namespace == ZenCacheStore::DefaultNamespace);
+ CHECK(LegacyBucketRequest.Bucket == "test"sv);
+ CHECK(!LegacyBucketRequest.HashKey.has_value());
+ CHECK(!LegacyBucketRequest.ValueContentId.has_value());
+
+ HttpRequestData LegacyHashKeyRequest;
+ CHECK(HttpRequestParseRelativeUri("test/0123456789abcdef12340123456789abcdef1234", LegacyHashKeyRequest));
+ CHECK(LegacyHashKeyRequest.Namespace == ZenCacheStore::DefaultNamespace);
+ CHECK(LegacyHashKeyRequest.Bucket == "test"sv);
+ CHECK(LegacyHashKeyRequest.HashKey == IoHash::FromHexString("0123456789abcdef12340123456789abcdef1234"sv));
+ CHECK(!LegacyHashKeyRequest.ValueContentId.has_value());
+
+ HttpRequestData LegacyValueContentIdRequest;
+ CHECK(HttpRequestParseRelativeUri("test/0123456789abcdef12340123456789abcdef1234/56789abcdef12345678956789abcdef123456789",
+ LegacyValueContentIdRequest));
+ CHECK(LegacyValueContentIdRequest.Namespace == ZenCacheStore::DefaultNamespace);
+ CHECK(LegacyValueContentIdRequest.Bucket == "test"sv);
+ CHECK(LegacyValueContentIdRequest.HashKey == IoHash::FromHexString("0123456789abcdef12340123456789abcdef1234"sv));
+ CHECK(LegacyValueContentIdRequest.ValueContentId == IoHash::FromHexString("56789abcdef12345678956789abcdef123456789"sv));
+
+ HttpRequestData V2DefaultNamespaceRequest;
+ CHECK(HttpRequestParseRelativeUri("api/v2/ns_", V2DefaultNamespaceRequest));
+ CHECK(V2DefaultNamespaceRequest.Namespace == ZenCacheStore::DefaultNamespace);
+ CHECK(!V2DefaultNamespaceRequest.Bucket.has_value());
+ CHECK(!V2DefaultNamespaceRequest.HashKey.has_value());
+ CHECK(!V2DefaultNamespaceRequest.ValueContentId.has_value());
+
+ HttpRequestData V2NamespaceRequest;
+ CHECK(HttpRequestParseRelativeUri("api/v2/ns_nicenamespace", V2NamespaceRequest));
+ CHECK(V2NamespaceRequest.Namespace == "nicenamespace"sv);
+ CHECK(!V2NamespaceRequest.Bucket.has_value());
+ CHECK(!V2NamespaceRequest.HashKey.has_value());
+ CHECK(!V2NamespaceRequest.ValueContentId.has_value());
+
+ HttpRequestData V2BucketRequestWithDefaultNamespace;
+ CHECK(HttpRequestParseRelativeUri("api/v2/ns_/test", V2BucketRequestWithDefaultNamespace));
+ CHECK(V2BucketRequestWithDefaultNamespace.Namespace == ZenCacheStore::DefaultNamespace);
+ CHECK(V2BucketRequestWithDefaultNamespace.Bucket == "test"sv);
+ CHECK(!V2BucketRequestWithDefaultNamespace.HashKey.has_value());
+ CHECK(!V2BucketRequestWithDefaultNamespace.ValueContentId.has_value());
+
+ HttpRequestData V2BucketRequestWithNamespace;
+ CHECK(HttpRequestParseRelativeUri("api/v2/ns_nicenamespace/test", V2BucketRequestWithNamespace));
+ CHECK(V2BucketRequestWithNamespace.Namespace == "nicenamespace"sv);
+ CHECK(V2BucketRequestWithNamespace.Bucket == "test"sv);
+ CHECK(!V2BucketRequestWithNamespace.HashKey.has_value());
+ CHECK(!V2BucketRequestWithNamespace.ValueContentId.has_value());
+
+ HttpRequestData V2HashKeyRequest;
+ CHECK(HttpRequestParseRelativeUri("api/v2/ns_/test/0123456789abcdef12340123456789abcdef1234", V2HashKeyRequest));
+ CHECK(V2HashKeyRequest.Namespace == ZenCacheStore::DefaultNamespace);
+ CHECK(V2HashKeyRequest.Bucket == "test");
+ CHECK(V2HashKeyRequest.HashKey == IoHash::FromHexString("0123456789abcdef12340123456789abcdef1234"sv));
+ CHECK(!V2HashKeyRequest.ValueContentId.has_value());
+
+ HttpRequestData V2ValueContentIdRequest;
+ CHECK(HttpRequestParseRelativeUri(
+ "api/v2/ns_nicenamespace/test/0123456789abcdef12340123456789abcdef1234/56789abcdef12345678956789abcdef123456789",
+ V2ValueContentIdRequest));
+ CHECK(V2ValueContentIdRequest.Namespace == "nicenamespace"sv);
+ CHECK(V2ValueContentIdRequest.Bucket == "test"sv);
+ CHECK(V2ValueContentIdRequest.HashKey == IoHash::FromHexString("0123456789abcdef12340123456789abcdef1234"sv));
+ CHECK(V2ValueContentIdRequest.ValueContentId == IoHash::FromHexString("56789abcdef12345678956789abcdef123456789"sv));
+
+ HttpRequestData Invalid;
+ CHECK(!HttpRequestParseRelativeUri("api/v2/bla", Invalid));
+ CHECK(!HttpRequestParseRelativeUri("api/v2//", Invalid));
+ CHECK(!HttpRequestParseRelativeUri("api/v2/ns_bad\2_namespace", Invalid));
+ CHECK(!HttpRequestParseRelativeUri("api/v2/ns_nice/\2\1bucket", Invalid));
+ CHECK(!HttpRequestParseRelativeUri("api/v2/ns_namespace/bucket/0123456789a", Invalid));
+ CHECK(!HttpRequestParseRelativeUri("api/v2/ns_namespace/bucket/pppppppp89abcdef12340123456789abcdef1234", Invalid));
+ CHECK(!HttpRequestParseRelativeUri("api/v2/ns_namespace/bucket/0123456789abcdef12340123456789abcdef1234/56789abcd", Invalid));
+ CHECK(!HttpRequestParseRelativeUri(
+ "api/v2/ns_namespace/bucket/0123456789abcdef12340123456789abcdef1234/ppppppppdef12345678956789abcdef123456789",
+ Invalid));
+}
+
+#endif
+
+void
+z$service_forcelink()
+{
+}
+
} // namespace zen
diff --git a/zenserver/cache/structuredcache.h b/zenserver/cache/structuredcache.h
index 40e92c675..ba02b3b14 100644
--- a/zenserver/cache/structuredcache.h
+++ b/zenserver/cache/structuredcache.h
@@ -161,4 +161,6 @@ IsCompressedBinary(ZenContentType Type)
return Type == ZenContentType::kBinary || Type == ZenContentType::kCompressedBinary;
}
+void z$service_forcelink();
+
} // namespace zen
diff --git a/zenserver/cache/structuredcachestore.cpp b/zenserver/cache/structuredcachestore.cpp
index c21945702..5d1d39c50 100644
--- a/zenserver/cache/structuredcachestore.cpp
+++ b/zenserver/cache/structuredcachestore.cpp
@@ -2128,8 +2128,6 @@ ZenCacheDiskLayer::TotalSize() const
//////////////////////////// ZenCacheStore
-static constexpr std::string_view ZenCacheNamespaceDirPrefix = "ns_";
-
ZenCacheStore::ZenCacheStore(CasGc& Gc, std::filesystem::path BasePath) : GcStorage(Gc), GcContributor(Gc)
{
CreateDirectories(BasePath);
@@ -2142,7 +2140,7 @@ ZenCacheStore::ZenCacheStore(CasGc& Gc, std::filesystem::path BasePath) : GcStor
for (const std::filesystem::path& DirPath : DirContent.Directories)
{
std::string DirName = PathToUtf8(DirPath.stem());
- if (DirName.starts_with(ZenCacheNamespaceDirPrefix))
+ if (DirName.starts_with(NamespacePrefix))
{
Namespaces.push_back(DirName.substr(3));
continue;
@@ -2155,7 +2153,7 @@ ZenCacheStore::ZenCacheStore(CasGc& Gc, std::filesystem::path BasePath) : GcStor
if (std::find(Namespaces.begin(), Namespaces.end(), DefaultNamespace) == Namespaces.end())
{
ZEN_INFO("Moving #{} legacy buckets to anonymous namespace", LegacyBuckets.size());
- std::filesystem::path DefaultNamespaceFolder = BasePath / fmt::format("{}{}", ZenCacheNamespaceDirPrefix, DefaultNamespace);
+ std::filesystem::path DefaultNamespaceFolder = BasePath / fmt::format("{}{}", NamespacePrefix, DefaultNamespace);
CreateDirectories(DefaultNamespaceFolder);
// Move any non-namespace folders into the default namespace folder
@@ -2176,7 +2174,7 @@ ZenCacheStore::ZenCacheStore(CasGc& Gc, std::filesystem::path BasePath) : GcStor
for (const std::string& NamespaceName : Namespaces)
{
m_Namespaces[NamespaceName] =
- std::make_unique<ZenCacheNamespace>(Gc, BasePath / fmt::format("{}{}", ZenCacheNamespaceDirPrefix, NamespaceName));
+ std::make_unique<ZenCacheNamespace>(Gc, BasePath / fmt::format("{}{}", NamespacePrefix, NamespaceName));
}
}
@@ -2284,8 +2282,9 @@ ZenCacheStore::StorageSize() const
//////////////////////////////////////////////////////////////////////////
+} // namespace zen
+
#if ZEN_WITH_TESTS
-}
namespace zen {
diff --git a/zenserver/cache/structuredcachestore.h b/zenserver/cache/structuredcachestore.h
index 881285bc9..b6d06432c 100644
--- a/zenserver/cache/structuredcachestore.h
+++ b/zenserver/cache/structuredcachestore.h
@@ -357,6 +357,7 @@ class ZenCacheStore final : public GcStorage, public GcContributor
{
public:
static constexpr std::string_view DefaultNamespace = "";
+ static constexpr std::string_view NamespacePrefix = "ns_";
ZenCacheStore(CasGc& Gc, std::filesystem::path BasePath);
~ZenCacheStore();
diff --git a/zenserver/zenserver.cpp b/zenserver/zenserver.cpp
index abaec888a..9e6c67d34 100644
--- a/zenserver/zenserver.cpp
+++ b/zenserver/zenserver.cpp
@@ -1155,6 +1155,7 @@ test_main(int argc, char** argv)
zen::zenhttp_forcelinktests();
zen::zenstore_forcelinktests();
zen::z$_forcelink();
+ zen::z$service_forcelink();
zen::logging::InitializeLogging();
spdlog::set_level(spdlog::level::debug);