diff options
| author | Dan Engelbrecht <[email protected]> | 2023-01-26 01:04:38 -0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-01-26 01:04:38 -0800 |
| commit | 80e91f8ce89e1a36b0e55540e78555f9dd3bfbca (patch) | |
| tree | 84efdc20ea2d23096130641830f0fc62e4fa2969 /zenserver/projectstore.cpp | |
| parent | Fixed macro leaking out (diff) | |
| download | zen-80e91f8ce89e1a36b0e55540e78555f9dd3bfbca.tar.xz zen-80e91f8ce89e1a36b0e55540e78555f9dd3bfbca.zip | |
Better error responses/logging in project store request (#217)
* Better error responses/logging in project store request
* changelog
Diffstat (limited to 'zenserver/projectstore.cpp')
| -rw-r--r-- | zenserver/projectstore.cpp | 232 |
1 files changed, 139 insertions, 93 deletions
diff --git a/zenserver/projectstore.cpp b/zenserver/projectstore.cpp index 1779bfb3c..1885a6b1c 100644 --- a/zenserver/projectstore.cpp +++ b/zenserver/projectstore.cpp @@ -1477,7 +1477,7 @@ ProjectStore::GetProjectsList() return Response.Save().AsArray(); } -HttpResponseCode +std::pair<HttpResponseCode, std::string> ProjectStore::GetProjectFiles(const std::string_view ProjectId, const std::string_view OplogId, bool FilterClient, CbObject& OutPayload) { using namespace std::literals; @@ -1485,16 +1485,14 @@ ProjectStore::GetProjectFiles(const std::string_view ProjectId, const std::strin Ref<ProjectStore::Project> Project = OpenProject(ProjectId); if (!Project) { - ZEN_INFO("Project file request for unknown project '{}'", ProjectId); - return HttpResponseCode::NotFound; + return {HttpResponseCode::NotFound, fmt::format("Project files request for unknown project '{}'", ProjectId)}; } ProjectStore::Oplog* FoundLog = Project->OpenOplog(OplogId); if (!FoundLog) { - ZEN_INFO("Project file for unknown oplog '{}/{}'", ProjectId, OplogId); - return HttpResponseCode::NotFound; + return {HttpResponseCode::NotFound, fmt::format("Project files for unknown oplog '{}/{}'", ProjectId, OplogId)}; } CbObjectWriter Response; @@ -1513,10 +1511,10 @@ ProjectStore::GetProjectFiles(const std::string_view ProjectId, const std::strin Response.EndArray(); OutPayload = Response.Save(); - return HttpResponseCode::OK; + return {HttpResponseCode::OK, {}}; } -HttpResponseCode +std::pair<HttpResponseCode, std::string> ProjectStore::GetChunkInfo(const std::string_view ProjectId, const std::string_view OplogId, const std::string_view ChunkId, @@ -1527,21 +1525,19 @@ ProjectStore::GetChunkInfo(const std::string_view ProjectId, Ref<ProjectStore::Project> Project = OpenProject(ProjectId); if (!Project) { - ZEN_INFO("Chunk info request for unknown project '{}'", ProjectId); - return HttpResponseCode::NotFound; + return {HttpResponseCode::NotFound, fmt::format("Chunk info request for unknown project '{}'", ProjectId)}; } ProjectStore::Oplog* FoundLog = Project->OpenOplog(OplogId); if (!FoundLog) { - ZEN_INFO("Chunk info request for unknown oplog '{}/{}'", ProjectId, OplogId); - return HttpResponseCode::NotFound; + return {HttpResponseCode::NotFound, fmt::format("Chunk info request for unknown oplog '{}/{}'", ProjectId, OplogId)}; } if (ChunkId.size() != 2 * sizeof(Oid::OidBits)) { - ZEN_INFO("Chunk info request for invalid chunk id '{}/{}'/'{}'", ProjectId, OplogId, ChunkId); - return HttpResponseCode::BadRequest; + return {HttpResponseCode::BadRequest, + fmt::format("Chunk info request for invalid chunk id '{}/{}'/'{}'", ProjectId, OplogId, ChunkId)}; } const Oid Obj = Oid::FromHexString(ChunkId); @@ -1549,8 +1545,7 @@ ProjectStore::GetChunkInfo(const std::string_view ProjectId, IoBuffer Chunk = FoundLog->FindChunk(Obj); if (!Chunk) { - ZEN_DEBUG("chunk - '{}/{}/{}' MISSING", ProjectId, OplogId, ChunkId); - return HttpResponseCode::NotFound; + return {HttpResponseCode::NotFound, {}}; } uint64_t ChunkSize = Chunk.GetSize(); @@ -1566,39 +1561,36 @@ ProjectStore::GetChunkInfo(const std::string_view ProjectId, CbObjectWriter Response; Response << "size"sv << ChunkSize; OutPayload = Response.Save(); - return HttpResponseCode::OK; + return {HttpResponseCode::OK, {}}; } -HttpResponseCode -ProjectStore::GetChunk(const std::string_view ProjectId, - const std::string_view OplogId, - const std::string_view ChunkId, - uint64_t Offset, - uint64_t Size, - ZenContentType AcceptType, - IoBuffer& OutChunk) +std::pair<HttpResponseCode, std::string> +ProjectStore::GetChunkRange(const std::string_view ProjectId, + const std::string_view OplogId, + const std::string_view ChunkId, + uint64_t Offset, + uint64_t Size, + ZenContentType AcceptType, + IoBuffer& OutChunk) { bool IsOffset = Offset != 0 || Size != ~(0ull); Ref<ProjectStore::Project> Project = OpenProject(ProjectId); if (!Project) { - ZEN_INFO("Chunk request for unknown project '{}'", ProjectId); - return HttpResponseCode::NotFound; + return {HttpResponseCode::NotFound, fmt::format("Chunk request for unknown project '{}'", ProjectId)}; } ProjectStore::Oplog* FoundLog = Project->OpenOplog(OplogId); if (!FoundLog) { - ZEN_INFO("Chunk request for unknown oplog '{}/{}'", ProjectId, OplogId); - return HttpResponseCode::NotFound; + return {HttpResponseCode::NotFound, fmt::format("Chunk info request for unknown oplog '{}/{}'", ProjectId, OplogId)}; } if (ChunkId.size() != 2 * sizeof(Oid::OidBits)) { - ZEN_INFO("Chunk request for invalid chunk id '{}/{}/{}'", ProjectId, OplogId, ChunkId); - return HttpResponseCode::BadRequest; + return {HttpResponseCode::BadRequest, fmt::format("Chunk request for invalid chunk id '{}/{}'/'{}'", ProjectId, OplogId, ChunkId)}; } const Oid Obj = Oid::FromHexString(ChunkId); @@ -1606,8 +1598,7 @@ ProjectStore::GetChunk(const std::string_view ProjectId, IoBuffer Chunk = FoundLog->FindChunk(Obj); if (!Chunk) { - ZEN_DEBUG("chunk - '{}/{}/{}' MISSING", ProjectId, OplogId, ChunkId); - return HttpResponseCode::NotFound; + return {HttpResponseCode::NotFound, {}}; } OutChunk = Chunk; @@ -1664,20 +1655,34 @@ ProjectStore::GetChunk(const std::string_view ProjectId, OutChunk.SetContentType(ContentType); } - ZEN_DEBUG("chunk - '{}/{}/{}' '{}'", ProjectId, OplogId, ChunkId, ToString(ContentType)); - - return HttpResponseCode::OK; + return {HttpResponseCode::OK, {}}; } -HttpResponseCode -ProjectStore::GetChunk(const std::string_view Cid, ZenContentType AcceptType, IoBuffer& OutChunk) +std::pair<HttpResponseCode, std::string> +ProjectStore::GetChunk(const std::string_view ProjectId, + const std::string_view OplogId, + const std::string_view Cid, + ZenContentType AcceptType, + IoBuffer& OutChunk) { using namespace std::literals; + Ref<ProjectStore::Project> Project = OpenProject(ProjectId); + if (!Project) + { + return {HttpResponseCode::NotFound, fmt::format("Chunk request for unknown project '{}'", ProjectId)}; + } + + ProjectStore::Oplog* FoundLog = Project->OpenOplog(OplogId); + + if (!FoundLog) + { + return {HttpResponseCode::NotFound, fmt::format("Chunk info request for unknown oplog '{}/{}'", ProjectId, OplogId)}; + } + if (Cid.length() != IoHash::StringLength) { - ZEN_INFO("Chunk request for invalid chunk hash '{}'", Cid); - return HttpResponseCode::BadRequest; + return {HttpResponseCode::BadRequest, fmt::format("Chunk request for invalid chunk id '{}/{}'/'{}'", ProjectId, OplogId, Cid)}; } const IoHash Hash = IoHash::FromHexString(Cid); @@ -1685,8 +1690,7 @@ ProjectStore::GetChunk(const std::string_view Cid, ZenContentType AcceptType, Io if (!OutChunk) { - ZEN_DEBUG("chunk - '{}' MISSING", Cid); - return HttpResponseCode::NotFound; + return {HttpResponseCode::NotFound, fmt::format("chunk - '{}' MISSING", Cid)}; } if (AcceptType == HttpContentType::kBinary) @@ -1699,7 +1703,7 @@ ProjectStore::GetChunk(const std::string_view Cid, ZenContentType AcceptType, Io { OutChunk.SetContentType(HttpContentType::kCompressedBinary); } - return HttpResponseCode::OK; + return {HttpResponseCode::OK, {}}; } ////////////////////////////////////////////////////////////////////////// @@ -1871,13 +1875,23 @@ HttpProjectService::HttpProjectService(CidStore& Store, ProjectStore* Projects) const bool FilterClient = Params.GetValue("filter"sv) == "client"sv; - CbObject ResponsePayload; - HttpResponseCode Response = m_ProjectStore->GetProjectFiles(ProjectId, OplogId, FilterClient, ResponsePayload); - if (Response != HttpResponseCode::OK) + CbObject ResponsePayload; + std::pair<HttpResponseCode, std::string> Result = + m_ProjectStore->GetProjectFiles(ProjectId, OplogId, FilterClient, ResponsePayload); + if (Result.first == HttpResponseCode::OK) { - return HttpReq.WriteResponse(Response); + return HttpReq.WriteResponse(HttpResponseCode::OK, ResponsePayload); } - return HttpReq.WriteResponse(Response, ResponsePayload); + else + { + ZEN_DEBUG("Request {}: '{}' failed with {}. Reason: `{}`", + ToString(HttpReq.RequestVerb()), + HttpReq.QueryString(), + static_cast<int>(Result.first), + Result.second); + } + + return HttpReq.WriteResponse(Result.first, HttpContentType::kText, Result.second); }, HttpVerb::kGet); @@ -1890,13 +1904,25 @@ HttpProjectService::HttpProjectService(CidStore& Store, ProjectStore* Projects) const auto& OplogId = Req.GetCapture(2); const auto& ChunkId = Req.GetCapture(3); - CbObject ResponsePayload; - HttpResponseCode Response = m_ProjectStore->GetChunkInfo(ProjectId, OplogId, ChunkId, ResponsePayload); - if (Response != HttpResponseCode::OK) + CbObject ResponsePayload; + std::pair<HttpResponseCode, std::string> Result = m_ProjectStore->GetChunkInfo(ProjectId, OplogId, ChunkId, ResponsePayload); + if (Result.first == HttpResponseCode::OK) + { + return HttpReq.WriteResponse(HttpResponseCode::OK, ResponsePayload); + } + else if (Result.first == HttpResponseCode::NotFound) { - return HttpReq.WriteResponse(Response); + ZEN_DEBUG("chunk - '{}/{}/{}' MISSING", ProjectId, OplogId, ChunkId); } - HttpReq.WriteResponse(HttpResponseCode::OK, ResponsePayload); + else + { + ZEN_DEBUG("Request {}: '{}' failed with {}. Reason: `{}`", + ToString(HttpReq.RequestVerb()), + HttpReq.QueryString(), + static_cast<int>(Result.first), + Result.second); + } + return HttpReq.WriteResponse(Result.first, HttpContentType::kText, Result.second); }, HttpVerb::kGet); @@ -1940,15 +1966,27 @@ HttpProjectService::HttpProjectService(CidStore& Store, ProjectStore* Projects) HttpContentType AcceptType = HttpReq.AcceptContentType(); - IoBuffer Chunk; - HttpResponseCode Response = m_ProjectStore->GetChunk(ProjectId, OplogId, ChunkId, Offset, Size, AcceptType, Chunk); - if (Response != HttpResponseCode::OK) + IoBuffer Chunk; + std::pair<HttpResponseCode, std::string> Result = + m_ProjectStore->GetChunkRange(ProjectId, OplogId, ChunkId, Offset, Size, AcceptType, Chunk); + if (Result.first == HttpResponseCode::OK) { - return HttpReq.WriteResponse(Response); + ZEN_DEBUG("chunk - '{}/{}/{}' '{}'", ProjectId, OplogId, ChunkId, ToString(Chunk.GetContentType())); + return HttpReq.WriteResponse(HttpResponseCode::OK, Chunk.GetContentType(), Chunk); } - - m_Log.debug("chunk - '{}/{}/{}' '{}'", ProjectId, OplogId, ChunkId, ToString(Chunk.GetContentType())); - return HttpReq.WriteResponse(HttpResponseCode::OK, Chunk.GetContentType(), Chunk); + else if (Result.first == HttpResponseCode::NotFound) + { + ZEN_DEBUG("chunk - '{}/{}/{}' MISSING", ProjectId, OplogId, ChunkId); + } + else + { + ZEN_DEBUG("Request {}: '{}' failed with {}. Reason: `{}`", + ToString(HttpReq.RequestVerb()), + HttpReq.QueryString(), + static_cast<int>(Result.first), + Result.second); + } + return HttpReq.WriteResponse(Result.first, HttpContentType::kText, Result.second); }, HttpVerb::kGet | HttpVerb::kHead); @@ -1957,31 +1995,31 @@ HttpProjectService::HttpProjectService(CidStore& Store, ProjectStore* Projects) [this](HttpRouterRequest& Req) { HttpServerRequest& HttpReq = Req.ServerRequest(); - const auto& HashString = Req.GetCapture(3); - IoHash Hash = IoHash::FromHexString(HashString); + const auto& ProjectId = Req.GetCapture(1); + const auto& OplogId = Req.GetCapture(2); + const auto& Cid = Req.GetCapture(3); HttpContentType AcceptType = HttpReq.AcceptContentType(); - if (AcceptType == HttpContentType::kUnknownContentType) + IoBuffer Value; + std::pair<HttpResponseCode, std::string> Result = m_ProjectStore->GetChunk(ProjectId, OplogId, Cid, AcceptType, Value); + + if (Result.first == HttpResponseCode::OK) { - AcceptType = HttpContentType::kBinary; + return HttpReq.WriteResponse(HttpResponseCode::OK, Value.GetContentType(), Value); } - - HttpContentType ContentType = HttpContentType::kCompressedBinary; - IoBuffer Value = m_CidStore.FindChunkByCid(Hash); - - if (!Value) + else if (Result.first == HttpResponseCode::NotFound) { - return HttpReq.WriteResponse(HttpResponseCode::NotFound); + ZEN_DEBUG("chunk - '{}/{}/{}' MISSING", ProjectId, OplogId, Cid); } - - if (AcceptType == HttpContentType::kBinary) + else { - CompressedBuffer Compressed = CompressedBuffer::FromCompressedNoValidate(std::move(Value)); - Value = Compressed.Decompress().AsIoBuffer(); - ContentType = HttpContentType::kBinary; + ZEN_DEBUG("Request {}: '{}' failed with {}. Reason: `{}`", + ToString(HttpReq.RequestVerb()), + HttpReq.QueryString(), + static_cast<int>(Result.first), + Result.second); } - - return HttpReq.WriteResponse(HttpResponseCode::OK, ContentType, Value); + return HttpReq.WriteResponse(Result.first, HttpContentType::kText, Result.second); }, HttpVerb::kGet); @@ -2994,9 +3032,13 @@ TEST_CASE("project.store.partial.read") } { IoBuffer Chunk; - CHECK(ProjectStore.GetChunk(Attachments[OpIds[1]][0].second.DecodeRawHash().ToHexString(), - HttpContentType::kCompressedBinary, - Chunk) == HttpResponseCode::OK); + CHECK(ProjectStore + .GetChunk("proj1"sv, + "oplog1"sv, + Attachments[OpIds[1]][0].second.DecodeRawHash().ToHexString(), + HttpContentType::kCompressedBinary, + Chunk) + .first == HttpResponseCode::OK); IoHash RawHash; uint64_t RawSize; CompressedBuffer Attachment = CompressedBuffer::FromCompressed(SharedBuffer(Chunk), RawHash, RawSize); @@ -3004,25 +3046,29 @@ TEST_CASE("project.store.partial.read") } IoBuffer ChunkResult; - CHECK(ProjectStore.GetChunk("proj1"sv, - "oplog1"sv, - OidAsString(Attachments[OpIds[2]][1].first), - 0, - ~0ull, - HttpContentType::kCompressedBinary, - ChunkResult) == HttpResponseCode::OK); + CHECK(ProjectStore + .GetChunkRange("proj1"sv, + "oplog1"sv, + OidAsString(Attachments[OpIds[2]][1].first), + 0, + ~0ull, + HttpContentType::kCompressedBinary, + ChunkResult) + .first == HttpResponseCode::OK); CHECK(ChunkResult); CHECK(CompressedBuffer::FromCompressedNoValidate(std::move(ChunkResult)).DecodeRawSize() == Attachments[OpIds[2]][1].second.DecodeRawSize()); IoBuffer PartialChunkResult; - CHECK(ProjectStore.GetChunk("proj1"sv, - "oplog1"sv, - OidAsString(Attachments[OpIds[2]][1].first), - 5, - 1773, - HttpContentType::kCompressedBinary, - PartialChunkResult) == HttpResponseCode::OK); + CHECK(ProjectStore + .GetChunkRange("proj1"sv, + "oplog1"sv, + OidAsString(Attachments[OpIds[2]][1].first), + 5, + 1773, + HttpContentType::kCompressedBinary, + PartialChunkResult) + .first == HttpResponseCode::OK); CHECK(PartialChunkResult); IoHash PartialRawHash; uint64_t PartialRawSize; |