aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/cache/httpstructuredcache.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2024-09-23 19:28:26 +0200
committerGitHub Enterprise <[email protected]>2024-09-23 19:28:26 +0200
commitb9d5ea52a837167b08113823f38e53b59b44a7fe (patch)
tree6daa3416de9a7662c287f7267e7c398fccebd27c /src/zenserver/cache/httpstructuredcache.cpp
parentgc unused refactor (#165) (diff)
downloadzen-b9d5ea52a837167b08113823f38e53b59b44a7fe.tar.xz
zen-b9d5ea52a837167b08113823f38e53b59b44a7fe.zip
Added namespace qualifier (optional) for z$ rpc requests (#166)
This change adds support for a namespace-qualified RPC endpoint for z$ at `/z$/<namespace>/$rpc` which may be used to validate RPC requests by URL inspection. The old scheme is still supported.
Diffstat (limited to 'src/zenserver/cache/httpstructuredcache.cpp')
-rw-r--r--src/zenserver/cache/httpstructuredcache.cpp125
1 files changed, 74 insertions, 51 deletions
diff --git a/src/zenserver/cache/httpstructuredcache.cpp b/src/zenserver/cache/httpstructuredcache.cpp
index 52e31ff40..109fb34f6 100644
--- a/src/zenserver/cache/httpstructuredcache.cpp
+++ b/src/zenserver/cache/httpstructuredcache.cpp
@@ -366,10 +366,27 @@ HttpStructuredCacheService::HandleRequest(HttpServerRequest& Request)
metrics::OperationTiming::Scope $(m_HttpRequests);
- std::string_view Key = Request.RelativeUri();
- if (Key == HttpZCacheRPCPrefix)
+ const std::string_view Key = Request.RelativeUri();
+
+ std::string_view UriNamespace;
+
+ if (Key.ends_with(HttpZCacheRPCPrefix))
{
- return HandleRpcRequest(Request);
+ const size_t RpcOffset = Key.length() - HttpZCacheRPCPrefix.length();
+
+ if (RpcOffset)
+ {
+ std::string_view KeyPrefix = Key.substr(0, RpcOffset);
+
+ if (KeyPrefix.back() == '/')
+ {
+ KeyPrefix.remove_suffix(1);
+
+ UriNamespace = KeyPrefix;
+ }
+ }
+
+ return HandleRpcRequest(Request, UriNamespace);
}
if (Key == HttpZCacheUtilStartRecording)
@@ -1452,6 +1469,7 @@ HttpStructuredCacheService::ReplayRequestRecorder(const CacheRequestContext& Co
int TargetPid = 0;
CbPackage RpcResult;
if (m_RpcHandler.HandleRpcRequest(Context,
+ /* UriNamespace */ {},
RequestInfo.ContentType,
std::move(Body),
AcceptMagic,
@@ -1497,7 +1515,7 @@ HttpStructuredCacheService::ReplayRequestRecorder(const CacheRequestContext& Co
}
void
-HttpStructuredCacheService::HandleRpcRequest(HttpServerRequest& Request)
+HttpStructuredCacheService::HandleRpcRequest(HttpServerRequest& Request, std::string_view UriNamespace)
{
ZEN_TRACE_CPU("z$::Http::HandleRpcRequest");
@@ -1519,65 +1537,70 @@ HttpStructuredCacheService::HandleRpcRequest(HttpServerRequest& Request)
return Request.WriteResponse(HttpResponseCode::BadRequest);
}
- auto HandleRpc =
- [this, RequestContext, Body = Request.ReadPayload(), ContentType, AcceptType](HttpServerRequest& AsyncRequest) mutable {
- if (m_RequestRecordingEnabled)
+ auto HandleRpc = [this,
+ RequestContext,
+ Body = Request.ReadPayload(),
+ ContentType,
+ AcceptType,
+ UriNamespaceString = std::string{UriNamespace}](HttpServerRequest& AsyncRequest) mutable {
+ if (m_RequestRecordingEnabled)
+ {
+ RwLock::SharedLockScope _(m_RequestRecordingLock);
+ if (m_RequestRecorder)
{
- RwLock::SharedLockScope _(m_RequestRecordingLock);
- if (m_RequestRecorder)
- {
- m_RequestRecorder->RecordRequest(
- {.ContentType = ContentType, .AcceptType = AcceptType, .SessionId = RequestContext.SessionId},
- Body);
- }
+ m_RequestRecorder->RecordRequest(
+ {.ContentType = ContentType, .AcceptType = AcceptType, .SessionId = RequestContext.SessionId},
+ Body);
}
+ }
- uint32_t AcceptMagic = 0;
- RpcAcceptOptions AcceptFlags = RpcAcceptOptions::kNone;
- int TargetProcessId = 0;
- CbPackage RpcResult;
+ uint32_t AcceptMagic = 0;
+ RpcAcceptOptions AcceptFlags = RpcAcceptOptions::kNone;
+ int TargetProcessId = 0;
+ CbPackage RpcResult;
- CacheRpcHandler::RpcResponseCode ResultCode = m_RpcHandler.HandleRpcRequest(RequestContext,
- ContentType,
- std::move(Body),
- AcceptMagic,
- AcceptFlags,
- TargetProcessId,
- RpcResult);
+ CacheRpcHandler::RpcResponseCode ResultCode = m_RpcHandler.HandleRpcRequest(RequestContext,
+ UriNamespaceString,
+ ContentType,
+ std::move(Body),
+ /* out */ AcceptMagic,
+ /* out */ AcceptFlags,
+ /* out */ TargetProcessId,
+ /* out */ RpcResult);
- HttpResponseCode HttpResultCode = HttpResponseCode(int(ResultCode));
+ HttpResponseCode HttpResultCode = HttpResponseCode(int(ResultCode));
- if (!IsHttpSuccessCode(HttpResultCode))
- {
- return AsyncRequest.WriteResponse(HttpResultCode);
- }
+ if (!IsHttpSuccessCode(HttpResultCode))
+ {
+ return AsyncRequest.WriteResponse(HttpResultCode);
+ }
- if (AcceptMagic == kCbPkgMagic)
+ if (AcceptMagic == kCbPkgMagic)
+ {
+ void* TargetProcessHandle = nullptr;
+ FormatFlags Flags = FormatFlags::kDefault;
+ if (EnumHasAllFlags(AcceptFlags, RpcAcceptOptions::kAllowLocalReferences))
{
- void* TargetProcessHandle = nullptr;
- FormatFlags Flags = FormatFlags::kDefault;
- if (EnumHasAllFlags(AcceptFlags, RpcAcceptOptions::kAllowLocalReferences))
+ Flags |= FormatFlags::kAllowLocalReferences;
+ if (!EnumHasAnyFlags(AcceptFlags, RpcAcceptOptions::kAllowPartialLocalReferences))
{
- Flags |= FormatFlags::kAllowLocalReferences;
- if (!EnumHasAnyFlags(AcceptFlags, RpcAcceptOptions::kAllowPartialLocalReferences))
- {
- Flags |= FormatFlags::kDenyPartialLocalReferences;
- }
- TargetProcessHandle = m_OpenProcessCache.GetProcessHandle(RequestContext.SessionId, TargetProcessId);
+ Flags |= FormatFlags::kDenyPartialLocalReferences;
}
- CompositeBuffer RpcResponseBuffer = FormatPackageMessageBuffer(RpcResult, Flags, TargetProcessHandle);
- AsyncRequest.WriteResponse(HttpResponseCode::OK, HttpContentType::kCbPackage, RpcResponseBuffer);
+ TargetProcessHandle = m_OpenProcessCache.GetProcessHandle(RequestContext.SessionId, TargetProcessId);
}
- else
- {
- BinaryWriter MemStream;
- RpcResult.Save(MemStream);
+ CompositeBuffer RpcResponseBuffer = FormatPackageMessageBuffer(RpcResult, Flags, TargetProcessHandle);
+ AsyncRequest.WriteResponse(HttpResponseCode::OK, HttpContentType::kCbPackage, RpcResponseBuffer);
+ }
+ else
+ {
+ BinaryWriter MemStream;
+ RpcResult.Save(MemStream);
- AsyncRequest.WriteResponse(HttpResponseCode::OK,
- HttpContentType::kCbPackage,
- IoBuffer(IoBuffer::Wrap, MemStream.GetData(), MemStream.GetSize()));
- }
- };
+ AsyncRequest.WriteResponse(HttpResponseCode::OK,
+ HttpContentType::kCbPackage,
+ IoBuffer(IoBuffer::Wrap, MemStream.GetData(), MemStream.GetSize()));
+ }
+ };
if (HasUpstream)
{