diff options
Diffstat (limited to 'src/zenserver/frontend/frontend.cpp')
| -rw-r--r-- | src/zenserver/frontend/frontend.cpp | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/src/zenserver/frontend/frontend.cpp b/src/zenserver/frontend/frontend.cpp index 579a65c5a..52ec5b8b3 100644 --- a/src/zenserver/frontend/frontend.cpp +++ b/src/zenserver/frontend/frontend.cpp @@ -9,6 +9,7 @@ #include <zencore/logging.h> #include <zencore/string.h> #include <zencore/trace.h> +#include <zenhttp/httpstats.h> ZEN_THIRD_PARTY_INCLUDES_START #if ZEN_PLATFORM_WINDOWS @@ -28,8 +29,9 @@ static unsigned char gHtmlZipData[] = { namespace zen { //////////////////////////////////////////////////////////////////////////////// -HttpFrontendService::HttpFrontendService(std::filesystem::path Directory, HttpStatusService& StatusService) +HttpFrontendService::HttpFrontendService(std::filesystem::path Directory, HttpStatsService& StatsService, HttpStatusService& StatusService) : m_Directory(Directory) +, m_StatsService(StatsService) , m_StatusService(StatusService) { ZEN_TRACE_CPU("HttpFrontendService::HttpFrontendService"); @@ -68,6 +70,14 @@ HttpFrontendService::HttpFrontendService(std::filesystem::path Directory, HttpSt { m_Directory = HtmlDir; } + + // Map data/ requests to the project docs/ directory in dev mode + std::filesystem::path DocsDir = ParentPath / "docs"; + if (IsDir(DocsDir, ErrorCode)) + { + m_DocsDirectory = DocsDir; + } + break; } Path = ParentPath; @@ -86,12 +96,14 @@ HttpFrontendService::HttpFrontendService(std::filesystem::path Directory, HttpSt { ZEN_INFO("front-end is NOT AVAILABLE"); } + m_StatsService.RegisterHandler("dashboard", *this); m_StatusService.RegisterHandler("dashboard", *this); } HttpFrontendService::~HttpFrontendService() { m_StatusService.UnregisterHandler("dashboard", *this); + m_StatsService.UnregisterHandler("dashboard", *this); } const char* @@ -114,6 +126,8 @@ HttpFrontendService::HandleRequest(zen::HttpServerRequest& Request) { using namespace std::literals; + metrics::OperationTiming::Scope $(m_HttpRequests); + ExtendableStringBuilder<256> UriBuilder; std::string_view Uri = Request.RelativeUriWithExtension(); @@ -145,6 +159,18 @@ HttpFrontendService::HandleRequest(zen::HttpServerRequest& Request) const std::string_view DotExt = Uri.substr(DotIndex + 1); ContentType = ParseContentType(DotExt); + + // Extensions used only for static file serving — not in the global + // ParseContentType table because that table also drives URI extension + // stripping for content negotiation, and we don't want /api/foo.txt to + // have its extension removed. + if (ContentType == HttpContentType::kUnknownContentType) + { + if (DotExt == "txt" || DotExt == "md") + { + ContentType = HttpContentType::kText; + } + } } if (ContentType == HttpContentType::kUnknownContentType) @@ -154,6 +180,21 @@ HttpFrontendService::HandleRequest(zen::HttpServerRequest& Request) auto WriteResponseForUri = [this, &Request](std::string_view InUri, HttpResponseCode ResponseCode, HttpContentType ContentType) -> bool { + // In dev mode, map data/ requests to the project docs/ directory + constexpr std::string_view DataPrefix = "data/"; + if (!m_DocsDirectory.empty() && InUri.starts_with(DataPrefix)) + { + std::string_view DocsRelative = InUri.substr(DataPrefix.size()); + auto FullPath = m_DocsDirectory / std::filesystem::path(DocsRelative).make_preferred(); + FileContents File = ReadFile(FullPath); + + if (!File.ErrorCode) + { + Request.WriteResponse(ResponseCode, ContentType, File.Data[0]); + return true; + } + } + // The given content directory overrides any zip-fs discovered in the binary if (!m_Directory.empty()) { @@ -195,4 +236,26 @@ HttpFrontendService::HandleRequest(zen::HttpServerRequest& Request) } } +void +HttpFrontendService::HandleStatsRequest(HttpServerRequest& Request) +{ + Request.WriteResponse(HttpResponseCode::OK, CollectStats()); +} + +CbObject +HttpFrontendService::CollectStats() +{ + ZEN_TRACE_CPU("HttpFrontendService::Stats"); + CbObjectWriter Cbo; + + EmitSnapshot("requests", m_HttpRequests, Cbo); + return Cbo.Save(); +} + +uint64_t +HttpFrontendService::GetActivityCounter() +{ + return m_HttpRequests.Count(); +} + } // namespace zen |