From b180c024faa84b382a6c16f4fadb768ce207a08e Mon Sep 17 00:00:00 2001 From: travisladuke Date: Mon, 5 Feb 2024 12:38:44 -0800 Subject: [PATCH] feat: static file server this lets you host web apps out of :9993/app/{app_name} :9993/app/{other_app} from $ZT_HOME/app/{app_name} --- controller/EmbeddedNetworkController.cpp | 55 ++++++++++++++++++++++-- service/OneService.cpp | 5 +++ 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/controller/EmbeddedNetworkController.cpp b/controller/EmbeddedNetworkController.cpp index 9cb971a58..ac5d4d628 100644 --- a/controller/EmbeddedNetworkController.cpp +++ b/controller/EmbeddedNetworkController.cpp @@ -875,6 +875,53 @@ void EmbeddedNetworkController::configureHTTPControlPlane( std::string memberListPath = "/controller/network/([0-9a-fA-F]{16})/member"; std::string memberListPath2 = "/unstable/controller/network/([0-9a-fA-F]{16})/member"; std::string memberPath = "/controller/network/([0-9a-fA-F]{16})/member/([0-9a-fA-F]{10})"; + std::string appUiPath = "/app"; + + std::string homeDir(OSUtils::platformDefaultHomePath()); + static char appUiDir[16384]; + sprintf(appUiDir,"%s/%s",homeDir.c_str(),appUiPath.c_str()); + + + //static file server for controller-ui + auto ret = s.set_mount_point(appUiPath, appUiDir); + if (!ret) { + fprintf(stderr, "Mounting app directory failed. Creating it. Path: %s - Dir: %s\n", appUiPath.c_str(), appUiDir); + if (!OSUtils::mkdir(appUiDir)) { + fprintf(stderr, "Could not create app directory either. Path: %s - Dir: %s\n", appUiPath.c_str(), appUiDir); + } else { + ret = s.set_mount_point(appUiPath, appUiDir); + if (!ret) { + fprintf(stderr, "Really could not create and mount directory. Path: %s - Dir: %s\nWeb apps won't work.\n", appUiPath.c_str(), appUiDir); + } + } + } else { + // fallback to index.html for unknown paths/files + s.Get(appUiPath + R"(/(\w+)/(.*))", [&](const httplib::Request& req, httplib::Response& res) { + auto match = req.matches[1]; + if (match.matched) { + char indexHtmlPath[16384]; + sprintf(indexHtmlPath,"%s/%s/%s", appUiDir, match.str().c_str(), "index.html"); + + std::string indexHtml; + + if (!OSUtils::readFile(indexHtmlPath, indexHtml)) { + res.status = 500; + return; + } + + res.set_content(indexHtml.c_str(), "text/html"); + } else { + res.status = 500; + return; + } + }); + + // auto fix no trailing slash by redirecting + s.Get(appUiPath + R"(/(\w+))", [&](const httplib::Request& req, httplib::Response& res) { + res.status = 301; + res.set_header("location", req.path + "/"); + }); + } auto controllerGet = [&, setContent](const httplib::Request &req, httplib::Response &res) { char tmp[4096]; @@ -887,11 +934,11 @@ void EmbeddedNetworkController::configureHTTPControlPlane( (unsigned long long)OSUtils::now(), dbOk ? "true" : "false"); - if (!dbOk) { - res.status = 503; - } + if (!dbOk) { + res.status = 503; + } - setContent(req, res, tmp); + setContent(req, res, tmp); }; s.Get(controllerPath, controllerGet); sv6.Get(controllerPath, controllerGet); diff --git a/service/OneService.cpp b/service/OneService.cpp index eeebd90ed..4ad002502 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -1625,6 +1625,11 @@ class OneServiceImpl : public OneService isAuth = true; } + // Web Apps base path + if (req.path.rfind("/app", 0) == 0) { //starts with /app + isAuth = true; + } + if (!isAuth) { // check auth token if (req.has_header("x-zt1-auth")) {