aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-03-26 13:28:07 +0100
committerGitHub Enterprise <[email protected]>2024-03-26 13:28:07 +0100
commit66cf5342b2fe8bd3f2961dc70b9c302bf4de12bf (patch)
tree16dfe666651653f03342dd502e85bbfecd4448c2 /src
parentremove redundant json11 includes (diff)
downloadzen-66cf5342b2fe8bd3f2961dc70b9c302bf4de12bf.tar.xz
zen-66cf5342b2fe8bd3f2961dc70b9c302bf4de12bf.zip
add filter to projectstore entries request (#25)
* Add HttpServerRequest::Decode to decode http request parameters * Add support to filter projectstore `entries` request using the `fieldfilter` where the wanted fields are comma (,) delimited * Add support for responding with compressed payloads for projectstore `entries` requests by adding AcceptType `compressed-binary` to the request header * Add support for responding with compressed payloads for projectstore `files` requests by adding AcceptType `compressed-binary` to the request header * Add support for responding with compressed payloads for projectstore `chunkinfo` requests by adding AcceptType `compressed-binary` to the request header
Diffstat (limited to 'src')
-rw-r--r--src/zenhttp/httpserver.cpp34
-rw-r--r--src/zenhttp/include/zenhttp/httpserver.h2
-rw-r--r--src/zenserver/projectstore/httpprojectstore.cpp71
3 files changed, 101 insertions, 6 deletions
diff --git a/src/zenhttp/httpserver.cpp b/src/zenhttp/httpserver.cpp
index dcbeac907..adb3128bf 100644
--- a/src/zenhttp/httpserver.cpp
+++ b/src/zenhttp/httpserver.cpp
@@ -530,6 +530,40 @@ HttpServerRequest::WriteResponse(HttpResponseCode ResponseCode, HttpContentType
WriteResponse(ResponseCode, ContentType, Buffers);
}
+std::string
+HttpServerRequest::Decode(std::string_view PercentEncodedString)
+{
+ size_t Length = PercentEncodedString.length();
+ std::string Decoded;
+ Decoded.reserve(Length);
+ size_t Offset = 0;
+ while (Offset < Length)
+ {
+ char C = PercentEncodedString[Offset];
+ if (C == '%' && (Offset <= (Length - 3)))
+ {
+ std::string_view CharHash(&PercentEncodedString[Offset + 1], 2);
+ uint8_t DecodedChar = 0;
+ if (ParseHexBytes(CharHash, &DecodedChar))
+ {
+ Decoded.push_back((char)DecodedChar);
+ Offset += 3;
+ }
+ else
+ {
+ Decoded.push_back(C);
+ Offset++;
+ }
+ }
+ else
+ {
+ Decoded.push_back(C);
+ Offset++;
+ }
+ }
+ return Decoded;
+}
+
HttpServerRequest::QueryParams
HttpServerRequest::GetQueryParams()
{
diff --git a/src/zenhttp/include/zenhttp/httpserver.h b/src/zenhttp/include/zenhttp/httpserver.h
index 1089dd221..7b87cb84b 100644
--- a/src/zenhttp/include/zenhttp/httpserver.h
+++ b/src/zenhttp/include/zenhttp/httpserver.h
@@ -62,6 +62,8 @@ public:
}
};
+ static std::string Decode(std::string_view PercentEncodedString);
+
virtual bool TryGetRanges(HttpRanges&) { return false; }
QueryParams GetQueryParams();
diff --git a/src/zenserver/projectstore/httpprojectstore.cpp b/src/zenserver/projectstore/httpprojectstore.cpp
index 260f60cfe..e8a748c4c 100644
--- a/src/zenserver/projectstore/httpprojectstore.cpp
+++ b/src/zenserver/projectstore/httpprojectstore.cpp
@@ -6,6 +6,7 @@
#include <zencore/compactbinarybuilder.h>
#include <zencore/compactbinarypackage.h>
+#include <zencore/compactbinaryutil.h>
#include <zencore/filesystem.h>
#include <zencore/fmtutils.h>
#include <zencore/logging.h>
@@ -626,7 +627,15 @@ HttpProjectService::HandleFilesRequest(HttpRouterRequest& Req)
std::pair<HttpResponseCode, std::string> Result = m_ProjectStore->GetProjectFiles(ProjectId, OplogId, FilterClient, ResponsePayload);
if (Result.first == HttpResponseCode::OK)
{
- return HttpReq.WriteResponse(HttpResponseCode::OK, ResponsePayload);
+ if (HttpReq.AcceptContentType() == HttpContentType::kCompressedBinary)
+ {
+ CompositeBuffer Payload = CompressedBuffer::Compress(ResponsePayload.GetBuffer()).GetCompressed();
+ return HttpReq.WriteResponse(HttpResponseCode::OK, HttpContentType::kCompressedBinary, Payload);
+ }
+ else
+ {
+ return HttpReq.WriteResponse(HttpResponseCode::OK, ResponsePayload);
+ }
}
else
{
@@ -661,7 +670,15 @@ HttpProjectService::HandleChunkInfosRequest(HttpRouterRequest& Req)
std::pair<HttpResponseCode, std::string> Result = m_ProjectStore->GetProjectChunkInfos(ProjectId, OplogId, ResponsePayload);
if (Result.first == HttpResponseCode::OK)
{
- return HttpReq.WriteResponse(HttpResponseCode::OK, ResponsePayload);
+ if (HttpReq.AcceptContentType() == HttpContentType::kCompressedBinary)
+ {
+ CompositeBuffer Payload = CompressedBuffer::Compress(ResponsePayload.GetBuffer()).GetCompressed();
+ return HttpReq.WriteResponse(HttpResponseCode::OK, HttpContentType::kCompressedBinary, Payload);
+ }
+ else
+ {
+ return HttpReq.WriteResponse(HttpResponseCode::OK, ResponsePayload);
+ }
}
else
{
@@ -1369,7 +1386,28 @@ HttpProjectService::HandleOpLogEntriesRequest(HttpRouterRequest& Req)
if (FoundLog->OplogCount() > 0)
{
+ std::unordered_set<std::string> FieldNamesFilter;
+ auto FilterObject = [&FieldNamesFilter](CbObjectView& Object) -> CbObject {
+ CbObject RewrittenOp = RewriteCbObject(Object, [&FieldNamesFilter](CbObjectWriter&, CbFieldView Field) -> bool {
+ if (FieldNamesFilter.contains(std::string(Field.GetName())))
+ {
+ return false;
+ }
+
+ return true;
+ });
+
+ return RewrittenOp;
+ };
+
HttpServerRequest::QueryParams Params = HttpReq.GetQueryParams();
+ if (auto FieldFilter = HttpServerRequest::Decode(Params.GetValue("fieldfilter")); !FieldFilter.empty())
+ {
+ ForEachStrTok(FieldFilter, ',', [&](std::string_view FieldName) {
+ FieldNamesFilter.insert(std::string(FieldName));
+ return true;
+ });
+ }
if (auto OpKey = Params.GetValue("opkey"); !OpKey.empty())
{
@@ -1378,7 +1416,14 @@ HttpProjectService::HandleOpLogEntriesRequest(HttpRouterRequest& Req)
if (Op.has_value())
{
- Response << "entry"sv << Op.value();
+ if (FieldNamesFilter.empty())
+ {
+ Response << "entry"sv << Op.value();
+ }
+ else
+ {
+ Response << "entry"sv << FilterObject(Op.value());
+ }
}
else
{
@@ -1389,13 +1434,27 @@ HttpProjectService::HandleOpLogEntriesRequest(HttpRouterRequest& Req)
{
Response.BeginArray("entries"sv);
- FoundLog->IterateOplog([&Response](CbObjectView Op) { Response << Op; });
+ if (FieldNamesFilter.empty())
+ {
+ FoundLog->IterateOplog([&Response](CbObjectView Op) { Response << Op; });
+ }
+ else
+ {
+ FoundLog->IterateOplog([this, &Response, &FilterObject](CbObjectView Op) { Response << FilterObject(Op); });
+ }
Response.EndArray();
}
}
-
- return HttpReq.WriteResponse(HttpResponseCode::OK, Response.Save());
+ if (HttpReq.AcceptContentType() == HttpContentType::kCompressedBinary)
+ {
+ CompositeBuffer Payload = CompressedBuffer::Compress(Response.Save().GetBuffer()).GetCompressed();
+ return HttpReq.WriteResponse(HttpResponseCode::OK, HttpContentType::kCompressedBinary, Payload);
+ }
+ else
+ {
+ return HttpReq.WriteResponse(HttpResponseCode::OK, Response.Save());
+ }
}
void