aboutsummaryrefslogtreecommitdiff
path: root/zenserver/cache/structuredcache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'zenserver/cache/structuredcache.cpp')
-rw-r--r--zenserver/cache/structuredcache.cpp168
1 files changed, 142 insertions, 26 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