aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/storage/vfs/vfsservice.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-10-14 11:32:16 +0200
committerGitHub Enterprise <[email protected]>2025-10-14 11:32:16 +0200
commitca09abbeef5b1788f4a52b61eedd2f3dd07f81f2 (patch)
tree005a50adfddf6982bab3a06bb93d4c50da1a11fd /src/zenserver/storage/vfs/vfsservice.cpp
parentmake asiohttp work without IPv6 (#562) (diff)
downloadzen-ca09abbeef5b1788f4a52b61eedd2f3dd07f81f2.tar.xz
zen-ca09abbeef5b1788f4a52b61eedd2f3dd07f81f2.zip
move all storage-related services into storage tree (#571)
* move all storage-related services into storage tree * move config into config/ * also move admin service into storage since it mostly has storage related functionality * header consolidation
Diffstat (limited to 'src/zenserver/storage/vfs/vfsservice.cpp')
-rw-r--r--src/zenserver/storage/vfs/vfsservice.cpp179
1 files changed, 179 insertions, 0 deletions
diff --git a/src/zenserver/storage/vfs/vfsservice.cpp b/src/zenserver/storage/vfs/vfsservice.cpp
new file mode 100644
index 000000000..863ec348a
--- /dev/null
+++ b/src/zenserver/storage/vfs/vfsservice.cpp
@@ -0,0 +1,179 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+#include "vfsservice.h"
+
+#include <zenstore/vfsimpl.h>
+
+#include <zencore/compactbinarybuilder.h>
+
+namespace zen {
+
+using namespace std::literals;
+
+#if ZEN_WITH_VFS
+
+//////////////////////////////////////////////////////////////////////////
+
+bool
+GetContentAsCbObject(HttpServerRequest& HttpReq, CbObject& Cb)
+{
+ IoBuffer Payload = HttpReq.ReadPayload();
+ HttpContentType PayloadContentType = HttpReq.RequestContentType();
+
+ switch (PayloadContentType)
+ {
+ case HttpContentType::kJSON:
+ case HttpContentType::kUnknownContentType:
+ case HttpContentType::kText:
+ {
+ std::string JsonText(reinterpret_cast<const char*>(Payload.GetData()), Payload.GetSize());
+ Cb = LoadCompactBinaryFromJson(JsonText).AsObject();
+ if (!Cb)
+ {
+ HttpReq.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ "Content format not supported, expected JSON format");
+ return false;
+ }
+ }
+ break;
+ case HttpContentType::kCbObject:
+ Cb = LoadCompactBinaryObject(Payload);
+ if (!Cb)
+ {
+ HttpReq.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ "Content format not supported, expected compact binary format");
+ return false;
+ }
+ break;
+ default:
+ HttpReq.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid request content type");
+ return false;
+ }
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//
+// to test:
+//
+// echo {"method": "mount", "params": {"path": "d:\\VFS_ROOT"}} | curl.exe http://localhost:8558/vfs --data-binary @-
+// echo {"method": "unmount"} | curl.exe http://localhost:8558/vfs --data-binary @-
+
+VfsService::VfsService(HttpStatusService& StatusService, VfsServiceImpl* ServiceImpl) : m_StatusService(StatusService), m_Impl(ServiceImpl)
+{
+ m_Router.RegisterRoute(
+ "info",
+ [&](HttpRouterRequest& Request) {
+ CbObjectWriter Cbo;
+ Cbo << "running" << m_Impl->IsVfsRunning();
+ Cbo << "rootpath" << m_Impl->GetMountpointPath();
+
+ Request.ServerRequest().WriteResponse(HttpResponseCode::OK, Cbo.Save());
+ },
+ HttpVerb::kGet | HttpVerb::kHead);
+
+ m_Router.RegisterRoute(
+ "",
+ [&](HttpRouterRequest& Req) {
+ CbObject Payload;
+
+ if (!GetContentAsCbObject(Req.ServerRequest(), Payload))
+ return;
+
+ std::string_view RpcName = Payload["method"sv].AsString();
+
+ if (RpcName == "mount"sv)
+ {
+ CbObjectView Params = Payload["params"sv].AsObjectView();
+ std::string_view Mountpath = Params["path"sv].AsString();
+
+ if (Mountpath.empty())
+ {
+ return Req.ServerRequest().WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "no path specified");
+ }
+
+ if (m_Impl->IsVfsRunning())
+ {
+ return Req.ServerRequest().WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "VFS already mounted");
+ }
+
+ try
+ {
+ m_Impl->Mount(Mountpath);
+ }
+ catch (const std::exception& Ex)
+ {
+ return Req.ServerRequest().WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, Ex.what());
+ }
+
+ Req.ServerRequest().WriteResponse(HttpResponseCode::OK);
+ }
+ else if (RpcName == "unmount"sv)
+ {
+ if (!m_Impl->IsVfsRunning())
+ {
+ return Req.ServerRequest().WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "VFS not active");
+ }
+
+ try
+ {
+ m_Impl->Unmount();
+ }
+ catch (const std::exception& Ex)
+ {
+ return Req.ServerRequest().WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, Ex.what());
+ }
+
+ Req.ServerRequest().WriteResponse(HttpResponseCode::OK);
+ }
+ else
+ {
+ Req.ServerRequest().WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "unknown RPC"sv);
+ }
+ },
+ HttpVerb::kPost);
+ m_StatusService.RegisterHandler("vfs", *this);
+}
+
+VfsService::~VfsService()
+{
+ m_StatusService.UnregisterHandler("vfs", *this);
+}
+
+#else
+
+VfsService::VfsService(HttpStatusService& StatusService, VfsServiceImpl* ServiceImpl) : m_StatusService(StatusService)
+{
+ ZEN_UNUSED(ServiceImpl);
+}
+
+VfsService::~VfsService()
+{
+}
+
+#endif
+
+const char*
+VfsService::BaseUri() const
+{
+ return "/vfs/";
+}
+
+void
+VfsService::HandleStatusRequest(HttpServerRequest& Request)
+{
+ CbObjectWriter Cbo;
+ Cbo << "ok" << true;
+ Request.WriteResponse(HttpResponseCode::OK, Cbo.Save());
+}
+
+void
+VfsService::HandleRequest(HttpServerRequest& HttpServiceRequest)
+{
+ m_Router.HandleRequest(HttpServiceRequest);
+}
+
+} // namespace zen