aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/workspaces/httpworkspaces.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2024-06-04 22:21:06 +0200
committerGitHub Enterprise <[email protected]>2024-06-04 22:21:06 +0200
commit3a82e1cb3b5a284d2c47e03d541a35b84589314b (patch)
treed4b6c3d7c548b2d6f83b105fb0a5668ca2152889 /src/zenserver/workspaces/httpworkspaces.cpp
parentadd batching of CacheStore requests for GetCacheValues/GetCacheChunks (#90) (diff)
downloadzen-3a82e1cb3b5a284d2c47e03d541a35b84589314b.tar.xz
zen-3a82e1cb3b5a284d2c47e03d541a35b84589314b.zip
workspace share aliases (#91)
- Add `zen workspace-share` `--root-path` option - the root local file path of the workspace - if given it will automatically create the workspace before creating the share. If `--workspace` is omitted, an id will be generated from the `--root-path` parameter - Add `/ws/share/{alias}/` endpoint - a shortcut to `/ws/{workspace_id}/{share_id}/` based endpoints using the alias for a workspace share - Add `--alias` option to replace `--workspace` and `--share` options for `workspace-share` zen commands - Rename `zen workspace create` `folder` option to `root-path` - Rename `zen workspace create` `folder` option to `share-path`
Diffstat (limited to 'src/zenserver/workspaces/httpworkspaces.cpp')
-rw-r--r--src/zenserver/workspaces/httpworkspaces.cpp623
1 files changed, 424 insertions, 199 deletions
diff --git a/src/zenserver/workspaces/httpworkspaces.cpp b/src/zenserver/workspaces/httpworkspaces.cpp
index 121f40149..534b72bd5 100644
--- a/src/zenserver/workspaces/httpworkspaces.cpp
+++ b/src/zenserver/workspaces/httpworkspaces.cpp
@@ -37,6 +37,8 @@ namespace {
return Oid::FromMemory(Hash.Hash);
}
+ constinit AsciiSet ValidAliasCharactersSet{"abcdefghijklmnopqrstuvwxyz0123456789+-_.[]ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
+
} // namespace
HttpWorkspacesService::HttpWorkspacesService(HttpStatsService& StatsService, const FileServeConfig& Cfg, Workspaces& Workspaces)
@@ -126,6 +128,7 @@ HttpWorkspacesService::Initialize()
m_Router.AddPattern("workspace", "([[:xdigit:]]{24})");
m_Router.AddPattern("share_id", "([[:xdigit:]]{24})");
m_Router.AddPattern("chunk", "([[:xdigit:]]{24})");
+ m_Router.AddPattern("share_alias", "([[:alnum:]_.\\+\\-\\[\\]]+)");
m_Router.RegisterRoute(
"{workspace_id}/{share_id}/files",
@@ -153,6 +156,36 @@ HttpWorkspacesService::Initialize()
HttpVerb::kGet | HttpVerb::kHead);
m_Router.RegisterRoute(
+ "share/{share_alias}/files",
+ [this](HttpRouterRequest& Req) { ShareAliasFilesRequest(Req); },
+ HttpVerb::kGet);
+
+ m_Router.RegisterRoute(
+ "share/{share_alias}/{chunk}/info",
+ [this](HttpRouterRequest& Req) { ShareAliasChunkInfoRequest(Req); },
+ HttpVerb::kGet);
+
+ m_Router.RegisterRoute(
+ "share/{share_alias}/batch",
+ [this](HttpRouterRequest& Req) { ShareAliasBatchRequest(Req); },
+ HttpVerb::kPost);
+
+ m_Router.RegisterRoute(
+ "share/{share_alias}/entries",
+ [this](HttpRouterRequest& Req) { ShareAliasEntriesRequest(Req); },
+ HttpVerb::kGet);
+
+ m_Router.RegisterRoute(
+ "share/{share_alias}/{chunk}",
+ [this](HttpRouterRequest& Req) { ShareAliasChunkRequest(Req); },
+ HttpVerb::kGet | HttpVerb::kHead);
+
+ m_Router.RegisterRoute(
+ "share/{share_alias}",
+ [this](HttpRouterRequest& Req) { ShareAliasRequest(Req); },
+ HttpVerb::kPut | HttpVerb::kGet | HttpVerb::kDelete);
+
+ m_Router.RegisterRoute(
"{workspace_id}/{share_id}",
[this](HttpRouterRequest& Req) { ShareRequest(Req); },
HttpVerb::kPut | HttpVerb::kGet | HttpVerb::kDelete);
@@ -209,6 +242,354 @@ HttpWorkspacesService::FilesRequest(HttpRouterRequest& Req)
HttpContentType::kText,
fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
}
+ FilesRequest(Req, WorkspaceId, ShareId);
+}
+
+void
+HttpWorkspacesService::ChunkInfoRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ const Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
+ if (WorkspaceId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
+ }
+ const Oid ShareId = Oid::TryFromHexString(Req.GetCapture(2));
+ if (ShareId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
+ }
+ ChunkInfoRequest(Req, WorkspaceId, ShareId);
+}
+
+void
+HttpWorkspacesService::BatchRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ const Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
+ if (WorkspaceId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
+ }
+ const Oid ShareId = Oid::TryFromHexString(Req.GetCapture(2));
+ if (ShareId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
+ }
+ BatchRequest(Req, WorkspaceId, ShareId);
+}
+
+void
+HttpWorkspacesService::EntriesRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ const Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
+ if (WorkspaceId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
+ }
+ const Oid ShareId = Oid::TryFromHexString(Req.GetCapture(2));
+ if (ShareId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
+ }
+ EntriesRequest(Req, WorkspaceId, ShareId);
+}
+
+void
+HttpWorkspacesService::ChunkRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ const Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
+ if (WorkspaceId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
+ }
+ const Oid ShareId = Oid::TryFromHexString(Req.GetCapture(2));
+ if (ShareId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
+ }
+ ChunkRequest(Req, WorkspaceId, ShareId);
+}
+
+void
+HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ const Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
+ if (WorkspaceId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
+ }
+ Oid ShareId = Oid::Zero;
+ if (Req.GetCapture(2) != Oid::Zero.ToString())
+ {
+ ShareId = Oid::TryFromHexString(Req.GetCapture(2));
+ if (ShareId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
+ }
+ }
+ ShareRequest(Req, WorkspaceId, ShareId);
+}
+
+void
+HttpWorkspacesService::WorkspaceRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
+ switch (ServerRequest.RequestVerb())
+ {
+ case HttpVerb::kPut:
+ {
+ std::filesystem::path WorkspacePath = GetPathParameter(ServerRequest, "root_path"sv);
+ if (WorkspacePath.empty())
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ "Invalid 'root_path' parameter");
+ }
+ if (Req.GetCapture(1) == Oid::Zero.ToString())
+ {
+ // Synthesize Id
+ WorkspaceId = PathToChunkId(WorkspacePath);
+ ZEN_INFO("Generated workspace id from path '{}': {}", WorkspacePath, WorkspaceId);
+ }
+ else if (WorkspaceId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
+ }
+ m_WorkspacesStats.WorkspaceWriteCount++;
+ Workspaces::WorkspaceConfiguration NewConfig = {.Id = WorkspaceId, .RootPath = WorkspacePath};
+ bool OK = m_Workspaces.AddWorkspace(NewConfig);
+ if (OK)
+ {
+ WriteState();
+ return ServerRequest.WriteResponse(HttpResponseCode::Created, HttpContentType::kText, fmt::format("{}", WorkspaceId));
+ }
+ else
+ {
+ Workspaces::WorkspaceConfiguration Config = m_Workspaces.GetWorkspaceConfiguration(WorkspaceId);
+ if (Config == NewConfig)
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, fmt::format("{}", WorkspaceId));
+ }
+ return ServerRequest.WriteResponse(
+ HttpResponseCode::Conflict,
+ HttpContentType::kText,
+ fmt::format("Workspace {} already exists with root path '{}'", WorkspaceId, Config.RootPath));
+ }
+ }
+ case HttpVerb::kGet:
+ {
+ if (WorkspaceId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
+ }
+ m_WorkspacesStats.WorkspaceReadCount++;
+ Workspaces::WorkspaceInfo Info = m_Workspaces.GetWorkspaceInfo(WorkspaceId);
+ if (Info.Config.Id != Oid::Zero)
+ {
+ CbObjectWriter Response;
+ Response << "id" << Info.Config.Id;
+ Response << "root_path" << Info.Config.RootPath.string(); // utf8?
+ Response.BeginArray("shares");
+ for (const Workspaces::WorkspaceShareConfiguration& ShareConfig : Info.Shares)
+ {
+ Response.BeginObject();
+ {
+ Response << "id" << ShareConfig.Id;
+ Response << "share_path" << ShareConfig.SharePath.string(); // utf8?
+ if (!ShareConfig.Alias.empty())
+ {
+ Response << "alias" << ShareConfig.Alias;
+ }
+ }
+ Response.EndObject();
+ }
+ Response.EndArray();
+
+ return ServerRequest.WriteResponse(HttpResponseCode::OK, Response.Save());
+ }
+ return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
+ }
+ case HttpVerb::kDelete:
+ {
+ if (WorkspaceId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
+ }
+ m_WorkspacesStats.WorkspaceDeleteCount++;
+ bool Deleted = m_Workspaces.RemoveWorkspace(WorkspaceId);
+ if (Deleted)
+ {
+ WriteState();
+ return ServerRequest.WriteResponse(HttpResponseCode::OK);
+ }
+ return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
+ }
+ }
+}
+
+void
+HttpWorkspacesService::ShareAliasFilesRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ std::string Alias = Req.GetCapture(1);
+ if (Alias.empty())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid alias '{}'", Req.GetCapture(1)));
+ }
+ std::optional<Workspaces::ShareAlias> WorkspaceAndShareId = m_Workspaces.GetShareAlias(Alias);
+ if (!WorkspaceAndShareId.has_value())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
+ }
+ FilesRequest(Req, WorkspaceAndShareId.value().WorkspaceId, WorkspaceAndShareId.value().ShareId);
+}
+
+void
+HttpWorkspacesService::ShareAliasChunkInfoRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ std::string Alias = Req.GetCapture(1);
+ if (Alias.empty())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid alias '{}'", Req.GetCapture(1)));
+ }
+ std::optional<Workspaces::ShareAlias> WorkspaceAndShareId = m_Workspaces.GetShareAlias(Alias);
+ if (!WorkspaceAndShareId.has_value())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
+ }
+ ChunkInfoRequest(Req, WorkspaceAndShareId.value().WorkspaceId, WorkspaceAndShareId.value().ShareId);
+}
+
+void
+HttpWorkspacesService::ShareAliasBatchRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ std::string Alias = Req.GetCapture(1);
+ if (Alias.empty())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid alias '{}'", Req.GetCapture(1)));
+ }
+ std::optional<Workspaces::ShareAlias> WorkspaceAndShareId = m_Workspaces.GetShareAlias(Alias);
+ if (!WorkspaceAndShareId.has_value())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
+ }
+ BatchRequest(Req, WorkspaceAndShareId.value().WorkspaceId, WorkspaceAndShareId.value().ShareId);
+}
+
+void
+HttpWorkspacesService::ShareAliasEntriesRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ std::string Alias = Req.GetCapture(1);
+ if (Alias.empty())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid alias '{}'", Req.GetCapture(1)));
+ }
+ std::optional<Workspaces::ShareAlias> WorkspaceAndShareId = m_Workspaces.GetShareAlias(Alias);
+ if (!WorkspaceAndShareId.has_value())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
+ }
+ EntriesRequest(Req, WorkspaceAndShareId.value().WorkspaceId, WorkspaceAndShareId.value().ShareId);
+}
+
+void
+HttpWorkspacesService::ShareAliasChunkRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ std::string Alias = Req.GetCapture(1);
+ if (Alias.empty())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid alias '{}'", Req.GetCapture(1)));
+ }
+ std::optional<Workspaces::ShareAlias> WorkspaceAndShareId = m_Workspaces.GetShareAlias(Alias);
+ if (!WorkspaceAndShareId.has_value())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
+ }
+ ChunkRequest(Req, WorkspaceAndShareId.value().WorkspaceId, WorkspaceAndShareId.value().ShareId);
+}
+
+void
+HttpWorkspacesService::ShareAliasRequest(HttpRouterRequest& Req)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
+ std::string Alias = Req.GetCapture(1);
+ if (Alias.empty())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid alias '{}'", Req.GetCapture(1)));
+ }
+ std::optional<Workspaces::ShareAlias> WorkspaceAndShareId = m_Workspaces.GetShareAlias(Alias);
+ if (!WorkspaceAndShareId.has_value())
+ {
+ return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
+ }
+ ShareRequest(Req, WorkspaceAndShareId.value().WorkspaceId, WorkspaceAndShareId.value().ShareId);
+}
+
+void
+HttpWorkspacesService::FilesRequest(HttpRouterRequest& Req, const Oid& WorkspaceId, const Oid& ShareId)
+{
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
m_WorkspacesStats.WorkspaceShareFilesReadCount++;
@@ -290,26 +671,10 @@ HttpWorkspacesService::FilesRequest(HttpRouterRequest& Req)
}
void
-HttpWorkspacesService::ChunkInfoRequest(HttpRouterRequest& Req)
+HttpWorkspacesService::ChunkInfoRequest(HttpRouterRequest& Req, const Oid& WorkspaceId, const Oid& ShareId)
{
HttpServerRequest& ServerRequest = Req.ServerRequest();
- const Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
- if (WorkspaceId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
- }
- const Oid ShareId = Oid::TryFromHexString(Req.GetCapture(2));
- if (ShareId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
- }
- const Oid ChunkId = Oid::TryFromHexString(Req.GetCapture(3));
+ const Oid ChunkId = Oid::TryFromHexString(Req.GetCapture(3));
if (ChunkId == Oid::Zero)
{
m_WorkspacesStats.BadRequestCount++;
@@ -330,25 +695,9 @@ HttpWorkspacesService::ChunkInfoRequest(HttpRouterRequest& Req)
}
void
-HttpWorkspacesService::BatchRequest(HttpRouterRequest& Req)
+HttpWorkspacesService::BatchRequest(HttpRouterRequest& Req, const Oid& WorkspaceId, const Oid& ShareId)
{
- HttpServerRequest& ServerRequest = Req.ServerRequest();
- const Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
- if (WorkspaceId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
- }
- const Oid ShareId = Oid::TryFromHexString(Req.GetCapture(2));
- if (ShareId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
- }
+ HttpServerRequest& ServerRequest = Req.ServerRequest();
IoBuffer Payload = ServerRequest.ReadPayload();
std::optional<std::vector<RequestChunkEntry>> ChunkRequests = ParseChunkBatchRequest(Payload);
if (!ChunkRequests.has_value())
@@ -392,7 +741,7 @@ HttpWorkspacesService::BatchRequest(HttpRouterRequest& Req)
}
void
-HttpWorkspacesService::EntriesRequest(HttpRouterRequest& Req)
+HttpWorkspacesService::EntriesRequest(HttpRouterRequest& Req, const Oid& WorkspaceId, const Oid& ShareId)
{
HttpServerRequest& ServerRequest = Req.ServerRequest();
std::string_view OpKey = ServerRequest.GetQueryParams().GetValue("opkey"sv);
@@ -401,22 +750,6 @@ HttpWorkspacesService::EntriesRequest(HttpRouterRequest& Req)
m_WorkspacesStats.BadRequestCount++;
return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
}
- const Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
- if (WorkspaceId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
- }
- const Oid ShareId = Oid::TryFromHexString(Req.GetCapture(2));
- if (ShareId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
- }
std::unordered_set<std::string> WantedFieldNames;
if (auto FieldFilter = HttpServerRequest::Decode(ServerRequest.GetQueryParams().GetValue("fieldfilter")); !FieldFilter.empty())
{
@@ -503,26 +836,10 @@ HttpWorkspacesService::EntriesRequest(HttpRouterRequest& Req)
}
void
-HttpWorkspacesService::ChunkRequest(HttpRouterRequest& Req)
+HttpWorkspacesService::ChunkRequest(HttpRouterRequest& Req, const Oid& WorkspaceId, const Oid& ShareId)
{
HttpServerRequest& ServerRequest = Req.ServerRequest();
- const Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
- if (WorkspaceId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
- }
- const Oid ShareId = Oid::TryFromHexString(Req.GetCapture(2));
- if (ShareId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
- }
- const Oid ChunkId = Oid::TryFromHexString(Req.GetCapture(3));
+ const Oid ChunkId = Oid::TryFromHexString(Req.GetCapture(3));
if (ChunkId == Oid::Zero)
{
m_WorkspacesStats.BadRequestCount++;
@@ -582,18 +899,11 @@ HttpWorkspacesService::ChunkRequest(HttpRouterRequest& Req)
}
void
-HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req)
+HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req, const Oid& WorkspaceId, const Oid& InShareId)
{
+ Oid ShareId = InShareId;
+
HttpServerRequest& ServerRequest = Req.ServerRequest();
- const Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
- if (WorkspaceId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
- }
- Oid ShareId = Oid::TryFromHexString(Req.GetCapture(2));
switch (ServerRequest.RequestVerb())
{
case HttpVerb::kPut:
@@ -606,19 +916,20 @@ HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req)
HttpContentType::kText,
"Invalid 'share_path' parameter");
}
- if (Req.GetCapture(2) == Oid::Zero.ToString())
+
+ if (ShareId == Oid::Zero)
{
// Synthesize Id
ShareId = PathToChunkId(SharePath);
ZEN_INFO("Generated workspace id from path '{}': {}", SharePath, ShareId);
}
- else if (ShareId == Oid::Zero)
+
+ std::string Alias = HttpServerRequest::Decode(ServerRequest.GetQueryParams().GetValue("alias"sv));
+ if (!AsciiSet::HasOnly(Alias, ValidAliasCharactersSet))
{
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid share id '{}'", Req.GetCapture(2)));
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid 'alias' parameter");
}
+
m_WorkspacesStats.WorkspaceShareWriteCount++;
if (m_Workspaces.GetWorkspaceInfo(WorkspaceId).Config.Id != WorkspaceId)
{
@@ -626,7 +937,10 @@ HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req)
HttpContentType::kText,
fmt::format("Workspace '{}' does not exist", WorkspaceId));
}
- bool OK = m_Workspaces.AddWorkspaceShare(WorkspaceId, {ShareId, SharePath}, [](const std::filesystem::path& Path) {
+ const Workspaces::WorkspaceShareConfiguration NewConfig = {.Id = ShareId,
+ .SharePath = SharePath,
+ .Alias = std::string(Alias)};
+ bool OK = m_Workspaces.AddWorkspaceShare(WorkspaceId, NewConfig, [](const std::filesystem::path& Path) {
return PathToChunkId(Path);
});
if (OK)
@@ -637,17 +951,18 @@ HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req)
else
{
Workspaces::WorkspaceShareConfiguration Config = m_Workspaces.GetWorkspaceShareConfiguration(WorkspaceId, ShareId);
- if (Config.Id == ShareId)
+ if (Config == NewConfig)
{
- if (Config.SharePath == SharePath)
- {
- return ServerRequest.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, fmt::format("{}", ShareId));
- }
+ return ServerRequest.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, fmt::format("{}", ShareId));
}
return ServerRequest.WriteResponse(
HttpResponseCode::Conflict,
HttpContentType::kText,
- fmt::format("Workspace share '{}' already exist in workspace '{}'", ShareId, WorkspaceId));
+ fmt::format("Workspace share '{}' already exist in workspace '{}' with share path '{}' and alias '{}'",
+ ShareId,
+ WorkspaceId,
+ Config.SharePath,
+ Config.Alias));
}
}
case HttpVerb::kGet:
@@ -659,6 +974,13 @@ HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req)
HttpContentType::kText,
fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
}
+ if (ShareId == Oid::Zero)
+ {
+ m_WorkspacesStats.BadRequestCount++;
+ return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
+ HttpContentType::kText,
+ fmt::format("Invalid share id '{}'", ShareId));
+ }
m_WorkspacesStats.WorkspaceShareReadCount++;
Workspaces::WorkspaceShareConfiguration Config = m_Workspaces.GetWorkspaceShareConfiguration(WorkspaceId, ShareId);
if (Config.Id != Oid::Zero)
@@ -666,6 +988,10 @@ HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req)
CbObjectWriter Response;
Response << "id" << Config.Id;
Response << "share_path" << Config.SharePath.string(); // utf8?
+ if (!Config.Alias.empty())
+ {
+ Response << "alias" << Config.Alias;
+ }
return ServerRequest.WriteResponse(HttpResponseCode::OK, Response.Save());
}
return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
@@ -679,116 +1005,15 @@ HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req)
HttpContentType::kText,
fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
}
- m_WorkspacesStats.WorkspaceShareDeleteCount++;
- bool Deleted = m_Workspaces.RemoveWorkspaceShare(WorkspaceId, ShareId);
- if (Deleted)
- {
- WriteState();
- return ServerRequest.WriteResponse(HttpResponseCode::OK);
- }
- return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
- }
- }
-}
-
-void
-HttpWorkspacesService::WorkspaceRequest(HttpRouterRequest& Req)
-{
- HttpServerRequest& ServerRequest = Req.ServerRequest();
- Oid WorkspaceId = Oid::TryFromHexString(Req.GetCapture(1));
- switch (ServerRequest.RequestVerb())
- {
- case HttpVerb::kPut:
- {
- std::filesystem::path WorkspacePath = GetPathParameter(ServerRequest, "root_path"sv);
- if (WorkspacePath.empty())
+ if (ShareId == Oid::Zero)
{
m_WorkspacesStats.BadRequestCount++;
return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
HttpContentType::kText,
- "Invalid 'root_path' parameter");
- }
- if (Req.GetCapture(1) == Oid::Zero.ToString())
- {
- // Synthesize Id
- WorkspaceId = PathToChunkId(WorkspacePath);
- ZEN_INFO("Generated workspace id from path '{}': {}", WorkspacePath, WorkspaceId);
+ fmt::format("Invalid share id '{}'", ShareId));
}
- else if (WorkspaceId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
- }
- m_WorkspacesStats.WorkspaceWriteCount++;
- bool OK = m_Workspaces.AddWorkspace({WorkspaceId, WorkspacePath});
- if (OK)
- {
- WriteState();
- return ServerRequest.WriteResponse(HttpResponseCode::Created, HttpContentType::kText, fmt::format("{}", WorkspaceId));
- }
- else
- {
- Workspaces::WorkspaceInfo Info = m_Workspaces.GetWorkspaceInfo(WorkspaceId);
- if (Info.Config.Id == WorkspaceId)
- {
- if (Info.Config.RootPath == WorkspacePath)
- {
- return ServerRequest.WriteResponse(HttpResponseCode::OK,
- HttpContentType::kText,
- fmt::format("{}", WorkspaceId));
- }
- }
- return ServerRequest.WriteResponse(
- HttpResponseCode::Conflict,
- HttpContentType::kText,
- fmt::format("Workspace {} already exists with root path '{}'", WorkspaceId, Info.Config.RootPath));
- }
- }
- case HttpVerb::kGet:
- {
- if (WorkspaceId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
- }
- m_WorkspacesStats.WorkspaceReadCount++;
- Workspaces::WorkspaceInfo Info = m_Workspaces.GetWorkspaceInfo(WorkspaceId);
- if (Info.Config.Id != Oid::Zero)
- {
- CbObjectWriter Response;
- Response << "id" << Info.Config.Id;
- Response << "root_path" << Info.Config.RootPath.string(); // utf8?
- Response.BeginArray("shares");
- for (const Workspaces::WorkspaceShareConfiguration& ShareConfig : Info.Shares)
- {
- Response.BeginObject();
- {
- Response << "id" << ShareConfig.Id;
- Response << "share_path" << ShareConfig.SharePath.string(); // utf8?
- }
- Response.EndObject();
- }
- Response.EndArray();
-
- return ServerRequest.WriteResponse(HttpResponseCode::OK, Response.Save());
- }
- return ServerRequest.WriteResponse(HttpResponseCode::NotFound);
- }
- case HttpVerb::kDelete:
- {
- if (WorkspaceId == Oid::Zero)
- {
- m_WorkspacesStats.BadRequestCount++;
- return ServerRequest.WriteResponse(HttpResponseCode::BadRequest,
- HttpContentType::kText,
- fmt::format("Invalid workspace id '{}'", Req.GetCapture(1)));
- }
- m_WorkspacesStats.WorkspaceDeleteCount++;
- bool Deleted = m_Workspaces.RemoveWorkspace(WorkspaceId);
+ m_WorkspacesStats.WorkspaceShareDeleteCount++;
+ bool Deleted = m_Workspaces.RemoveWorkspaceShare(WorkspaceId, ShareId);
if (Deleted)
{
WriteState();