#include "web_handler.h" #include "web_vendor.h" #include /* clang-format */ #include static vendor::MyOpt myOpts_[] = { {"help", no_argument, 'h', "[options] [documents] [IPaddress][:port]..." }, {"auth", required_argument, 0, "User and role configuration" }, {"debug", no_argument, 0, "Run in debug mode" }, {"home", required_argument, 0, "Change to directory to run" }, {"log", required_argument, 0, "logFile:level, Log to file file at verbosity level"}, {"route", required_argument, 0, "route file" }, {"port", required_argument, 0, "set port, default: 8880" }, {"delay", required_argument, 0, "delay secs to quit" }, {"document", required_argument, 0, "document" }, {"verbose", required_argument, 0, "Same as --log stderr:2" }, {"version", no_argument, 0, "version information" } }; const std::string DAS_WEB_DOCUMENT = "."; const int32_t DAS_WEB_PORT = 8880; const int32_t DAS_WEB_SSL_PORT = 8881; WebVendor::WebVendor() : listenPort_(DAS_WEB_PORT), docFile_(DAS_WEB_DOCUMENT), homeDir_(VENDOR_WWW_PATH), duration_(0) { routeFile_ = ""; // "route.txt"; authFile_ = ""; // "auth.txt"; logSetPath(std::string(VENDOR_LOG_PATH).c_str()); HTELINK_LOG_INFO("set log path: %s", VENDOR_LOG_PATH.c_str()); } WebVendor::~WebVendor() { finish_ = 1; websClose(); } int WebVendor::ParseCmdline(const std::string &optname, const std::string &optarg) { if (optname == "auth") { authFile_ = optarg; } else if (optname == "debug") { websSetDebug(1); debug_ = true; } else if (optname == "home") { homeDir_ = optarg; if (chdir(homeDir_.c_str()) < 0) { HTELINK_LOG_ERR("Cannot change directory to %s", homeDir_.c_str()); exit(-1); } HTELINK_LOG_INFO("change to dir: %s", homeDir_.c_str()); } else if (optname == "log") { logSetPath(optarg.c_str()); HTELINK_LOG_INFO("set log path: %s", optarg.c_str()); } else if (optname == "route") { routeFile_ = optarg; } else if (optname == "document") { docFile_ = optarg; } else if (optname == "port") { listenPort_ = atoi(optarg.c_str()); } else if (optname == "port") { duration_ = atoi(optarg.c_str()); } else if (optname == "verbose") { logSetPath(optarg.c_str()); HTELINK_LOG_INFO("set log path: %s", optarg.c_str()); } else if (optname == "version") { } else { exit(-1); } return 0; } vendor::MyOpt *WebVendor::GetOpts() { return myOpts_; } int WebVendor::GetOptSize() { return sizeof(myOpts_) / sizeof(myOpts_[0]); } void sigHandler(int sig) { HTELINK_LOG_DEBUG("sigHandler, %d", sig); } int WebVendor::Run() { finish_ = 0; signal(SIGTERM, sigHandler); signal(SIGPIPE, SIG_IGN); // _fmode = _O_BINARY; if (routeFile_.empty()) { routeFile_ = homeDir_ + "/route.txt"; } if (authFile_.empty()) { authFile_ = homeDir_ + "/route.txt"; } HTELINK_LOG_INFO( "webs Open doc %s, route file %s, auth file %s", docFile_.c_str(), routeFile_.c_str(), authFile_.c_str()); if (websOpen(docFile_.empty() ? nullptr : docFile_.c_str(), routeFile_.c_str()) < 0) { HTELINK_LOG_ERR("Cannot initialize server. Exiting."); return -1; } websSetPasswordStoreVerify([](Webs *wp) -> bool { return WebHandler::instance()->LoginVerify(wp); }); websSetIndex("index.html"); DefineWeb(); HTELINK_LOG_INFO("webs Load %s", authFile_.c_str()); if (websLoad(authFile_.c_str()) < 0) { HTELINK_LOG_ERR("Cannot load %s", authFile_.c_str()); return -1; } /* clang-format off */ std::string listHosts[] = { std::string("http://*:") + std::to_string(listenPort_), // std::string("https://*:") + std::to_string(DAS_WEB_SSL_PORT) }; /* clang-format on */ for (std::string &host : listHosts) { HTELINK_LOG_INFO("webs Listen %s", host.c_str()); if (websListen(host.c_str()) < 0) { HTELINK_LOG_ERR("Cannot listen %s", host.c_str()); return -1; } } DumpWebVendor(); if (duration_ > 0) { HTELINK_LOG_INFO("Running for %d secs\n", duration_); websStartEvent( duration_ * 1000, [](void *data, int id) { websStopEvent(id); }, &finish_); } websServiceEvents(&finish_); HTELINK_LOG_INFO("webs service exit, err = %s", strerror(errno)); return 0; } std::string WebVendor::Name() { return "web-deamon"; } void WebVendor::Stop(int signal) { HTELINK_LOG_INFO("webs exit, signal = %d", signal); finish_ = 1; } void WebVendor::DumpWebVendor(void) { char home[ME_GOAHEAD_LIMIT_STRING]; getcwd(home, sizeof(home)); HTELINK_LOG_INFO("Configuration for %s", PRODUCT_NAME); HTELINK_LOG_INFO("---------------------------------------------"); HTELINK_LOG_INFO("Version: %s", DAS_VERSION); HTELINK_LOG_INFO("BuildType: %s", ME_DEBUG ? "Debug" : "Release"); HTELINK_LOG_INFO("CPU: %s", ME_CPU); HTELINK_LOG_INFO("OS: %s", ME_OS); HTELINK_LOG_INFO("Host: %s", websGetServerUrl()); HTELINK_LOG_INFO("Directory: %s", home); HTELINK_LOG_INFO("Documents: %s", websGetDocuments()); HTELINK_LOG_INFO("Configure: %s", ME_CONFIG_CMD); HTELINK_LOG_INFO("---------------------------------------------"); } void WebVendor::DefineWeb() { if (debug_) { websDefineHandler( "debug", [](Webs *wp) -> bool { HTELINK_LOG_DEBUG("webs debug path: %s, prefix = %s, user = %s, password = %s, decode = %d method = " "%s, protocol = %s", wp->path == nullptr ? "" : wp->path, wp->route->prefix, wp->username, wp->password, wp->encoded, wp->method, wp->protocol); return false; }, 0, 0, 0); } // websDefineHandler( "uid", 0, [](Webs *wp) -> bool { HTELINK_LOG_DEBUG("webs uid path: %s, prefix = %s, user = %s, method = %s, protocol = %s", wp->path == nullptr ? "" : wp->path, wp->route->prefix, wp->username, wp->method, wp->protocol); return WebHandler::instance()->WebResult(wp, "/uid/"); }, 0, 0); websDefineHandler( "ajax", 0, [](Webs *wp) -> bool { HTELINK_LOG_DEBUG("webs ajax path: %s, prefix = %s, user = %s, method = %s, protocol = %s", wp->path == nullptr ? "" : wp->path, wp->route->prefix, wp->username, wp->method, wp->protocol); return WebHandler::instance()->WebResult(wp, "/ajax/"); }, 0, 0); // "route uri=/ajax handler=ajax\n route uri=%s handler=uid\n route uri=/"; websAddRoute("/ajax", "ajax", 0); websAddRoute(std::to_string(getuid()).c_str(), "uid", 0); if (debug_) { websAddRoute("/", "debug", 0); } websAddRoute("/", "file", -1); }