Removed the ConfigLoader.

This commit is contained in:
Relintai 2021-06-20 17:37:21 +02:00
parent bb1f871478
commit 9e0621daf0
3 changed files with 3 additions and 505 deletions

View File

@ -1,458 +0,0 @@
/**
*
* @file ConfigLoader.cc
* @author An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* Drogon
*
*/
#include "ConfigLoader.h"
#include "HttpAppFrameworkImpl.h"
#include <trantor/utils/Logger.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <thread>
#ifndef _WIN32
#include <unistd.h>
#else
#include <io.h>
#endif
using namespace drogon;
static bool bytesSize(std::string &sizeStr, size_t &size) {
if (sizeStr.empty()) {
size = -1;
return true;
} else {
size = 1;
switch (sizeStr[sizeStr.length() - 1]) {
case 'k':
case 'K':
size = 1024;
sizeStr.resize(sizeStr.length() - 1);
break;
case 'M':
case 'm':
size = (1024 * 1024);
sizeStr.resize(sizeStr.length() - 1);
break;
case 'g':
case 'G':
size = (1024 * 1024 * 1024);
sizeStr.resize(sizeStr.length() - 1);
break;
#if ((ULONG_MAX) != (UINT_MAX))
// 64bit system
case 't':
case 'T':
size = (1024L * 1024L * 1024L * 1024L);
sizeStr.resize(sizeStr.length() - 1);
break;
#endif
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '7':
case '8':
case '9':
break;
default:
return false;
break;
}
std::istringstream iss(sizeStr);
size_t tmpSize;
iss >> tmpSize;
if (iss.fail()) {
return false;
}
if ((size_t(-1) / tmpSize) >= size)
size *= tmpSize;
else {
size = -1;
}
return true;
}
}
ConfigLoader::ConfigLoader(const std::string &configFile) {
#ifdef _WIN32
if (_access(configFile.c_str(), 0) != 0)
#else
if (access(configFile.c_str(), 0) != 0)
#endif
{
std::cerr << "Config file " << configFile << " not found!" << std::endl;
exit(1);
}
#ifdef _WIN32
if (_access(configFile.c_str(), 04) != 0)
#else
if (access(configFile.c_str(), R_OK) != 0)
#endif
{
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(const Json::Value &data) :
configJsonRoot_(data) {
}
ConfigLoader::ConfigLoader(Json::Value &&data) :
configJsonRoot_(std::move(data)) {
}
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();
HttpAppFrameworkImpl::instance().setLogPath(logPath, baseName, logSize);
}
auto logLevel = log.get("log_level", "DEBUG").asString();
if (logLevel == "TRACE") {
trantor::Logger::setLogLevel(trantor::Logger::kTrace);
} else if (logLevel == "DEBUG") {
trantor::Logger::setLogLevel(trantor::Logger::kDebug);
} else if (logLevel == "INFO") {
trantor::Logger::setLogLevel(trantor::Logger::kInfo);
} else if (logLevel == "WARN") {
trantor::Logger::setLogLevel(trantor::Logger::kWarn);
}
}
static void loadControllers(const Json::Value &controllers) {
if (!controllers)
return;
for (auto const &controller : controllers) {
auto path = controller.get("path", "").asString();
auto ctrlName = controller.get("controller", "").asString();
if (path == "" || ctrlName == "")
continue;
std::vector<internal::HttpConstraint> constraints;
if (!controller["http_methods"].isNull()) {
for (auto const &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);
} else if (strMethod == "patch") {
constraints.push_back(Patch);
}
}
}
if (!controller["filters"].isNull()) {
for (auto const &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();
if (threadsNum == 1) {
threadsNum = app.get("number_of_threads", 1).asUInt64();
}
if (threadsNum == 0) {
// set the number to the number of processors.
threadsNum = std::thread::hardware_concurrency();
LOG_TRACE << "The number of processors is " << threadsNum;
}
if (threadsNum < 1)
threadsNum = 1;
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);
}
if (!app["static_file_headers"].empty()) {
if (app["static_file_headers"].isArray()) {
std::vector<std::pair<std::string, std::string> > headers;
for (auto &header : app["static_file_headers"]) {
headers.emplace_back(std::make_pair<std::string, std::string>(
header["name"].asString(), header["value"].asString()));
}
drogon::app().setStaticFileHeaders(headers);
} else {
std::cerr << "The static_file_headers option must be an array\n";
exit(1);
}
}
// 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 const &fileType : fileTypes) {
types.push_back(fileType.asString());
LOG_TRACE << "file type:" << types.back();
}
drogon::app().setFileTypes(types);
}
// locations
if (app.isMember("locations")) {
auto &locations = app["locations"];
if (!locations.isArray()) {
std::cerr << "The locations option must be an array\n";
exit(1);
}
for (auto &location : locations) {
auto uri = location.get("uri_prefix", "").asString();
if (uri.empty())
continue;
auto defaultContentType =
location.get("default_content_type", "").asString();
auto alias = location.get("alias", "").asString();
auto isCaseSensitive =
location.get("is_case_sensitive", false).asBool();
auto allAll = location.get("allow_all", true).asBool();
auto isRecursive = location.get("is_recursive", true).asBool();
if (!location["filters"].isNull()) {
if (location["filters"].isArray()) {
std::vector<std::string> filters;
for (auto const &filter : location["filters"]) {
filters.push_back(filter.asString());
}
drogon::app().addALocation(uri,
defaultContentType,
alias,
isCaseSensitive,
allAll,
isRecursive,
filters);
} else {
std::cerr << "the filters of location '" << uri
<< "' should be an array" << std::endl;
exit(1);
}
} else {
drogon::app().addALocation(uri,
defaultContentType,
alias,
isCaseSensitive,
allAll,
isRecursive);
}
}
}
// 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);
}
#ifndef _WIN32
// 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 const &viewsPath : viewsPaths) {
paths.push_back(viewsPath.asString());
LOG_TRACE << "views path:" << paths.back();
}
auto outputPath =
app.get("dynamic_views_output_path", "").asString();
drogon::app().enableDynamicViewsLoading(paths, outputPath);
}
}
#endif
auto unicodeEscaping =
app.get("enable_unicode_escaping_in_json", true).asBool();
drogon::app().setUnicodeEscapingInJson(unicodeEscaping);
auto &precision = app["float_precision_in_json"];
if (!precision.isNull()) {
auto precisionLength = precision.get("precision", 0).asUInt64();
auto precisionType =
precision.get("precision_type", "significant").asString();
drogon::app().setFloatPrecisionInJson(precisionLength, precisionType);
}
// log
loadLogSetting(app["log"]);
// run as daemon
auto runAsDaemon = app.get("run_as_daemon", false).asBool();
if (runAsDaemon) {
drogon::app().enableRunAsDaemon();
}
// handle SIGTERM
auto handleSigterm = app.get("handle_sig_term", true).asBool();
if (!handleSigterm) {
drogon::app().disableSigtermHandling();
}
// 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 useBr = app.get("use_brotli", false).asBool();
drogon::app().enableBrotli(useBr);
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);
auto server = app.get("server_header_field", "").asString();
if (!server.empty())
drogon::app().setServerHeaderField(server);
auto sendServerHeader = app.get("enable_server_header", true).asBool();
drogon::app().enableServerHeader(sendServerHeader);
auto sendDateHeader = app.get("enable_date_header", true).asBool();
drogon::app().enableDateHeader(sendDateHeader);
auto keepaliveReqs = app.get("keepalive_requests", 0).asUInt64();
drogon::app().setKeepaliveRequestsNumber(keepaliveReqs);
auto pipeliningReqs = app.get("pipelining_requests", 0).asUInt64();
drogon::app().setPipeliningRequestsNumber(pipeliningReqs);
auto useGzipStatic = app.get("gzip_static", true).asBool();
drogon::app().setGzipStatic(useGzipStatic);
auto useBrStatic = app.get("br_static", true).asBool();
drogon::app().setBrStatic(useBrStatic);
auto maxBodySize = app.get("client_max_body_size", "1M").asString();
size_t size;
if (bytesSize(maxBodySize, size)) {
drogon::app().setClientMaxBodySize(size);
} else {
std::cerr << "Error format of client_max_body_size" << std::endl;
exit(1);
}
auto maxMemoryBodySize =
app.get("client_max_memory_body_size", "64K").asString();
if (bytesSize(maxMemoryBodySize, size)) {
drogon::app().setClientMaxMemoryBodySize(size);
} else {
std::cerr << "Error format of client_max_memory_body_size" << std::endl;
exit(1);
}
auto maxWsMsgSize =
app.get("client_max_websocket_message_size", "128K").asString();
if (bytesSize(maxWsMsgSize, size)) {
drogon::app().setClientMaxWebSocketMessageSize(size);
} else {
std::cerr << "Error format of client_max_websocket_message_size"
<< std::endl;
exit(1);
}
drogon::app().enableReusePort(app.get("reuse_port", false).asBool());
drogon::app().setHomePage(app.get("home_page", "index.html").asString());
drogon::app().setImplicitPageEnable(
app.get("use_implicit_page", true).asBool());
drogon::app().setImplicitPage(
app.get("implicit_page", "index.html").asString());
}
static void loadListeners(const Json::Value &listeners) {
if (!listeners)
return;
LOG_TRACE << "Has " << listeners.size() << " listeners";
for (auto const &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();
auto useOldTLS = listener.get("use_old_tls", false).asBool();
std::vector<std::pair<std::string, std::string> > sslConfCmds;
if (listener.isMember("ssl_conf")) {
for (const auto &opt : listener["ssl_conf"]) {
if (opt.size() == 0 || opt.size() > 2) {
LOG_FATAL << "SSL configuration option should be an 1 or "
"2-element array";
abort();
}
sslConfCmds.emplace_back(opt[0].asString(),
opt.get(1, "").asString());
}
}
LOG_TRACE << "Add listener:" << addr << ":" << port;
drogon::app().addListener(
addr, port, useSSL, cert, key, useOldTLS, sslConfCmds);
}
}
static void loadSSL(const Json::Value &sslConf) {
if (!sslConf)
return;
auto key = sslConf.get("key", "").asString();
auto cert = sslConf.get("cert", "").asString();
drogon::app().setSSLFiles(cert, key);
std::vector<std::pair<std::string, std::string> > sslConfCmds;
if (sslConf.isMember("conf")) {
for (const auto &opt : sslConf["conf"]) {
if (opt.size() == 0 || opt.size() > 2) {
LOG_FATAL << "SSL configuration option should be an 1 or "
"2-element array";
abort();
}
sslConfCmds.emplace_back(opt[0].asString(),
opt.get(1, "").asString());
}
}
drogon::app().setSSLConfigCommands(sslConfCmds);
}
void ConfigLoader::load() {
// std::cout<<configJsonRoot_<<std::endl;
loadApp(configJsonRoot_["app"]);
loadSSL(configJsonRoot_["ssl"]);
loadListeners(configJsonRoot_["listeners"]);
//loadDbClients(configJsonRoot_["db_clients"]);
//loadRedisClients(configJsonRoot_["redis_clients"]);
}

