diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/zenhttp/diagsvcs.cpp | 26 | ||||
| -rw-r--r-- | src/zenhttp/httpserver.cpp | 8 | ||||
| -rw-r--r-- | src/zenhttp/include/zenhttp/diagsvcs.h | 16 | ||||
| -rw-r--r-- | src/zenhttp/include/zenhttp/httpcommon.h | 4 | ||||
| -rw-r--r-- | src/zenhttp/include/zenhttp/httpserver.h | 13 | ||||
| -rw-r--r-- | src/zenhttp/include/zenhttp/httpstats.h | 11 | ||||
| -rw-r--r-- | src/zenhttp/include/zenhttp/httptest.h | 4 | ||||
| -rw-r--r-- | src/zenhttp/monitoring/httpstats.cpp | 34 | ||||
| -rw-r--r-- | src/zenhttp/testing/httptest.cpp | 4 | ||||
| -rw-r--r-- | src/zenhttp/xmake.lua | 4 | ||||
| -rw-r--r-- | src/zenhttp/zenhttp.cpp | 1 |
11 files changed, 98 insertions, 27 deletions
diff --git a/src/zenhttp/diagsvcs.cpp b/src/zenhttp/diagsvcs.cpp index 8fa71b375..9a547aa47 100644 --- a/src/zenhttp/diagsvcs.cpp +++ b/src/zenhttp/diagsvcs.cpp @@ -17,8 +17,8 @@ namespace zen { using namespace std::literals; -bool -ReadFile(const std::string& Path, StringBuilderBase& Out) +static bool +ReadLogFile(const std::string& Path, StringBuilderBase& Out) { try { @@ -57,10 +57,14 @@ HttpHealthService::HttpHealthService() HttpServerRequest& HttpReq = RoutedReq.ServerRequest(); CbObjectWriter Writer; - Writer << "DataRoot"sv << m_HealthInfo.DataRoot.string(); - Writer << "AbsLogPath"sv << m_HealthInfo.AbsLogPath.string(); - Writer << "BuildVersion"sv << m_HealthInfo.BuildVersion; - Writer << "HttpServerClass"sv << m_HealthInfo.HttpServerClass; + + { + RwLock::SharedLockScope _(m_InfoLock); + Writer << "DataRoot"sv << m_HealthInfo.DataRoot.string(); + Writer << "AbsLogPath"sv << m_HealthInfo.AbsLogPath.string(); + Writer << "BuildVersion"sv << m_HealthInfo.BuildVersion; + Writer << "HttpServerClass"sv << m_HealthInfo.HttpServerClass; + } HttpReq.WriteResponse(HttpResponseCode::OK, Writer.Save()); }, @@ -73,11 +77,13 @@ HttpHealthService::HttpHealthService() zen::Log().flush(); - std::filesystem::path Path = - m_HealthInfo.AbsLogPath.empty() ? m_HealthInfo.DataRoot / "logs/zenserver.log" : m_HealthInfo.AbsLogPath; + std::filesystem::path Path = [&] { + RwLock::SharedLockScope _(m_InfoLock); + return m_HealthInfo.AbsLogPath.empty() ? m_HealthInfo.DataRoot / "logs/zenserver.log" : m_HealthInfo.AbsLogPath; + }(); ExtendableStringBuilder<4096> Sb; - if (ReadFile(Path.string(), Sb) && Sb.Size() > 0) + if (ReadLogFile(Path.string(), Sb) && Sb.Size() > 0) { HttpReq.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, Sb.ToView()); } @@ -87,6 +93,7 @@ HttpHealthService::HttpHealthService() } }, HttpVerb::kGet); + m_Router.RegisterRoute( "version", [this](HttpRouterRequest& RoutedReq) { @@ -106,6 +113,7 @@ HttpHealthService::HttpHealthService() void HttpHealthService::SetHealthInfo(HealthServiceInfo&& Info) { + RwLock::ExclusiveLockScope _(m_InfoLock); m_HealthInfo = std::move(Info); } diff --git a/src/zenhttp/httpserver.cpp b/src/zenhttp/httpserver.cpp index 671cbd319..dbf284ab5 100644 --- a/src/zenhttp/httpserver.cpp +++ b/src/zenhttp/httpserver.cpp @@ -95,6 +95,7 @@ static constinit uint32_t HashCompressedBinary = HashStringDjb2("application/x static constinit uint32_t HashHtml = HashStringDjb2("html"sv); static constinit uint32_t HashTextHtml = HashStringDjb2("text/html"sv); static constinit uint32_t HashJavaScript = HashStringDjb2("js"sv); +static constinit uint32_t HashJavaScriptSourceMap = HashStringDjb2("map"sv); // actually .js.map static constinit uint32_t HashApplicationJavaScript = HashStringDjb2("application/javascript"sv); static constinit uint32_t HashCss = HashStringDjb2("css"sv); static constinit uint32_t HashTextCss = HashStringDjb2("text/css"sv); @@ -127,6 +128,7 @@ struct HashedTypeEntry {HashTextHtml, HttpContentType::kHTML}, {HashJavaScript, HttpContentType::kJavaScript}, {HashApplicationJavaScript, HttpContentType::kJavaScript}, + {HashJavaScriptSourceMap, HttpContentType::kJavaScript}, {HashCss, HttpContentType::kCSS}, {HashTextCss, HttpContentType::kCSS}, {HashPng, HttpContentType::kPNG}, @@ -276,6 +278,12 @@ ToString(HttpVerb Verb) } std::string_view +ToString(HttpResponseCode HttpCode) +{ + return ReasonStringForHttpResultCode(int(HttpCode)); +} + +std::string_view ReasonStringForHttpResultCode(int HttpCode) { switch (HttpCode) diff --git a/src/zenhttp/include/zenhttp/diagsvcs.h b/src/zenhttp/include/zenhttp/diagsvcs.h index bd03f8023..8cc869c83 100644 --- a/src/zenhttp/include/zenhttp/diagsvcs.h +++ b/src/zenhttp/include/zenhttp/diagsvcs.h @@ -11,10 +11,15 @@ namespace zen { +/** HTTP test endpoint + + This is intended to be used to exercise basic HTTP communication infrastructure + which is useful for benchmarking performance of the server code and when evaluating + network performance / diagnosing connectivity issues + + */ class HttpTestService : public HttpService { - uint32_t LogPoint = 0; - public: HttpTestService() {} ~HttpTestService() = default; @@ -30,8 +35,6 @@ public: if (Uri == "hello"sv) { Request.WriteResponse(HttpResponseCode::OK, HttpContentType::kText, u8"hello world!"sv); - - // OutputLogMessageInternal(&LogPoint, 0, 0); } else if (Uri == "1K"sv) { @@ -92,6 +95,10 @@ struct HealthServiceInfo std::string BuildVersion; }; +/** Health monitoring endpoint + + Thji + */ class HttpHealthService : public HttpService { public: @@ -105,6 +112,7 @@ public: private: HttpRequestRouter m_Router; + RwLock m_InfoLock; HealthServiceInfo m_HealthInfo; }; diff --git a/src/zenhttp/include/zenhttp/httpcommon.h b/src/zenhttp/include/zenhttp/httpcommon.h index fb0d128a2..bc18549c9 100644 --- a/src/zenhttp/include/zenhttp/httpcommon.h +++ b/src/zenhttp/include/zenhttp/httpcommon.h @@ -179,9 +179,11 @@ IsHttpSuccessCode(int HttpCode) noexcept } [[nodiscard]] inline bool -IsHttpSuccessCode(HttpResponseCode HttpCode) +IsHttpSuccessCode(HttpResponseCode HttpCode) noexcept { return IsHttpSuccessCode(int(HttpCode)); } +std::string_view ToString(HttpResponseCode HttpCode); + } // namespace zen diff --git a/src/zenhttp/include/zenhttp/httpserver.h b/src/zenhttp/include/zenhttp/httpserver.h index dd66b1fe7..d1a562ee4 100644 --- a/src/zenhttp/include/zenhttp/httpserver.h +++ b/src/zenhttp/include/zenhttp/httpserver.h @@ -23,6 +23,8 @@ namespace zen { +class CbPackage; + /** HTTP Server Request */ class HttpServerRequest @@ -311,6 +313,17 @@ private: bool HandlePackageOffers(HttpService& Service, HttpServerRequest& Request, Ref<IHttpPackageHandler>& PackageHandlerRef); +struct IHttpStatsProvider +{ + virtual void HandleStatsRequest(HttpServerRequest& Request) = 0; +}; + +struct IHttpStatsService +{ + virtual void RegisterHandler(std::string_view Id, IHttpStatsProvider& Provider) = 0; + virtual void UnregisterHandler(std::string_view Id, IHttpStatsProvider& Provider) = 0; +}; + void http_forcelink(); // internal } // namespace zen diff --git a/src/zenhttp/include/zenhttp/httpstats.h b/src/zenhttp/include/zenhttp/httpstats.h index 732815a9a..4a1cdcb20 100644 --- a/src/zenhttp/include/zenhttp/httpstats.h +++ b/src/zenhttp/include/zenhttp/httpstats.h @@ -9,12 +9,7 @@ namespace zen { -struct IHttpStatsProvider -{ - virtual void HandleStatsRequest(HttpServerRequest& Request) = 0; -}; - -class HttpStatsService : public HttpService +class HttpStatsService : public HttpService, public IHttpStatsService { public: HttpStatsService(); @@ -22,8 +17,8 @@ public: virtual const char* BaseUri() const override; virtual void HandleRequest(HttpServerRequest& Request) override; - void RegisterHandler(std::string_view Id, IHttpStatsProvider& Provider); - void UnregisterHandler(std::string_view Id, IHttpStatsProvider& Provider); + virtual void RegisterHandler(std::string_view Id, IHttpStatsProvider& Provider) override; + virtual void UnregisterHandler(std::string_view Id, IHttpStatsProvider& Provider) override; private: spdlog::logger& m_Log; diff --git a/src/zenhttp/include/zenhttp/httptest.h b/src/zenhttp/include/zenhttp/httptest.h index 57d2d63f3..74db69785 100644 --- a/src/zenhttp/include/zenhttp/httptest.h +++ b/src/zenhttp/include/zenhttp/httptest.h @@ -9,6 +9,8 @@ #include <atomic> +#if ZEN_WITH_TESTS + namespace zen { /** @@ -53,3 +55,5 @@ private: }; } // namespace zen + +#endif diff --git a/src/zenhttp/monitoring/httpstats.cpp b/src/zenhttp/monitoring/httpstats.cpp index a873b4977..1dad48d68 100644 --- a/src/zenhttp/monitoring/httpstats.cpp +++ b/src/zenhttp/monitoring/httpstats.cpp @@ -2,6 +2,8 @@ #include "zenhttp/httpstats.h" +#include <zencore/compactbinarybuilder.h> + namespace zen { HttpStatsService::HttpStatsService() : m_Log(logging::Get("stats")) @@ -15,7 +17,7 @@ HttpStatsService::~HttpStatsService() const char* HttpStatsService::BaseUri() const { - return "/stats/"; + return "/stats"; } void @@ -46,10 +48,34 @@ HttpStatsService::HandleRequest(HttpServerRequest& Request) case HttpVerb::kHead: case HttpVerb::kGet: { - RwLock::SharedLockScope _(m_Lock); - if (auto It = m_Providers.find(std::string{Key}); It != end(m_Providers)) + if (Key.empty()) { - return It->second->HandleStatsRequest(Request); + CbObjectWriter Cbo; + + Cbo.BeginArray("providers"); + + { + RwLock::SharedLockScope _(m_Lock); + for (auto& Kv : m_Providers) + { + Cbo << Kv.first; + } + } + + Cbo.EndArray(); + + Request.WriteResponse(HttpResponseCode::OK, Cbo.Save()); + } + + if (Key[0] == '/') + { + Key.remove_prefix(1); + + RwLock::SharedLockScope _(m_Lock); + if (auto It = m_Providers.find(std::string{Key}); It != end(m_Providers)) + { + return It->second->HandleStatsRequest(Request); + } } } diff --git a/src/zenhttp/testing/httptest.cpp b/src/zenhttp/testing/httptest.cpp index 3e77e9c8c..a02e36bcc 100644 --- a/src/zenhttp/testing/httptest.cpp +++ b/src/zenhttp/testing/httptest.cpp @@ -6,6 +6,8 @@ #include <zencore/compactbinarypackage.h> #include <zencore/timer.h> +#if ZEN_WITH_TESTS + namespace zen { using namespace std::literals; @@ -205,3 +207,5 @@ HttpTestingService::PackageHandler::CreateTarget(const IoHash& Cid, uint64_t Sto } } // namespace zen + +#endif diff --git a/src/zenhttp/xmake.lua b/src/zenhttp/xmake.lua index b4154c0fa..411436b16 100644 --- a/src/zenhttp/xmake.lua +++ b/src/zenhttp/xmake.lua @@ -2,6 +2,7 @@ target('zenhttp') set_kind("static") + set_group("libs") add_headerfiles("**.h") add_files("**.cpp") add_files("httpsys.cpp", {unity_ignored=true}) @@ -13,7 +14,8 @@ target('zenhttp') "vcpkg::openssl", -- required by curl "vcpkg::zlib", -- required by curl "vcpkg::gsl-lite", - "vcpkg::http-parser" + "vcpkg::http-parser", + "vcpkg::cpr" ) add_options("httpsys") diff --git a/src/zenhttp/zenhttp.cpp b/src/zenhttp/zenhttp.cpp index 4bd6a5697..3e5b387b8 100644 --- a/src/zenhttp/zenhttp.cpp +++ b/src/zenhttp/zenhttp.cpp @@ -14,6 +14,7 @@ void zenhttp_forcelinktests() { http_forcelink(); + httpclient_forcelink(); forcelink_httpshared(); } |