diff options
Diffstat (limited to 'zenserver/cache/structuredcache.cpp')
| -rw-r--r-- | zenserver/cache/structuredcache.cpp | 168 |
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 |