diff options
| author | Dan Engelbrecht <[email protected]> | 2022-09-08 08:55:38 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-09-07 23:55:38 -0700 |
| commit | c96d28abc6c2c526295ec8ef9b7959b0ff862d23 (patch) | |
| tree | 7b1e116a3184bb38a47621660f11871c1cd254ff | |
| parent | Implement proper GetCacheValues upstream (#155) (diff) | |
| download | zen-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.md | 1 | ||||
| -rw-r--r-- | zenserver/upstream/jupiter.cpp | 34 | ||||
| -rw-r--r-- | zenserver/upstream/jupiter.h | 1 | ||||
| -rw-r--r-- | zenserver/upstream/upstreamcache.cpp | 28 |
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(); + } + } } } |