module daster; import vibe.vibe; import singlog; import readconf; import core.stdc.stdlib : exit, EXIT_SUCCESS, EXIT_FAILURE; import std.stdio: writefln; import std.getopt; import std.file; import std.path; import std.algorithm; import std.array; import verinfo; import pgdb; import structures; import requests.numbers; import requests.sms; import requests.ussd; import requests.server; static ServerInfo serverInfo; private void showVersion() { writefln("daster версия %s, собрано %s", getDasterVersion(), __DATE__); } int main(string[] args) { log.level(log.INFORMATION); log.output(log.SYSLOG); bool flagVersion; string flagSettings; try { auto opt = getopt( args, config.bundling, config.caseSensitive, "settings|s", "<файл> Путь к файлу конфигурации settings.conf", &flagSettings, "version|v", "Текущая версия программы", &flagVersion ); if (opt.helpWanted) { showVersion(); defaultGetoptPrinter( "Использование: daster [ОПЦИИ]...\n", opt.options ); return EXIT_SUCCESS; } if (flagVersion) { showVersion(); return EXIT_SUCCESS; } } catch (GetOptException e) { showVersion(); log.c(e.msg); log.i("Попробуйте 'daster -h' для дополнительной информации"); log.i("https://git.zhirov.kz/alexander/daster"); return EXIT_FAILURE; } if (!flagSettings.length) flagSettings = "./settings.conf"; if (!flagSettings.exists) { log.c("Файл конфигурации не найден: " ~ flagSettings); exit(1); } rc.read(flagSettings); auto webHost = rcWebHost(); serverInfo = ServerInfo(webHost.title); if (webHost.loglevel != -1) log.level(webHost.loglevel); if (webHost.logoutput) log.output(webHost.logoutput); if (webHost.logfile.length) log.file(webHost.logfile); rcAsteriskDB(); auto router = new URLRouter; router.post("/", &postReq); router.get("/", &getReq); router.get("*", serveStaticFiles(buildPath(webHost.data, "public"))); router.get("*", serveStaticFiles(buildPath(webHost.data, "images"))); router.get("*", serveStaticFiles(buildPath(webHost.data, "js"))); router.get("*", serveStaticFiles(buildPath(webHost.data, "jq"))); auto memorySessionStore = new MemorySessionStore; auto settingsHTTP = new HTTPServerSettings; auto settingsHTTPS = new HTTPServerSettings; if (webHost.http) { settingsHTTP.sessionStore = memorySessionStore; settingsHTTP.port = webHost.http; settingsHTTP.bindAddresses = ["::1"] ~ webHost.addresses; } if (webHost.https) { settingsHTTPS.sessionStore = memorySessionStore; settingsHTTPS.port = webHost.https; settingsHTTPS.bindAddresses = ["::1"] ~ webHost.addresses; settingsHTTPS.tlsContext = createTLSContext(TLSContextKind.server); settingsHTTPS.tlsContext.useCertificateChainFile(webHost.cert); settingsHTTPS.tlsContext.usePrivateKeyFile(webHost.key); } startWebServer(webHost, settingsHTTP, settingsHTTPS, router); return EXIT_SUCCESS; } void startWebServer(WebHost wh, HTTPServerSettings http, HTTPServerSettings https, URLRouter router) { if (wh.http && wh.https) { auto listenerHTTP = listenHTTP(http, router); auto listenerHTTPS = listenHTTP(https, router); scope (exit) { listenerHTTP.stopListening(); } scope (exit) { listenerHTTPS.stopListening(); } runApplication(); } else if (wh.http) { auto listenerHTTP = listenHTTP(http, router); scope (exit) { listenerHTTP.stopListening(); } runApplication(); } else if (wh.https) { auto listenerHTTPS = listenHTTP(https, router); scope (exit) { listenerHTTPS.stopListening(); } runApplication(); } } void getReq(HTTPServerRequest req, HTTPServerResponse res) { // if (req.session) { // auto user = req.session.get!UserData("userData"); // if (user.loggedIn) { // renderMainPage(req, res); // return; // } // } // render!("index.dt", serverInfo)(res); renderMainPage(req, res); } void renderMainPage(HTTPServerRequest req, HTTPServerResponse res) { render!("index.dt", serverInfo)(res); } void postReq(HTTPServerRequest req, HTTPServerResponse res) { if (req.method != HTTPMethod.POST) return; auto jsr = req.json; string query = jsr["query"].get!string; if (query.empty) return; // if (query != "authorization" && !checkAuth(req)) { // res.send( // true, // "Сессия не существует. Перезагрузите страницу" // ); // return; // } log.d("json request: " ~ jsr.to!string); switch (query) { // case "authorization": // authorization(req, res); // break; // case "logout": // logout(req, res); // break; case "listnumbergroups": getListNumberGroups(req, res); break; case "listgroupnumbers": getListGroupNumbers(req, res); break; case "viewnumber": getViewNumber(req, res); break; case "addnumber": getAddNumber(req, res); break; case "writenumber": sendWriteNumber(req, res); break; case "updatenumber": sendUpdateNumber(req, res); break; case "delnumber": sendDelNumber(req, res); break; case "listsmsgroups": getListSMSGroups(req, res); break; case "listgroupsms": getListGroupSMS(req, res); break; case "viewsms": getViewSMS(req, res); break; case "delsms": sendDelSMS(req, res); break; case "listussdgroups": getListUSSDGroups(req, res); break; case "listgroupussd": getListGroupUSSD(req, res); break; case "viewussd": getViewUSSD(req, res); break; case "delussd": sendDelUSSD(req, res); break; case "serverinfo": getServerInfo(req, res); break; case "writeserverinfo": sendWriteServerInfo(req, res); break; default: res.redirect("/"); } } void rcAsteriskDB() { ConfigSection asteriskDB; try { asteriskDB = rc[]["daster-db"]; } catch (Exception e) { log.c("В конфигурационном файле не верны настройки daster-db"); exit(1); } if (asteriskDB["host"].empty) { log.c("В конфигурационном файле не верны настройки daster-db.host"); exit(1); } if (asteriskDB["port"].empty) { log.c("В конфигурационном файле не верны настройки daster-db.port"); exit(1); } if (asteriskDB["dbname"].empty) { log.c("В конфигурационном файле не верны настройки daster-db.dbname"); exit(1); } if (asteriskDB["user"].empty) { log.c("В конфигурационном файле не верны настройки daster-db.user"); exit(1); } try { pgsql( "hostaddr=" ~ asteriskDB["host"] ~ " port=" ~ asteriskDB["port"] ~ " dbname=" ~ asteriskDB["dbname"] ~ " user=" ~ asteriskDB["user"] ~ " password=" ~ asteriskDB["password"] ); } catch (Exception e) { log.c(e.msg); exit(1); } } WebHost rcWebHost() { WebHost wh; ConfigSection webHost; try { webHost = rc[]["web-host"]; } catch (Exception e) { log.c("В конфигурационном файле не верны настройки web-host"); exit(1); } if (webHost["addresses"].empty) { log.c("В конфигурационном файле не верны настройки web-host.addresses"); exit(1); } try { wh.addresses = webHost["addresses"].to!string.split(',').map!(a => a.strip).array; } catch (Exception e) { log.c("В конфигурационном файле не верны настройки web-host.addresses"); exit(1); } if (webHost["http"].empty && webHost["https"].empty) { log.c("В конфигурационном файле не верны настройки web-host.[http|https]: должен быть указан хотя бы один протокол"); exit(1); } if (!webHost["http"].empty) { try { wh.http = webHost["http"].to!ushort; } catch (Exception e) { log.c("В конфигурационном файле не верны настройки web-host.http"); exit(1); } } if (!webHost["https"].empty) { try { wh.https = webHost["https"].to!ushort; } catch (Exception e) { log.c("В конфигурационном файле не верны настройки web-host.https"); exit(1); } } if (!webHost["https"].empty) { if (webHost["cert"].empty || webHost["key"].empty) { log.c("В конфигурационном файле не верны настройки web-host.[cert|key]: необходимо указать сертификат и ключ для использования https протокола" ); exit(1); } } try { wh.cert = webHost["cert"]; } catch (Exception e) { log.c("В конфигурационном файле не верны настройки web-host.cert"); exit(1); } try { wh.key = webHost["key"]; } catch (Exception e) { log.c("В конфигурационном файле не верны настройки web-host.key"); exit(1); } if (!webHost["data"].empty) { string data; try { data = webHost["data"]; } catch (Exception e) { log.c("В конфигурационном файле не верны настройки web-host.data"); exit(1); } if (data.exists) { if (!buildPath(data, "public").exists) { log.c("В конфигурационном файле не верны настройки web-host.data - каталог не существует: public"); exit(1); } if (!buildPath(data, "js").exists) { log.c("В конфигурационном файле не верны настройки web-host.data - каталог не существует: js"); exit(1); } if (!buildPath(data, "images").exists) { log.c("В конфигурационном файле не верны настройки web-host.data - каталог не существует: images"); exit(1); } } else { log.c("В конфигурационном файле не верны настройки web-host.data - каталог не существует: " ~ data); exit(1); } wh.data = data; } if (!webHost["title"].empty) { try { wh.title = webHost["title"]; } catch (Exception e) { log.w("Заголовок не был установлен - web-host.title"); } } if (!webHost["loglevel"].empty) { try { wh.loglevel = webHost["loglevel"].to!int; if (wh.loglevel < 0 || wh.loglevel > 6) throw new Exception("несуществующий уровень"); } catch (Exception e) { log.c("В конфигурационном файле не верны настройки web-host.loglevel: " ~ e.msg); exit(1); } } if (!webHost["logoutput"].empty) { try { wh.logoutput = webHost["logoutput"] .to!string.split(',') .map!((a) { auto flag = a.strip.to!int; if ([1, 2, 4].canFind(flag)) return flag; log.c("В конфигурационном файле не верны настройки web-host.logoutput"); exit(1); }) .fold!((a, b) => a | b); } catch (Exception e) { log.c("В конфигурационном файле не верны настройки web-host.logoutput"); exit(1); } if (wh.logoutput & 4) { if (webHost["logfile"].empty) { log.c("В конфигурационном файле не верны настройки web-host.logfile"); exit(1); } try { wh.logfile = webHost["logfile"]; } catch (Exception e) { log.c("В конфигурационном файле не верны настройки web-host.logfile"); exit(1); } } } return wh; }