aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-09-08 08:55:38 +0200
committerGitHub <[email protected]>2022-09-07 23:55:38 -0700
commitc96d28abc6c2c526295ec8ef9b7959b0ff862d23 (patch)
tree7b1e116a3184bb38a47621660f11871c1cd254ff
parentImplement proper GetCacheValues upstream (#155) (diff)
downloadzen-c96d28abc6c2c526295ec8ef9b7959b0ff862d23.tar.xz
zen-c96d28abc6c2c526295ec8ef9b7959b0ff862d23.zip
Added CloudCacheSession::GetInlineBlob to properly get CacheValues (#159)
* Added CloudCacheSession::GetInlineBlob to properly get CacheValues from Horde Issue #UE-162151 * validate uncompressed binary from Horde "application/x-jupiter-inline" response
-rw-r--r--CHANGELOG.md1
-rw-r--r--zenserver/upstream/jupiter.cpp34
-rw-r--r--zenserver/upstream/jupiter.h1
-rw-r--r--zenserver/upstream/upstreamcache.cpp28
4 files changed, 60 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b3378372e..0951e703a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@
- Bugfix: Fixed issue where projects would not be discovered via DiscoverProjects due to use of stem() vs filename()
- Bugfix: Use "\\\\?\\" prefixed paths on Windows and fix hardcoded path delimiters (UE-141222)
- Bugfix: Safer detection of html folder when running non-bundled executable
+- Bugfix: Use "application/x-jupiter-inline" to fetch GetCacheValues from Horde (UE-162151)
- Sentry: Added logging of sentry_init error code
- Sentry: Attach log file to Sentry error reports
- Sentry: Capture capture error/critical log statements as errors in Sentry
diff --git a/zenserver/upstream/jupiter.cpp b/zenserver/upstream/jupiter.cpp
index 65fa1da92..b82290f3d 100644
--- a/zenserver/upstream/jupiter.cpp
+++ b/zenserver/upstream/jupiter.cpp
@@ -181,6 +181,40 @@ CloudCacheSession::GetCompressedBlob(std::string_view Namespace, const IoHash& K
}
CloudCacheResult
+CloudCacheSession::GetInlineBlob(std::string_view Namespace, std::string_view BucketId, const IoHash& Key, IoHash& OutPayloadHash)
+{
+ ZEN_TRACE_CPU("HordeClient::GetInlineBlob");
+
+ ExtendableStringBuilder<256> Uri;
+ Uri << m_CacheClient->ServiceUrl() << "/api/v1/refs/" << Namespace << "/" << BucketId << "/" << Key.ToHexString();
+
+ cpr::Session& Session = GetSession();
+ const CloudCacheAccessToken& AccessToken = GetAccessToken();
+
+ Session.SetOption(cpr::Url{Uri.c_str()});
+ Session.SetOption(cpr::Header{{"Authorization", AccessToken.Value}, {"Accept", "application/x-jupiter-inline"}});
+ Session.SetOption(cpr::Body{});
+
+ cpr::Response Response = Session.Get();
+ ZEN_DEBUG("GET {}", Response);
+
+ if (Response.error)
+ {
+ return {.ErrorCode = static_cast<int32_t>(Response.error.code), .Reason = Response.error.message};
+ }
+ else if (!VerifyAccessToken(Response.status_code))
+ {
+ return {.ErrorCode = 401, .Reason = std::string("Invalid access token")};
+ }
+
+ const bool Success = Response.status_code == 200;
+ const IoBuffer Buffer = Success ? IoBufferBuilder::MakeCloneFromMemory(Response.text.data(), Response.text.size()) : IoBuffer();
+ OutPayloadHash = IoHash::FromHexString(Response.header["X-Jupiter-InlinePayloadHash"]);
+
+ return {.Response = Buffer, .Bytes = Response.downloaded_bytes, .ElapsedSeconds = Response.elapsed, .Success = Success};
+}
+
+CloudCacheResult
CloudCacheSession::GetObject(std::string_view Namespace, const IoHash& Key)
{
ZEN_TRACE_CPU("HordeClient::GetObject");
diff --git a/zenserver/upstream/jupiter.h b/zenserver/upstream/jupiter.h
index 4e5e38d6f..88ab77247 100644
--- a/zenserver/upstream/jupiter.h
+++ b/zenserver/upstream/jupiter.h
@@ -99,6 +99,7 @@ public:
CloudCacheResult GetBlob(std::string_view Namespace, const IoHash& Key);
CloudCacheResult GetCompressedBlob(std::string_view Namespace, const IoHash& Key);
CloudCacheResult GetObject(std::string_view Namespace, const IoHash& Key);
+ CloudCacheResult GetInlineBlob(std::string_view Namespace, std::string_view BucketId, const IoHash& Key, IoHash& OutPayloadHash);
PutRefResult PutRef(std::string_view Namespace, std::string_view BucketId, const IoHash& Key, IoBuffer Ref, ZenContentType RefType);
CloudCacheResult PutBlob(std::string_view Namespace, const IoHash& Key, IoBuffer Blob);
diff --git a/zenserver/upstream/upstreamcache.cpp b/zenserver/upstream/upstreamcache.cpp
index 7f5759e47..e92dde815 100644
--- a/zenserver/upstream/upstreamcache.cpp
+++ b/zenserver/upstream/upstreamcache.cpp
@@ -442,15 +442,35 @@ namespace detail {
if (!Result.Error)
{
std::string_view BlobStoreNamespace = GetActualBlobStoreNamespace(Session, Namespace);
- const CloudCacheResult BlobResult = Session.GetCompressedBlob(BlobStoreNamespace, IoHash::Zero);
- Payload = BlobResult.Response;
+ IoHash PayloadHash;
+ const CloudCacheResult BlobResult =
+ Session.GetInlineBlob(BlobStoreNamespace, Request.Key.Bucket, Request.Key.Hash, PayloadHash);
+ Payload = BlobResult.Response;
AppendResult(BlobResult, Result);
m_Status.SetFromErrorCode(BlobResult.ErrorCode, BlobResult.Reason);
- if (Payload && IsCompressedBinary(Payload.GetContentType()))
+ if (Payload)
{
- Compressed = CompressedBuffer::FromCompressed(SharedBuffer(Payload));
+ if (IsCompressedBinary(Payload.GetContentType()))
+ {
+ Compressed = CompressedBuffer::FromCompressed(SharedBuffer(Payload));
+ }
+ else
+ {
+ Compressed = CompressedBuffer::Compress(SharedBuffer(Payload));
+ IoHash RawHash = IoHash::FromBLAKE3(Compressed.GetRawHash());
+ if (RawHash != PayloadHash)
+ {
+ ZEN_WARN("Horde request for inline payload of {}/{}/{} has hash {}, expected hash {} from header",
+ Namespace,
+ Request.Key.Bucket,
+ Request.Key.Hash.ToHexString(),
+ RawHash.ToHexString(),
+ PayloadHash.ToHexString());
+ Compressed.Reset();
+ }
+ }
}
}