web_vendor.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #include "web_handler.h"
  2. #include "web_vendor.h"
  3. #include <json/json.h>
  4. /* clang-format */
  5. #include <goahead.h>
  6. static vendor::MyOpt myOpts_[] = {
  7. {"help", no_argument, 'h', "[options] [documents] [IPaddress][:port]..." },
  8. {"auth", required_argument, 0, "User and role configuration" },
  9. {"debug", no_argument, 0, "Run in debug mode" },
  10. {"home", required_argument, 0, "Change to directory to run" },
  11. {"log", required_argument, 0, "logFile:level, Log to file file at verbosity level"},
  12. {"route", required_argument, 0, "route file" },
  13. {"port", required_argument, 0, "set port, default: 8880" },
  14. {"delay", required_argument, 0, "delay secs to quit" },
  15. {"document", required_argument, 0, "document" },
  16. {"verbose", required_argument, 0, "Same as --log stderr:2" },
  17. {"version", no_argument, 0, "version information" }
  18. };
  19. const std::string DAS_WEB_DOCUMENT = ".";
  20. const int32_t DAS_WEB_PORT = 8880;
  21. const int32_t DAS_WEB_SSL_PORT = 8881;
  22. WebVendor::WebVendor() : listenPort_(DAS_WEB_PORT), docFile_(DAS_WEB_DOCUMENT), homeDir_(VENDOR_WWW_PATH), duration_(0)
  23. {
  24. routeFile_ = ""; // "route.txt";
  25. authFile_ = ""; // "auth.txt";
  26. logSetPath(std::string(VENDOR_LOG_PATH).c_str());
  27. HTELINK_LOG_INFO("set log path: %s", VENDOR_LOG_PATH.c_str());
  28. }
  29. WebVendor::~WebVendor()
  30. {
  31. finish_ = 1;
  32. websClose();
  33. }
  34. int WebVendor::ParseCmdline(const std::string &optname, const std::string &optarg)
  35. {
  36. if (optname == "auth") {
  37. authFile_ = optarg;
  38. } else if (optname == "debug") {
  39. websSetDebug(1);
  40. debug_ = true;
  41. } else if (optname == "home") {
  42. homeDir_ = optarg;
  43. if (chdir(homeDir_.c_str()) < 0) {
  44. HTELINK_LOG_ERR("Cannot change directory to %s", homeDir_.c_str());
  45. exit(-1);
  46. }
  47. HTELINK_LOG_INFO("change to dir: %s", homeDir_.c_str());
  48. } else if (optname == "log") {
  49. logSetPath(optarg.c_str());
  50. HTELINK_LOG_INFO("set log path: %s", optarg.c_str());
  51. } else if (optname == "route") {
  52. routeFile_ = optarg;
  53. } else if (optname == "document") {
  54. docFile_ = optarg;
  55. } else if (optname == "port") {
  56. listenPort_ = atoi(optarg.c_str());
  57. } else if (optname == "port") {
  58. duration_ = atoi(optarg.c_str());
  59. } else if (optname == "verbose") {
  60. logSetPath(optarg.c_str());
  61. HTELINK_LOG_INFO("set log path: %s", optarg.c_str());
  62. } else if (optname == "version") {
  63. } else {
  64. exit(-1);
  65. }
  66. return 0;
  67. }
  68. vendor::MyOpt *WebVendor::GetOpts()
  69. {
  70. return myOpts_;
  71. }
  72. int WebVendor::GetOptSize()
  73. {
  74. return sizeof(myOpts_) / sizeof(myOpts_[0]);
  75. }
  76. void sigHandler(int sig)
  77. {
  78. HTELINK_LOG_DEBUG("sigHandler, %d", sig);
  79. }
  80. int WebVendor::Run()
  81. {
  82. finish_ = 0;
  83. signal(SIGTERM, sigHandler);
  84. signal(SIGPIPE, SIG_IGN);
  85. // _fmode = _O_BINARY;
  86. if (routeFile_.empty()) {
  87. routeFile_ = homeDir_ + "/route.txt";
  88. }
  89. if (authFile_.empty()) {
  90. authFile_ = homeDir_ + "/route.txt";
  91. }
  92. HTELINK_LOG_INFO(
  93. "webs Open doc %s, route file %s, auth file %s", docFile_.c_str(), routeFile_.c_str(), authFile_.c_str());
  94. if (websOpen(docFile_.empty() ? nullptr : docFile_.c_str(), routeFile_.c_str()) < 0) {
  95. HTELINK_LOG_ERR("Cannot initialize server. Exiting.");
  96. return -1;
  97. }
  98. websSetPasswordStoreVerify([](Webs *wp) -> bool {
  99. return WebHandler::instance()->LoginVerify(wp);
  100. });
  101. websSetIndex("index.html");
  102. DefineWeb();
  103. HTELINK_LOG_INFO("webs Load %s", authFile_.c_str());
  104. if (websLoad(authFile_.c_str()) < 0) {
  105. HTELINK_LOG_ERR("Cannot load %s", authFile_.c_str());
  106. return -1;
  107. }
  108. /* clang-format off */
  109. std::string listHosts[] = {
  110. std::string("http://*:") + std::to_string(listenPort_),
  111. // std::string("https://*:") + std::to_string(DAS_WEB_SSL_PORT)
  112. };
  113. /* clang-format on */
  114. for (std::string &host : listHosts) {
  115. HTELINK_LOG_INFO("webs Listen %s", host.c_str());
  116. if (websListen(host.c_str()) < 0) {
  117. HTELINK_LOG_ERR("Cannot listen %s", host.c_str());
  118. return -1;
  119. }
  120. }
  121. DumpWebVendor();
  122. if (duration_ > 0) {
  123. HTELINK_LOG_INFO("Running for %d secs\n", duration_);
  124. websStartEvent(
  125. duration_ * 1000,
  126. [](void *data, int id) {
  127. websStopEvent(id);
  128. },
  129. &finish_);
  130. }
  131. websServiceEvents(&finish_);
  132. HTELINK_LOG_INFO("webs service exit, err = %s", strerror(errno));
  133. return 0;
  134. }
  135. std::string WebVendor::Name()
  136. {
  137. return "web-deamon";
  138. }
  139. void WebVendor::Stop(int signal)
  140. {
  141. HTELINK_LOG_INFO("webs exit, signal = %d", signal);
  142. finish_ = 1;
  143. }
  144. void WebVendor::DumpWebVendor(void)
  145. {
  146. char home[ME_GOAHEAD_LIMIT_STRING];
  147. getcwd(home, sizeof(home));
  148. HTELINK_LOG_INFO("Configuration for %s", PRODUCT_NAME);
  149. HTELINK_LOG_INFO("---------------------------------------------");
  150. HTELINK_LOG_INFO("Version: %s", DAS_VERSION);
  151. HTELINK_LOG_INFO("BuildType: %s", ME_DEBUG ? "Debug" : "Release");
  152. HTELINK_LOG_INFO("CPU: %s", ME_CPU);
  153. HTELINK_LOG_INFO("OS: %s", ME_OS);
  154. HTELINK_LOG_INFO("Host: %s", websGetServerUrl());
  155. HTELINK_LOG_INFO("Directory: %s", home);
  156. HTELINK_LOG_INFO("Documents: %s", websGetDocuments());
  157. HTELINK_LOG_INFO("Configure: %s", ME_CONFIG_CMD);
  158. HTELINK_LOG_INFO("---------------------------------------------");
  159. }
  160. void WebVendor::DefineWeb()
  161. {
  162. if (debug_) {
  163. websDefineHandler(
  164. "debug",
  165. [](Webs *wp) -> bool {
  166. HTELINK_LOG_DEBUG("webs debug path: %s, prefix = %s, user = %s, password = %s, decode = %d method = "
  167. "%s, protocol = %s",
  168. wp->path == nullptr ? "" : wp->path, wp->route->prefix, wp->username, wp->password, wp->encoded,
  169. wp->method, wp->protocol);
  170. return false;
  171. },
  172. 0, 0, 0);
  173. }
  174. //
  175. websDefineHandler(
  176. "uid", 0,
  177. [](Webs *wp) -> bool {
  178. HTELINK_LOG_DEBUG("webs uid path: %s, prefix = %s, user = %s, method = %s, protocol = %s",
  179. wp->path == nullptr ? "" : wp->path, wp->route->prefix, wp->username, wp->method, wp->protocol);
  180. return WebHandler::instance()->WebResult(wp, "/uid/");
  181. },
  182. 0, 0);
  183. websDefineHandler(
  184. "ajax", 0,
  185. [](Webs *wp) -> bool {
  186. HTELINK_LOG_DEBUG("webs ajax path: %s, prefix = %s, user = %s, method = %s, protocol = %s",
  187. wp->path == nullptr ? "" : wp->path, wp->route->prefix, wp->username, wp->method, wp->protocol);
  188. return WebHandler::instance()->WebResult(wp, "/ajax/");
  189. },
  190. 0, 0);
  191. // "route uri=/ajax handler=ajax\n route uri=%s handler=uid\n route uri=/";
  192. websAddRoute("/ajax", "ajax", 0);
  193. websAddRoute(std::to_string(getuid()).c_str(), "uid", 0);
  194. if (debug_) {
  195. websAddRoute("/", "debug", 0);
  196. }
  197. websAddRoute("/", "file", -1);
  198. }