diff options
Diffstat (limited to 'src/zenserver')
| -rw-r--r-- | src/zenserver/config.cpp | 62 | ||||
| -rw-r--r-- | src/zenserver/config.h | 3 | ||||
| -rw-r--r-- | src/zenserver/workspaces/httpworkspaces.cpp | 321 | ||||
| -rw-r--r-- | src/zenserver/workspaces/httpworkspaces.h | 25 | ||||
| -rw-r--r-- | src/zenserver/zenserver.cpp | 5 |
5 files changed, 268 insertions, 148 deletions
diff --git a/src/zenserver/config.cpp b/src/zenserver/config.cpp index cda5aca16..2fd9bbaf3 100644 --- a/src/zenserver/config.cpp +++ b/src/zenserver/config.cpp @@ -27,61 +27,12 @@ ZEN_THIRD_PARTY_INCLUDES_END #if ZEN_PLATFORM_WINDOWS # include <conio.h> #else -# include <pwd.h> # include <unistd.h> #endif #include <unordered_map> #include <unordered_set> -#if ZEN_PLATFORM_WINDOWS - -# include <zencore/windows.h> - -// Used for getting My Documents for default data directory -# include <ShlObj.h> -# pragma comment(lib, "shell32.lib") -# pragma comment(lib, "ole32.lib") - -namespace zen { - -std::filesystem::path -PickDefaultSystemRootDirectory() -{ - // Pick sensible default - PWSTR ProgramDataDir = nullptr; - HRESULT hRes = SHGetKnownFolderPath(FOLDERID_ProgramData, 0, NULL, &ProgramDataDir); - - if (SUCCEEDED(hRes)) - { - std::filesystem::path FinalPath(ProgramDataDir); - FinalPath /= L"Epic\\Zen"; - ::CoTaskMemFree(ProgramDataDir); - - return FinalPath; - } - - return L""; -} - -} // namespace zen - -#else - -namespace zen { - -std::filesystem::path -PickDefaultSystemRootDirectory() -{ - int UserId = getuid(); - const passwd* Passwd = getpwuid(UserId); - return std::filesystem::path(Passwd->pw_dir) / ".zen"; -} - -} // namespace zen - -#endif - namespace zen { std::filesystem::path @@ -547,6 +498,9 @@ ParseConfigFile(const std::filesystem::path& Path, ////// workspaces LuaOptions.AddOption("workspaces.enabled"sv, ServerOptions.WorksSpacesConfig.Enabled, "workspaces-enabled"sv); + LuaOptions.AddOption("workspaces.allowconfigchanges"sv, + ServerOptions.WorksSpacesConfig.AllowConfigurationChanges, + "workspaces-allow-changes"sv); // These have special command line processing so we make sure we export them if they were configured on command line if (!ServerOptions.AuthConfig.OpenIdProviders.empty()) @@ -1063,13 +1017,19 @@ ParseCliOptions(int argc, char* argv[], ZenServerOptions& ServerOptions) cxxopts::value<bool>(ServerOptions.StatsConfig.Enabled)->default_value("false"), "Enable statsd reporter (localhost:8125)"); - options.add_option("stats", + options.add_option("workspaces", "", "workspaces-enabled", "", - cxxopts::value<bool>(ServerOptions.WorksSpacesConfig.Enabled)->default_value("false"), + cxxopts::value<bool>(ServerOptions.WorksSpacesConfig.Enabled)->default_value("true"), "Enable workspaces support with folder sharing"); + options.add_option("workspaces", + "", + "workspaces-allow-changes", + "", + cxxopts::value<bool>(ServerOptions.WorksSpacesConfig.AllowConfigurationChanges)->default_value("false"), + "Allow adding/modifying/deleting of workspace and shares via http endpoint"); try { cxxopts::ParseResult Result; diff --git a/src/zenserver/config.h b/src/zenserver/config.h index 58a31bbb0..3e01cac99 100644 --- a/src/zenserver/config.h +++ b/src/zenserver/config.h @@ -131,7 +131,8 @@ struct ZenProjectStoreConfig struct ZenWorkspacesConfig { - bool Enabled = false; + bool Enabled = false; + bool AllowConfigurationChanges = false; }; struct ZenServerOptions diff --git a/src/zenserver/workspaces/httpworkspaces.cpp b/src/zenserver/workspaces/httpworkspaces.cpp index 6a4e9c466..6e27b0f1e 100644 --- a/src/zenserver/workspaces/httpworkspaces.cpp +++ b/src/zenserver/workspaces/httpworkspaces.cpp @@ -29,19 +29,51 @@ namespace { return {}; } - Oid PathToChunkId(const std::filesystem::path& Path) + void WriteWorkspaceConfig(CbWriter& Writer, const Workspaces::WorkspaceConfiguration& Config) { - const std::string PathBuffer = reinterpret_cast<const char*>(Path.generic_u8string().c_str()); - BLAKE3 Hash = BLAKE3::HashMemory(PathBuffer.data(), PathBuffer.size()); - Hash.Hash[11] = 7; // FIoChunkType::ExternalFile - return Oid::FromMemory(Hash.Hash); - } + Writer << "id" << Config.Id; + Writer << "root_path" << Config.RootPath.string(); // utf8? + Writer << "allow_share_creation_from_http" << Config.AllowShareCreationFromHttp; + }; + + void WriteWorkspaceShareConfig(CbWriter& Writer, const Workspaces::WorkspaceShareConfiguration& Config) + { + Writer << "id" << Config.Id; + Writer << "share_path" << Config.SharePath.string(); // utf8? + if (!Config.Alias.empty()) + { + Writer << "alias" << Config.Alias; + } + }; - constinit AsciiSet ValidAliasCharactersSet{"abcdefghijklmnopqrstuvwxyz0123456789+-_.[]ABCDEFGHIJKLMNOPQRSTUVWXYZ"}; + void WriteWorkspaceAndSharesConfig(CbWriter& Writer, Workspaces& Workspaces, const Workspaces::WorkspaceConfiguration& WorkspaceConfig) + { + WriteWorkspaceConfig(Writer, WorkspaceConfig); + if (std::optional<std::vector<Oid>> ShareIds = Workspaces.GetWorkspaceShares(WorkspaceConfig.Id); ShareIds) + { + for (const Oid& ShareId : *ShareIds) + { + Writer.BeginArray("shares"); + { + if (std::optional<Workspaces::WorkspaceShareConfiguration> WorkspaceShareConfig = + Workspaces.GetWorkspaceShareConfiguration(WorkspaceConfig.Id, ShareId); + WorkspaceShareConfig) + { + Writer.BeginObject(); + { + WriteWorkspaceShareConfig(Writer, *WorkspaceShareConfig); + } + Writer.EndObject(); + } + } + Writer.EndArray(); + } + } + } } // namespace -HttpWorkspacesService::HttpWorkspacesService(HttpStatsService& StatsService, const FileServeConfig& Cfg, Workspaces& Workspaces) +HttpWorkspacesService::HttpWorkspacesService(HttpStatsService& StatsService, const WorkspacesServeConfig& Cfg, Workspaces& Workspaces) : m_Log(logging::Get("workspaces")) , m_StatsService(StatsService) , m_Config(Cfg) @@ -125,7 +157,7 @@ HttpWorkspacesService::Initialize() m_StatsService.RegisterHandler("ws", *this); - m_Router.AddPattern("workspace", "([[:xdigit:]]{24})"); + m_Router.AddPattern("workspace_id", "([[:xdigit:]]{24})"); m_Router.AddPattern("share_id", "([[:xdigit:]]{24})"); m_Router.AddPattern("chunk", "([[:xdigit:]]{24})"); m_Router.AddPattern("share_alias", "([[:alnum:]_.\\+\\-\\[\\]]+)"); @@ -195,7 +227,17 @@ HttpWorkspacesService::Initialize() [this](HttpRouterRequest& Req) { WorkspaceRequest(Req); }, HttpVerb::kPut | HttpVerb::kGet | HttpVerb::kDelete); - ReadState(); + m_Router.RegisterRoute( + "refresh", + [this](HttpRouterRequest& Req) { RefreshRequest(Req); }, + HttpVerb::kGet); + + m_Router.RegisterRoute( + "", + [this](HttpRouterRequest& Req) { WorkspacesRequest(Req); }, + HttpVerb::kGet); + + RefreshState(); } std::filesystem::path @@ -205,21 +247,52 @@ HttpWorkspacesService::GetStatePath() const } void -HttpWorkspacesService::ReadState() +HttpWorkspacesService::RefreshState() { if (!m_Config.SystemRootDir.empty()) { - m_Workspaces.ReadState(GetStatePath(), [](const std::filesystem::path& Path) { return PathToChunkId(Path); }); + m_Workspaces.RefreshState(GetStatePath()); } } +bool +HttpWorkspacesService::MayChangeConfiguration(const HttpServerRequest& Req) const +{ + ZEN_UNUSED(Req); + return m_Config.AllowConfigurationChanges; +} + void -HttpWorkspacesService::WriteState() +HttpWorkspacesService::RefreshRequest(HttpRouterRequest& Req) { - if (!m_Config.SystemRootDir.empty()) + HttpServerRequest& ServerRequest = Req.ServerRequest(); + RefreshState(); + return ServerRequest.WriteResponse(HttpResponseCode::OK); +} + +void +HttpWorkspacesService::WorkspacesRequest(HttpRouterRequest& Req) +{ + HttpServerRequest& ServerRequest = Req.ServerRequest(); + + std::vector<Oid> WorkspaceIds = m_Workspaces.GetWorkspaces(); + CbObjectWriter Response; + Response.BeginArray("workspaces"); + for (const Oid& WorkspaceId : WorkspaceIds) { - m_Workspaces.WriteState(GetStatePath()); + if (std::optional<Workspaces::WorkspaceConfiguration> WorkspaceConfig = m_Workspaces.GetWorkspaceConfiguration(WorkspaceId); + WorkspaceConfig) + { + Response.BeginObject(); + { + WriteWorkspaceAndSharesConfig(Response, m_Workspaces, *WorkspaceConfig); + } + Response.EndObject(); + } } + Response.EndArray(); + + return ServerRequest.WriteResponse(HttpResponseCode::OK, Response.Save()); } void @@ -397,10 +470,11 @@ HttpWorkspacesService::WorkspaceRequest(HttpRouterRequest& Req) HttpContentType::kText, "Invalid 'root_path' parameter"); } + if (Req.GetCapture(1) == Oid::Zero.ToString()) { // Synthesize Id - WorkspaceId = PathToChunkId(WorkspacePath); + WorkspaceId = Workspaces::PathToId(WorkspacePath); ZEN_INFO("Generated workspace id from path '{}': {}", WorkspacePath, WorkspaceId); } else if (WorkspaceId == Oid::Zero) @@ -410,25 +484,54 @@ HttpWorkspacesService::WorkspaceRequest(HttpRouterRequest& Req) 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) + + if (!MayChangeConfiguration(ServerRequest)) { - WriteState(); - return ServerRequest.WriteResponse(HttpResponseCode::Created, HttpContentType::kText, fmt::format("{}", WorkspaceId)); + return ServerRequest.WriteResponse(HttpResponseCode::Unauthorized, + HttpContentType::kText, + fmt::format("Adding workspace {} is not allowed", WorkspaceId)); } - else + bool AllowShareCreationFromHttp = false; + if (std::string_view Value = ServerRequest.GetQueryParams().GetValue("allow_share_creation_from_http"); Value == "true"sv) + { + AllowShareCreationFromHttp = true; + } + + m_WorkspacesStats.WorkspaceWriteCount++; + Workspaces::WorkspaceConfiguration OldConfig = Workspaces::FindWorkspace(Log(), GetStatePath(), WorkspaceId); + Workspaces::WorkspaceConfiguration NewConfig = {.Id = WorkspaceId, + .RootPath = WorkspacePath, + .AllowShareCreationFromHttp = AllowShareCreationFromHttp}; + if (OldConfig.Id == WorkspaceId && (OldConfig != NewConfig)) { - 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)); + fmt::format("Workspace {} already exists with root path '{}'", WorkspaceId, OldConfig.RootPath)); + } + else if (OldConfig.Id == Oid::Zero) + { + if (Workspaces::WorkspaceConfiguration ConfigWithSameRoot = + Workspaces::FindWorkspace(Log(), GetStatePath(), WorkspacePath); + ConfigWithSameRoot.Id != Oid::Zero) + { + return ServerRequest.WriteResponse( + HttpResponseCode::Conflict, + HttpContentType::kText, + fmt::format("Workspace {} already exists with same root path '{}'", ConfigWithSameRoot.Id, WorkspacePath)); + } + } + + bool Created = Workspaces::AddWorkspace(Log(), GetStatePath(), NewConfig); + if (Created) + { + ZEN_ASSERT(OldConfig.Id == Oid::Zero); + RefreshState(); + return ServerRequest.WriteResponse(HttpResponseCode::Created, HttpContentType::kText, fmt::format("{}", WorkspaceId)); + } + else + { + return ServerRequest.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, fmt::format("{}", WorkspaceId)); } } case HttpVerb::kGet: @@ -441,31 +544,17 @@ HttpWorkspacesService::WorkspaceRequest(HttpRouterRequest& Req) fmt::format("Invalid workspace id '{}'", Req.GetCapture(1))); } m_WorkspacesStats.WorkspaceReadCount++; - Workspaces::WorkspaceInfo Info = m_Workspaces.GetWorkspaceInfo(WorkspaceId); - if (Info.Config.Id != Oid::Zero) + std::optional<Workspaces::WorkspaceConfiguration> Workspace = m_Workspaces.GetWorkspaceConfiguration(WorkspaceId); + if (Workspace) { 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(); - + WriteWorkspaceAndSharesConfig(Response, m_Workspaces, *Workspace); return ServerRequest.WriteResponse(HttpResponseCode::OK, Response.Save()); } - return ServerRequest.WriteResponse(HttpResponseCode::NotFound); + else + { + return ServerRequest.WriteResponse(HttpResponseCode::NotFound); + } } case HttpVerb::kDelete: { @@ -476,11 +565,19 @@ HttpWorkspacesService::WorkspaceRequest(HttpRouterRequest& Req) HttpContentType::kText, fmt::format("Invalid workspace id '{}'", Req.GetCapture(1))); } + + if (!MayChangeConfiguration(ServerRequest)) + { + return ServerRequest.WriteResponse(HttpResponseCode::Unauthorized, + HttpContentType::kText, + fmt::format("Removing workspace {} is not allowed", WorkspaceId)); + } + m_WorkspacesStats.WorkspaceDeleteCount++; - bool Deleted = m_Workspaces.RemoveWorkspace(WorkspaceId); + bool Deleted = Workspaces::RemoveWorkspace(Log(), GetStatePath(), WorkspaceId); if (Deleted) { - WriteState(); + RefreshState(); return ServerRequest.WriteResponse(HttpResponseCode::OK); } return ServerRequest.WriteResponse(HttpResponseCode::NotFound); @@ -938,50 +1035,88 @@ HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req, const Oid& Workspace if (ShareId == Oid::Zero) { // Synthesize Id - ShareId = PathToChunkId(SharePath); + ShareId = Workspaces::PathToId(SharePath); ZEN_INFO("Generated workspace id from path '{}': {}", SharePath, ShareId); } std::string Alias = HttpServerRequest::Decode(ServerRequest.GetQueryParams().GetValue("alias"sv)); - if (!AsciiSet::HasOnly(Alias, ValidAliasCharactersSet)) + if (!AsciiSet::HasOnly(Alias, Workspaces::ValidAliasCharactersSet)) { return ServerRequest.WriteResponse(HttpResponseCode::BadRequest, HttpContentType::kText, "Invalid 'alias' parameter"); } - m_WorkspacesStats.WorkspaceShareWriteCount++; - if (m_Workspaces.GetWorkspaceInfo(WorkspaceId).Config.Id != WorkspaceId) + Workspaces::WorkspaceConfiguration Workspace = Workspaces::FindWorkspace(Log(), GetStatePath(), WorkspaceId); + if (Workspace.Id == Oid::Zero) { return ServerRequest.WriteResponse(HttpResponseCode::NotFound, HttpContentType::kText, fmt::format("Workspace '{}' does not exist", WorkspaceId)); } + + if (!Workspace.AllowShareCreationFromHttp) + { + if (!MayChangeConfiguration(ServerRequest)) + { + return ServerRequest.WriteResponse( + HttpResponseCode::Unauthorized, + HttpContentType::kText, + fmt::format("Adding workspace share {} in workspace {} is not allowed", WorkspaceId, ShareId)); + } + } + + m_WorkspacesStats.WorkspaceShareWriteCount++; + + const Workspaces::WorkspaceShareConfiguration OldConfig = + Workspaces::FindWorkspaceShare(Log(), Workspace.RootPath, ShareId); 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) - { - WriteState(); - return ServerRequest.WriteResponse(HttpResponseCode::Created, HttpContentType::kText, fmt::format("{}", ShareId)); - } - else + + if (OldConfig.Id == ShareId && (OldConfig != NewConfig)) { - Workspaces::WorkspaceShareConfiguration Config = m_Workspaces.GetWorkspaceShareConfiguration(WorkspaceId, ShareId); - if (Config == NewConfig) - { - 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 '{}' with share path '{}' and alias '{}'", ShareId, WorkspaceId, - Config.SharePath, - Config.Alias)); + OldConfig.SharePath, + OldConfig.Alias)); + } + else if (OldConfig.Id == Oid::Zero) + { + if (Workspaces::WorkspaceShareConfiguration ConfigWithSamePath = + Workspaces::FindWorkspaceShare(Log(), Workspace.RootPath, SharePath); + ConfigWithSamePath.Id != Oid::Zero) + { + return ServerRequest.WriteResponse( + HttpResponseCode::Conflict, + HttpContentType::kText, + fmt::format("Workspace share '{}' already exist in workspace '{}' with same share path '{}' and alias '{}'", + ShareId, + WorkspaceId, + OldConfig.SharePath, + OldConfig.Alias)); + } + } + + if (!std::filesystem::is_directory(Workspace.RootPath / NewConfig.SharePath)) + { + return ServerRequest.WriteResponse(HttpResponseCode::NotFound, + HttpContentType::kText, + fmt::format("directory {} does not exist in workspace {} root '{}'", + NewConfig.SharePath, + WorkspaceId, + Workspace.RootPath)); + } + + bool Created = Workspaces::AddWorkspaceShare(Log(), Workspace.RootPath, NewConfig); + if (Created) + { + RefreshState(); + return ServerRequest.WriteResponse(HttpResponseCode::Created, HttpContentType::kText, fmt::format("{}", ShareId)); } + return ServerRequest.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, fmt::format("{}", ShareId)); } case HttpVerb::kGet: { @@ -999,20 +1134,18 @@ HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req, const Oid& Workspace HttpContentType::kText, fmt::format("Invalid share id '{}'", ShareId)); } + m_WorkspacesStats.WorkspaceShareReadCount++; - Workspaces::WorkspaceShareConfiguration Config = m_Workspaces.GetWorkspaceShareConfiguration(WorkspaceId, ShareId); - if (Config.Id != Oid::Zero) + std::optional<Workspaces::WorkspaceShareConfiguration> Config = + m_Workspaces.GetWorkspaceShareConfiguration(WorkspaceId, ShareId); + if (!Config) { - 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); } - return ServerRequest.WriteResponse(HttpResponseCode::NotFound); + + CbObjectWriter Response; + WriteWorkspaceShareConfig(Response, *Config); + return ServerRequest.WriteResponse(HttpResponseCode::OK, Response.Save()); } case HttpVerb::kDelete: { @@ -1030,11 +1163,29 @@ HttpWorkspacesService::ShareRequest(HttpRouterRequest& Req, const Oid& Workspace HttpContentType::kText, fmt::format("Invalid share id '{}'", ShareId)); } + + Workspaces::WorkspaceConfiguration Workspace = Workspaces::FindWorkspace(Log(), GetStatePath(), WorkspaceId); + if (Workspace.Id == Oid::Zero) + { + return ServerRequest.WriteResponse(HttpResponseCode::NotFound); + } + + if (!Workspace.AllowShareCreationFromHttp) + { + if (!MayChangeConfiguration(ServerRequest)) + { + return ServerRequest.WriteResponse( + HttpResponseCode::Unauthorized, + HttpContentType::kText, + fmt::format("Removing workspace share {} in workspace {} is not allowed", WorkspaceId, ShareId)); + } + } + m_WorkspacesStats.WorkspaceShareDeleteCount++; - bool Deleted = m_Workspaces.RemoveWorkspaceShare(WorkspaceId, ShareId); + bool Deleted = Workspaces::RemoveWorkspaceShare(Log(), Workspace.RootPath, ShareId); if (Deleted) { - WriteState(); + RefreshState(); return ServerRequest.WriteResponse(HttpResponseCode::OK); } return ServerRequest.WriteResponse(HttpResponseCode::NotFound); diff --git a/src/zenserver/workspaces/httpworkspaces.h b/src/zenserver/workspaces/httpworkspaces.h index dfa50f822..f01f58b86 100644 --- a/src/zenserver/workspaces/httpworkspaces.h +++ b/src/zenserver/workspaces/httpworkspaces.h @@ -10,15 +10,16 @@ namespace zen { class Workspaces; -struct FileServeConfig +struct WorkspacesServeConfig { std::filesystem::path SystemRootDir; + bool AllowConfigurationChanges = false; }; class HttpWorkspacesService final : public HttpService, public IHttpStatsProvider { public: - HttpWorkspacesService(HttpStatsService& StatsService, const FileServeConfig& Cfg, Workspaces& Workspaces); + HttpWorkspacesService(HttpStatsService& StatsService, const WorkspacesServeConfig& Cfg, Workspaces& Workspaces); virtual ~HttpWorkspacesService(); virtual const char* BaseUri() const override; @@ -50,9 +51,13 @@ private: void Initialize(); std::filesystem::path GetStatePath() const; - void ReadState(); - void WriteState(); + void RefreshState(); + // void WriteState(); + bool MayChangeConfiguration(const HttpServerRequest& Req) const; + + void WorkspacesRequest(HttpRouterRequest& Req); + void RefreshRequest(HttpRouterRequest& Req); void FilesRequest(HttpRouterRequest& Req); void ChunkInfoRequest(HttpRouterRequest& Req); void BatchRequest(HttpRouterRequest& Req); @@ -75,12 +80,12 @@ private: void ChunkRequest(HttpRouterRequest& Req, const Oid& WorkspaceId, const Oid& ShareId, const Oid& ChunkId); void ShareRequest(HttpRouterRequest& Req, const Oid& WorkspaceId, const Oid& InShareId); - HttpStatsService& m_StatsService; - const FileServeConfig m_Config; - HttpRequestRouter m_Router; - Workspaces& m_Workspaces; - WorkspacesStats m_WorkspacesStats; - metrics::OperationTiming m_HttpRequests; + HttpStatsService& m_StatsService; + const WorkspacesServeConfig m_Config; + HttpRequestRouter m_Router; + Workspaces& m_Workspaces; + WorkspacesStats m_WorkspacesStats; + metrics::OperationTiming m_HttpRequests; }; } // namespace zen diff --git a/src/zenserver/zenserver.cpp b/src/zenserver/zenserver.cpp index 124e9ff5f..f6d6556a0 100644 --- a/src/zenserver/zenserver.cpp +++ b/src/zenserver/zenserver.cpp @@ -239,7 +239,10 @@ ZenServer::Initialize(const ZenServerOptions& ServerOptions, ZenServerState::Zen { m_Workspaces.reset(new Workspaces()); m_HttpWorkspacesService.reset( - new HttpWorkspacesService(m_StatsService, {.SystemRootDir = ServerOptions.SystemRootDir}, *m_Workspaces)); + new HttpWorkspacesService(m_StatsService, + {.SystemRootDir = ServerOptions.SystemRootDir, + .AllowConfigurationChanges = ServerOptions.WorksSpacesConfig.AllowConfigurationChanges}, + *m_Workspaces)); } if (ServerOptions.StructuredCacheConfig.Enabled) |