mirror of
https://gitee.com/an-tao/drogon.git
synced 2024-12-04 20:57:50 +08:00
278 lines
8.6 KiB
C++
278 lines
8.6 KiB
C++
/**
|
|
*
|
|
* @file
|
|
* @author An Tao
|
|
* @section LICENSE
|
|
*
|
|
* Copyright 2018, An Tao. All rights reserved.
|
|
* Use of this source code is governed by a MIT license
|
|
* that can be found in the License file.
|
|
*
|
|
* Drogon
|
|
*
|
|
*/
|
|
|
|
#include "ConfigLoader.h"
|
|
|
|
#include <trantor/utils/Logger.h>
|
|
#include <drogon/HttpAppFramework.h>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <unistd.h>
|
|
using namespace drogon;
|
|
|
|
ConfigLoader::ConfigLoader(const std::string &configFile)
|
|
{
|
|
if (access(configFile.c_str(), 0) != 0)
|
|
{
|
|
std::cerr << "Config file " << configFile << " not found!" << std::endl;
|
|
exit(1);
|
|
}
|
|
if (access(configFile.c_str(), R_OK) != 0)
|
|
{
|
|
std::cerr << "No permission to read config file " << configFile << std::endl;
|
|
exit(1);
|
|
}
|
|
_configFile = configFile;
|
|
std::ifstream infile(configFile.c_str(), std::ifstream::in);
|
|
if (infile)
|
|
{
|
|
try
|
|
{
|
|
infile >> _configJsonRoot;
|
|
}
|
|
catch (const std::exception &exception)
|
|
{
|
|
std::cerr << "Configuration file format error! in " << configFile << ":" << std::endl;
|
|
std::cerr << exception.what() << std::endl;
|
|
exit(1);
|
|
}
|
|
}
|
|
}
|
|
ConfigLoader::~ConfigLoader()
|
|
{
|
|
}
|
|
static void loadLogSetting(const Json::Value &log)
|
|
{
|
|
if (!log)
|
|
return;
|
|
auto logPath = log.get("log_path", "").asString();
|
|
if (logPath != "")
|
|
{
|
|
auto baseName = log.get("logfile_base_name", "").asString();
|
|
auto logSize = log.get("log_size_limit", 100000000).asUInt64();
|
|
drogon::app().setLogPath(logPath, baseName, logSize);
|
|
}
|
|
auto logLevel = log.get("log_level", "DEBUG").asString();
|
|
if (logLevel == "TRACE")
|
|
{
|
|
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
|
|
}
|
|
else if (logLevel == "DEBUG")
|
|
{
|
|
trantor::Logger::setLogLevel(trantor::Logger::DEBUG);
|
|
}
|
|
else if (logLevel == "INFO")
|
|
{
|
|
trantor::Logger::setLogLevel(trantor::Logger::INFO);
|
|
}
|
|
else if (logLevel == "WARN")
|
|
{
|
|
trantor::Logger::setLogLevel(trantor::Logger::WARN);
|
|
}
|
|
}
|
|
static void loadControllers(const Json::Value &controllers)
|
|
{
|
|
if (!controllers)
|
|
return;
|
|
for (auto controller : controllers)
|
|
{
|
|
auto path = controller.get("path", "").asString();
|
|
auto ctrlName = controller.get("controller", "").asString();
|
|
if (path == "" || ctrlName == "")
|
|
continue;
|
|
std::vector<any> constraints;
|
|
if (!controller["http_methods"].isNull())
|
|
{
|
|
for (auto method : controller["http_methods"])
|
|
{
|
|
auto strMethod = method.asString();
|
|
std::transform(strMethod.begin(), strMethod.end(), strMethod.begin(), tolower);
|
|
if (strMethod == "get")
|
|
{
|
|
constraints.push_back(Get);
|
|
}
|
|
else if (strMethod == "post")
|
|
{
|
|
constraints.push_back(Post);
|
|
}
|
|
else if (strMethod == "head") //The branch nerver work
|
|
{
|
|
constraints.push_back(Head);
|
|
}
|
|
else if (strMethod == "put")
|
|
{
|
|
constraints.push_back(Put);
|
|
}
|
|
else if (strMethod == "delete")
|
|
{
|
|
constraints.push_back(Delete);
|
|
}
|
|
}
|
|
}
|
|
if (!controller["filters"].isNull())
|
|
{
|
|
for (auto filter : controller["filters"])
|
|
{
|
|
constraints.push_back(filter.asString());
|
|
}
|
|
}
|
|
drogon::app().registerHttpSimpleController(path, ctrlName, constraints);
|
|
}
|
|
}
|
|
static void loadApp(const Json::Value &app)
|
|
{
|
|
if (!app)
|
|
return;
|
|
//threads number
|
|
auto threadsNum = app.get("threads_num", 1).asUInt64();
|
|
drogon::app().setThreadNum(threadsNum);
|
|
//session
|
|
auto enableSession = app.get("enable_session", false).asBool();
|
|
auto timeout = app.get("session_timeout", 0).asUInt64();
|
|
if (enableSession)
|
|
drogon::app().enableSession(timeout);
|
|
else
|
|
drogon::app().disableSession();
|
|
//document root
|
|
auto documentRoot = app.get("document_root", "").asString();
|
|
if (documentRoot != "")
|
|
{
|
|
drogon::app().setDocumentRoot(documentRoot);
|
|
}
|
|
//upload path
|
|
auto uploadPath = app.get("upload_path", "uploads").asString();
|
|
drogon::app().setUploadPath(uploadPath);
|
|
//file types
|
|
auto fileTypes = app["file_types"];
|
|
if (fileTypes.isArray() && !fileTypes.empty())
|
|
{
|
|
std::vector<std::string> types;
|
|
for (auto fileType : fileTypes)
|
|
{
|
|
types.push_back(fileType.asString());
|
|
LOG_TRACE << "file type:" << types.back();
|
|
}
|
|
drogon::app().setFileTypes(types);
|
|
}
|
|
//max connections
|
|
auto maxConns = app.get("max_connections", 0).asUInt64();
|
|
if (maxConns > 0)
|
|
{
|
|
drogon::app().setMaxConnectionNum(maxConns);
|
|
}
|
|
//max connections per IP
|
|
auto maxConnsPerIP = app.get("max_connections_per_ip", 0).asUInt64();
|
|
if (maxConnsPerIP > 0)
|
|
{
|
|
drogon::app().setMaxConnectionNumPerIP(maxConnsPerIP);
|
|
}
|
|
|
|
//dynamic views
|
|
auto enableDynamicViews = app.get("load_dynamic_views", false).asBool();
|
|
if (enableDynamicViews)
|
|
{
|
|
auto viewsPaths = app["dynamic_views_path"];
|
|
if (viewsPaths.isArray() && viewsPaths.size() > 0)
|
|
{
|
|
std::vector<std::string> paths;
|
|
for (auto viewsPath : viewsPaths)
|
|
{
|
|
paths.push_back(viewsPath.asString());
|
|
LOG_TRACE << "views path:" << paths.back();
|
|
}
|
|
drogon::app().enableDynamicViewsLoading(paths);
|
|
}
|
|
}
|
|
//log
|
|
loadLogSetting(app["log"]);
|
|
//run as daemon
|
|
auto runAsDaemon = app.get("run_as_daemon", false).asBool();
|
|
if (runAsDaemon)
|
|
{
|
|
drogon::app().enableRunAsDaemon();
|
|
}
|
|
//relaunch
|
|
auto relaunch = app.get("relaunch_on_error", false).asBool();
|
|
if (relaunch)
|
|
{
|
|
drogon::app().enableRelaunchOnError();
|
|
}
|
|
auto useSendfile = app.get("use_sendfile", true).asBool();
|
|
drogon::app().enableSendfile(useSendfile);
|
|
auto useGzip = app.get("use_gzip", true).asBool();
|
|
drogon::app().enableGzip(useGzip);
|
|
auto staticFilesCacheTime = app.get("static_files_cache_time", 5).asInt();
|
|
drogon::app().setStaticFilesCacheTime(staticFilesCacheTime);
|
|
loadControllers(app["simple_controllers_map"]);
|
|
//Kick off idle connections
|
|
auto kickOffTimeout = app.get("idle_connection_timeout", 60).asUInt64();
|
|
drogon::app().setIdleConnectionTimeout(kickOffTimeout);
|
|
}
|
|
static void loadDbClients(const Json::Value &dbClients)
|
|
{
|
|
#if USE_POSTGRESQL
|
|
if (!dbClients)
|
|
return;
|
|
for (auto &client : dbClients)
|
|
{
|
|
auto type = client.get("rdbms", "postgreSQL").asString();
|
|
auto host = client.get("host", "127.0.0.1").asString();
|
|
auto port = client.get("port", 5432).asUInt();
|
|
auto dbname = client.get("dbname", "").asString();
|
|
if (dbname == "")
|
|
{
|
|
std::cerr << "Please configure dbname in the configuration file" << std::endl;
|
|
exit(1);
|
|
}
|
|
auto user = client.get("user", "postgres").asString();
|
|
auto password = client.get("passwd", "").asString();
|
|
auto connNum = client.get("connection_number", 1).asUInt();
|
|
auto name = client.get("name", "default").asString();
|
|
drogon::app().createDbClient(type, host, (u_short)port, dbname, user, password, connNum, name);
|
|
}
|
|
#endif
|
|
}
|
|
static void loadListeners(const Json::Value &listeners)
|
|
{
|
|
if (!listeners)
|
|
return;
|
|
LOG_TRACE << "Has " << listeners.size() << " listeners";
|
|
for (auto listener : listeners)
|
|
{
|
|
auto addr = listener.get("address", "0.0.0.0").asString();
|
|
auto port = (uint16_t)listener.get("port", 0).asUInt();
|
|
auto useSSL = listener.get("https", false).asBool();
|
|
auto cert = listener.get("cert", "").asString();
|
|
auto key = listener.get("key", "").asString();
|
|
LOG_TRACE << "Add listener:" << addr << ":" << port;
|
|
drogon::app().addListener(addr, port, useSSL, cert, key);
|
|
}
|
|
}
|
|
static void loadSSL(const Json::Value &sslFiles)
|
|
{
|
|
if (!sslFiles)
|
|
return;
|
|
auto key = sslFiles.get("key", "").asString();
|
|
auto cert = sslFiles.get("cert", "").asString();
|
|
drogon::app().setSSLFiles(cert, key);
|
|
}
|
|
void ConfigLoader::load()
|
|
{
|
|
//std::cout<<_configJsonRoot<<std::endl;
|
|
loadApp(_configJsonRoot["app"]);
|
|
loadSSL(_configJsonRoot["ssl"]);
|
|
loadListeners(_configJsonRoot["listeners"]);
|
|
loadDbClients(_configJsonRoot["db_clients"]);
|
|
}
|