View File

@ -1,37 +0,0 @@
/**
*
* ConfigLoader.h
* An Tao
*
* Copyright 2018, An Tao. All rights reserved.
* https://github.com/an-tao/drogon
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* Drogon
*
*/
#pragma once
#include <json/json.h>
#include <trantor/utils/NonCopyable.h>
#include <string>
namespace drogon {
class ConfigLoader : public trantor::NonCopyable {
public:
explicit ConfigLoader(const std::string &configFile);
explicit ConfigLoader(const Json::Value &data);
explicit ConfigLoader(Json::Value &&data);
~ConfigLoader();
const Json::Value &jsonValue() const {
return configJsonRoot_;
}
void load();
private:
std::string configFile_;
Json::Value configJsonRoot_;
};
} // namespace drogon

View File

@ -14,7 +14,6 @@
#include "HttpAppFrameworkImpl.h"
#include "AOPAdvice.h"
#include "ConfigLoader.h"
#include "HttpClientImpl.h"
#include "http/HttpRequestImpl.h"
#include "http/HttpResponseImpl.h"
@ -323,21 +322,15 @@ HttpAppFramework &HttpAppFrameworkImpl::setMaxConnectionNumPerIP(
}
HttpAppFramework &HttpAppFrameworkImpl::loadConfigFile(
const std::string &fileName) {
ConfigLoader loader(fileName);
loader.load();
jsonConfig_ = loader.jsonValue();
return *this;
}
HttpAppFramework &HttpAppFrameworkImpl::loadConfigJson(const Json::Value &data) {
ConfigLoader loader(data);
loader.load();
jsonConfig_ = loader.jsonValue();
return *this;
}
HttpAppFramework &HttpAppFrameworkImpl::loadConfigJson(Json::Value &&data) {
ConfigLoader loader(std::move(data));
loader.load();
jsonConfig_ = loader.jsonValue();
return *this;
}
HttpAppFramework &HttpAppFrameworkImpl::setLogPath(