1.Add gzip option in config file;
2.rename config example file's name
This commit is contained in:
parent
f6c50f2370
commit
93a07ed17a
|
@ -2,6 +2,7 @@
|
|||
*/
|
||||
{
|
||||
//ssl:the global ssl files setting
|
||||
/*
|
||||
"ssl": {
|
||||
"cert": "../../trantor/trantor/tests/server.pem",
|
||||
"key": "../../trantor/trantor/tests/server.pem"
|
||||
|
@ -24,7 +25,7 @@
|
|||
"cert": "",
|
||||
"key": ""
|
||||
}
|
||||
],
|
||||
],*/
|
||||
"app": {
|
||||
//threads_num:num of threads,1 by default
|
||||
"threads_num": 16,
|
||||
|
@ -32,17 +33,30 @@
|
|||
"enable_session": false,
|
||||
"session_timeout": 0,
|
||||
//document_root:Root path of HTTP document,defaut path is ./
|
||||
"document_root":"./",
|
||||
"document_root": "./",
|
||||
/* file_types:
|
||||
* HTTP download file types,The file types supported by drogon
|
||||
* by default are "html", "js", "css", "xml", "xsl", "txt", "svg",
|
||||
* "ttf", "otf", "woff2", "woff" , "eot", "png", "jpg", "jpeg",
|
||||
* "gif", "bmp", "ico", "icns", etc. */
|
||||
"file_types":["gif","png","jpg","js","css","html","ico","swf","xap","apk","cur","xml"],
|
||||
"file_types": [
|
||||
"gif",
|
||||
"png",
|
||||
"jpg",
|
||||
"js",
|
||||
"css",
|
||||
"html",
|
||||
"ico",
|
||||
"swf",
|
||||
"xap",
|
||||
"apk",
|
||||
"cur",
|
||||
"xml"
|
||||
],
|
||||
//max_connections:max connections number,100000 by default
|
||||
"max_connections":100000,
|
||||
"max_connections": 100000,
|
||||
//max_connections_per_ip:max connections number per clinet,0 by default which means no limit
|
||||
"max_connections_per_ip":0,
|
||||
"max_connections_per_ip": 0,
|
||||
//Load_dynamic_views: false by default, when set to true, drogon will
|
||||
//compile and load dynamically "CSP View Files" in directories defined
|
||||
//by "dynamic_views_path"
|
||||
|
@ -51,25 +65,27 @@
|
|||
//it will be relative path of document_root path
|
||||
//"dynamic_views_path":["./views"],
|
||||
//log:set log output,drogon output logs to stdout by default
|
||||
"log":{
|
||||
"log": {
|
||||
//log_path:log file path,empty by default,in which case,log will output to the stdout
|
||||
"log_path":"./",
|
||||
"log_path": "./",
|
||||
//logfile_base_name:log file base name,empty by default which means drogon will name logfile as
|
||||
//drogon.log ...
|
||||
"logfile_base_name":"",
|
||||
"logfile_base_name": "",
|
||||
//log_size_limit:100000000 bytes by default,
|
||||
//When the log file size reaches "log_size_limit", the log file will be switched.
|
||||
"log_size_limit":100000000,
|
||||
"log_size_limit": 100000000,
|
||||
//log_level:"DEBUG" by default,options:"TRACE","DEBUG","INFO","WARN"
|
||||
//The TRACE level is only valid when built in DEBUG mode.
|
||||
"log_level":"DEBUG"
|
||||
"log_level": "DEBUG"
|
||||
},
|
||||
//run_as_daemon:false by default
|
||||
"run_as_daemon":false,
|
||||
"run_as_daemon": false,
|
||||
//relaunch_on_error:false by default,if true,the program will be restart by parent after exit;
|
||||
"relaunch_on_error":false,
|
||||
"relaunch_on_error": false,
|
||||
//use_sendfile:true by default,if ture,the program will
|
||||
//use sendfile() system-call to send static file to client;
|
||||
"use_sendfile":true
|
||||
"use_sendfile": true,
|
||||
//use_gzip:true by default,use gzip to compress the response body's content;
|
||||
"use_gzip": true
|
||||
}
|
||||
}
|
|
@ -204,7 +204,7 @@ static void newConfigFile(std::ofstream &configFile)
|
|||
"*/\n"
|
||||
"{\n"
|
||||
" //ssl:the global ssl files setting\n"
|
||||
" \"ssl\": {\n"
|
||||
" /*\"ssl\": {\n"
|
||||
" \"cert\": \"../../trantor/trantor/tests/server.pem\",\n"
|
||||
" \"key\": \"../../trantor/trantor/tests/server.pem\"\n"
|
||||
" },\n"
|
||||
|
@ -226,7 +226,7 @@ static void newConfigFile(std::ofstream &configFile)
|
|||
" \"cert\": \"\",\n"
|
||||
" \"key\": \"\"\n"
|
||||
" }\n"
|
||||
" ],\n"
|
||||
" ],*/\n"
|
||||
" \"app\": {\n"
|
||||
" //threads_num:num of threads,1 by default\n"
|
||||
" \"threads_num\": 16,\n"
|
||||
|
@ -234,40 +234,45 @@ static void newConfigFile(std::ofstream &configFile)
|
|||
" \"enable_session\": false,\n"
|
||||
" \"session_timeout\": 0,\n"
|
||||
" //document_root:Root path of HTTP document,defaut path is ./\n"
|
||||
" \"document_root\":\"./\",\n"
|
||||
" \"document_root\": \"./\",\n"
|
||||
" /* file_types:\n"
|
||||
" * HTTP download file types,The file types supported by drogon\n"
|
||||
" * by default are \"html\", \"js\", \"css\", \"xml\", \"xsl\", \"txt\", \"svg\",\n"
|
||||
" * \"ttf\", \"otf\", \"woff2\", \"woff\" , \"eot\", \"png\", \"jpg\", \"jpeg\",\n"
|
||||
" * \"gif\", \"bmp\", \"ico\", \"icns\", etc. */\n"
|
||||
" \"file_types\":[\"gif\",\"png\",\"jpg\",\"js\",\"css\",\"html\",\"ico\",\"swf\",\"xap\",\"apk\",\"cur\",\"xml\"],\n"
|
||||
" \"file_types\": [\"gif\",\"png\",\"jpg\",\"js\",\"css\",\"html\",\"ico\",\"swf\",\"xap\",\"apk\",\"cur\",\"xml\"],\n"
|
||||
" //max_connections:max connections number,100000 by default\n"
|
||||
" \"max_connections\":100000,\n"
|
||||
" \"max_connections\": 100000,\n"
|
||||
" //Load_dynamic_views: false by default, when set to true, drogon will\n"
|
||||
" //compile and load dynamically \"CSP View Files\" in directories defined\n"
|
||||
" //by \"dynamic_views_path\"\n"
|
||||
" \"load_dynamic_views\":true,\n"
|
||||
" \"load_dynamic_views\": true,\n"
|
||||
" //dynamic_views_path: if the path isn't prefixed with / or ./,\n"
|
||||
" //it will be relative path of document_root path\n"
|
||||
" \"dynamic_views_path\":[\"./views\"],\n"
|
||||
" \"dynamic_views_path\": [\"./views\"],\n"
|
||||
" //log:set log output,drogon output logs to stdout by default\n"
|
||||
" \"log\":{\n"
|
||||
" \"log\": {\n"
|
||||
" //log_path:log file path,empty by default,in which case,log will output to the stdout\n"
|
||||
" \"log_path\":\"./\",\n"
|
||||
" //logfile_base_name:log file base name,empty by default which means drogon will name logfile as\n"
|
||||
" \"log_path\": \"./\",\n"
|
||||
" //logfile_base_name:log file base name,empty by default which means 'drogon' will name logfile as\n"
|
||||
" //drogon.log ...\n"
|
||||
" \"logfile_base_name\":\"\",\n"
|
||||
" \"logfile_base_name\": \"\",\n"
|
||||
" //log_size_limit:100000000 bytes by default,\n"
|
||||
" //When the log file size reaches \"log_size_limit\", the log file is switched.\n"
|
||||
" \"log_size_limit\":100000000\n"
|
||||
" \"log_size_limit\": 100000000,\n"
|
||||
" //log_level:\"DEBUG\" by default,options:\"TRACE\",\"DEBUG\",\"INFO\",\"WARN\"\n"
|
||||
" //The TRACE level is only valid when built in DEBUG mode.\n"
|
||||
" \"log_level\": \"DEBUG\"\n"
|
||||
" },\n"
|
||||
" //run_as_daemon:false by default\n"
|
||||
" \"run_as_daemon\":false,\n"
|
||||
" \"run_as_daemon\": false,\n"
|
||||
" //relaunch_on_error:false by default,if true,the program will be restart by parent after exit;\n"
|
||||
" \"relaunch_on_error\":false,\n"
|
||||
" \"relaunch_on_error\": false,\n"
|
||||
" //use_sendfile:true by default,if ture,the program will\n"
|
||||
" //use sendfile() system-call to send static file to client;\n"
|
||||
" \"use_sendfile\":true\n"
|
||||
" \"use_sendfile\": true,\n"
|
||||
" //use_gzip:true by default,use gzip to compress the response body's content;\n"
|
||||
" \"use_gzip\": true\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
}
|
||||
|
|
|
@ -140,6 +140,6 @@ int main()
|
|||
drogon::HttpAppFramework::instance().enableSession(60);
|
||||
//start app framework
|
||||
//drogon::HttpAppFramework::instance().enableDynamicViewsLoading({"/tmp/views"});
|
||||
// drogon::HttpAppFramework::instance().loadConfigFile("../../config.json.example");
|
||||
drogon::HttpAppFramework::instance().loadConfigFile("../../config.json.example");
|
||||
drogon::HttpAppFramework::instance().run();
|
||||
}
|
||||
|
|
|
@ -39,80 +39,80 @@
|
|||
#include <vector>
|
||||
namespace drogon
|
||||
{
|
||||
//the drogon banner
|
||||
const char banner[]= " _ \n"
|
||||
" __| |_ __ ___ __ _ ___ _ __ \n"
|
||||
" / _` | '__/ _ \\ / _` |/ _ \\| '_ \\ \n"
|
||||
"| (_| | | | (_) | (_| | (_) | | | |\n"
|
||||
" \\__,_|_| \\___/ \\__, |\\___/|_| |_|\n"
|
||||
" |___/ \n";
|
||||
inline std::string getVersion()
|
||||
{
|
||||
return VERSION;
|
||||
}
|
||||
inline std::string getGitCommit()
|
||||
{
|
||||
return VERSION_MD5;
|
||||
}
|
||||
class HttpAppFramework:public trantor::NonCopyable
|
||||
{
|
||||
public:
|
||||
static HttpAppFramework &instance();
|
||||
virtual void setThreadNum(size_t threadNum)=0;
|
||||
virtual void setSSLFiles(const std::string &certPath,
|
||||
const std::string &keyPath)=0;
|
||||
virtual void addListener(const std::string &ip,
|
||||
uint16_t port,
|
||||
bool useSSL=false,
|
||||
const std::string & certFile="",
|
||||
const std::string & keyFile="")=0;
|
||||
virtual void run()=0;
|
||||
virtual ~HttpAppFramework();
|
||||
virtual void registerWebSocketController(const std::string &pathName,
|
||||
const std::string &crtlName,
|
||||
const std::vector<std::string> &filters=
|
||||
std::vector<std::string>())=0;
|
||||
virtual void registerHttpSimpleController(const std::string &pathName,
|
||||
const std::string &crtlName,
|
||||
const std::vector<std::string> &filters=std::vector<std::string>())=0;
|
||||
template <typename FUNCTION>
|
||||
static void registerHttpApiMethod(const std::string &pathPattern,
|
||||
FUNCTION && function,
|
||||
const std::vector<std::string> &filters=std::vector<std::string>())
|
||||
{
|
||||
LOG_TRACE<<"pathPattern:"<<pathPattern;
|
||||
HttpApiBinderBasePtr binder;
|
||||
|
||||
binder=std::make_shared<
|
||||
HttpApiBinder<FUNCTION>
|
||||
>(std::forward<FUNCTION>(function));
|
||||
|
||||
instance().registerHttpApiController(pathPattern,binder,filters);
|
||||
}
|
||||
virtual void enableSession(const size_t timeout=0)=0;
|
||||
virtual void disableSession()=0;
|
||||
virtual const std::string & getDocumentRoot() const =0;
|
||||
virtual void setDocumentRoot(const std::string &rootPath)=0;
|
||||
virtual void setFileTypes(const std::vector<std::string> &types)=0;
|
||||
virtual void enableDynamicViewsLoading(const std::vector<std::string> &libPaths)=0;
|
||||
|
||||
virtual void setMaxConnectionNum(size_t maxConnections)=0;
|
||||
virtual void setMaxConnectionNumPerIP(size_t maxConnectionsPerIP)=0;
|
||||
|
||||
virtual void loadConfigFile(const std::string &fileName)=0;
|
||||
|
||||
virtual void enableRunAsDaemon()=0;
|
||||
virtual void enableRelaunchOnError()=0;
|
||||
|
||||
virtual void setLogPath(const std::string &logPath,
|
||||
const std::string &logfileBaseName="",
|
||||
size_t logSize=100000000)=0;
|
||||
virtual void enableSendfile(bool sendFile)=0;
|
||||
|
||||
private:
|
||||
virtual void registerHttpApiController(const std::string &pathPattern,
|
||||
const HttpApiBinderBasePtr &binder,
|
||||
const std::vector<std::string> &filters=std::vector<std::string>())=0;
|
||||
|
||||
};
|
||||
//the drogon banner
|
||||
const char banner[] = " _ \n"
|
||||
" __| |_ __ ___ __ _ ___ _ __ \n"
|
||||
" / _` | '__/ _ \\ / _` |/ _ \\| '_ \\ \n"
|
||||
"| (_| | | | (_) | (_| | (_) | | | |\n"
|
||||
" \\__,_|_| \\___/ \\__, |\\___/|_| |_|\n"
|
||||
" |___/ \n";
|
||||
inline std::string getVersion()
|
||||
{
|
||||
return VERSION;
|
||||
}
|
||||
inline std::string getGitCommit()
|
||||
{
|
||||
return VERSION_MD5;
|
||||
}
|
||||
class HttpAppFramework : public trantor::NonCopyable
|
||||
{
|
||||
public:
|
||||
static HttpAppFramework &instance();
|
||||
virtual void setThreadNum(size_t threadNum) = 0;
|
||||
virtual void setSSLFiles(const std::string &certPath,
|
||||
const std::string &keyPath) = 0;
|
||||
virtual void addListener(const std::string &ip,
|
||||
uint16_t port,
|
||||
bool useSSL = false,
|
||||
const std::string &certFile = "",
|
||||
const std::string &keyFile = "") = 0;
|
||||
virtual void run() = 0;
|
||||
virtual ~HttpAppFramework();
|
||||
virtual void registerWebSocketController(const std::string &pathName,
|
||||
const std::string &crtlName,
|
||||
const std::vector<std::string> &filters =
|
||||
std::vector<std::string>()) = 0;
|
||||
virtual void registerHttpSimpleController(const std::string &pathName,
|
||||
const std::string &crtlName,
|
||||
const std::vector<std::string> &filters = std::vector<std::string>()) = 0;
|
||||
template <typename FUNCTION>
|
||||
static void registerHttpApiMethod(const std::string &pathPattern,
|
||||
FUNCTION &&function,
|
||||
const std::vector<std::string> &filters = std::vector<std::string>())
|
||||
{
|
||||
LOG_TRACE << "pathPattern:" << pathPattern;
|
||||
HttpApiBinderBasePtr binder;
|
||||
|
||||
binder = std::make_shared<
|
||||
HttpApiBinder<FUNCTION>>(std::forward<FUNCTION>(function));
|
||||
|
||||
instance().registerHttpApiController(pathPattern, binder, filters);
|
||||
}
|
||||
virtual void enableSession(const size_t timeout = 0) = 0;
|
||||
virtual void disableSession() = 0;
|
||||
virtual const std::string &getDocumentRoot() const = 0;
|
||||
virtual void setDocumentRoot(const std::string &rootPath) = 0;
|
||||
virtual void setFileTypes(const std::vector<std::string> &types) = 0;
|
||||
virtual void enableDynamicViewsLoading(const std::vector<std::string> &libPaths) = 0;
|
||||
|
||||
virtual void setMaxConnectionNum(size_t maxConnections) = 0;
|
||||
virtual void setMaxConnectionNumPerIP(size_t maxConnectionsPerIP) = 0;
|
||||
|
||||
virtual void loadConfigFile(const std::string &fileName) = 0;
|
||||
|
||||
virtual void enableRunAsDaemon() = 0;
|
||||
virtual void enableRelaunchOnError() = 0;
|
||||
|
||||
virtual void setLogPath(const std::string &logPath,
|
||||
const std::string &logfileBaseName = "",
|
||||
size_t logSize = 100000000) = 0;
|
||||
virtual void enableSendfile(bool sendFile) = 0;
|
||||
virtual void enableGzip(bool useGzip) = 0;
|
||||
virtual bool useGzip() const = 0;
|
||||
|
||||
private:
|
||||
virtual void registerHttpApiController(const std::string &pathPattern,
|
||||
const HttpApiBinderBasePtr &binder,
|
||||
const std::vector<std::string> &filters = std::vector<std::string>()) = 0;
|
||||
};
|
||||
} // namespace drogon
|
||||
|
|
|
@ -21,123 +21,123 @@
|
|||
#include <unistd.h>
|
||||
using namespace drogon;
|
||||
|
||||
ConfigLoader::ConfigLoader(const std::string &configFile) {
|
||||
if(access(configFile.c_str(),0)!=0)
|
||||
ConfigLoader::ConfigLoader(const std::string &configFile)
|
||||
{
|
||||
if (access(configFile.c_str(), 0) != 0)
|
||||
{
|
||||
std::cerr<<"Config file "<<configFile<<" not found!"<<std::endl;
|
||||
std::cerr << "Config file " << configFile << " not found!" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
if(access(configFile.c_str(),R_OK)!=0)
|
||||
if (access(configFile.c_str(), R_OK) != 0)
|
||||
{
|
||||
std::cerr<<"No permission to read config file "<<configFile<<std::endl;
|
||||
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)
|
||||
_configFile = configFile;
|
||||
std::ifstream infile(configFile.c_str(), std::ifstream::in);
|
||||
if (infile)
|
||||
{
|
||||
try {
|
||||
infile>>_configJsonRoot;
|
||||
try
|
||||
{
|
||||
infile >> _configJsonRoot;
|
||||
}
|
||||
catch (const std::exception &exception)
|
||||
{
|
||||
std::cerr<<"Configuration file format error! in "<<configFile<<":"<<std::endl;
|
||||
std::cerr<<exception.what()<<std::endl;
|
||||
std::cerr << "Configuration file format error! in " << configFile << ":" << std::endl;
|
||||
std::cerr << exception.what() << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
ConfigLoader::~ConfigLoader() {
|
||||
|
||||
ConfigLoader::~ConfigLoader()
|
||||
{
|
||||
}
|
||||
static void loadLogSetting(const Json::Value &log)
|
||||
{
|
||||
if(!log)
|
||||
if (!log)
|
||||
return;
|
||||
auto logPath=log.get("log_path","").asString();
|
||||
if(logPath!="")
|
||||
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();
|
||||
HttpAppFramework::instance().setLogPath(logPath,baseName,logSize);
|
||||
auto baseName = log.get("logfile_base_name", "").asString();
|
||||
auto logSize = log.get("log_size_limit", 100000000).asUInt64();
|
||||
HttpAppFramework::instance().setLogPath(logPath, baseName, logSize);
|
||||
}
|
||||
auto logLevel=log.get("log_level","DEBUG").asString();
|
||||
if(logLevel=="TRACE")
|
||||
auto logLevel = log.get("log_level", "DEBUG").asString();
|
||||
if (logLevel == "TRACE")
|
||||
{
|
||||
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
|
||||
}
|
||||
else if(logLevel=="DEBUG")
|
||||
else if (logLevel == "DEBUG")
|
||||
{
|
||||
trantor::Logger::setLogLevel(trantor::Logger::DEBUG);
|
||||
}
|
||||
else if(logLevel=="INFO")
|
||||
else if (logLevel == "INFO")
|
||||
{
|
||||
trantor::Logger::setLogLevel(trantor::Logger::INFO);
|
||||
}
|
||||
else if(logLevel=="WARN")
|
||||
else if (logLevel == "WARN")
|
||||
{
|
||||
trantor::Logger::setLogLevel(trantor::Logger::WARN);
|
||||
}
|
||||
}
|
||||
static void loadApp(const Json::Value &app)
|
||||
{
|
||||
if(!app)
|
||||
if (!app)
|
||||
return;
|
||||
//threads number
|
||||
auto threadsNum=app.get("threads_num",1).asUInt64();
|
||||
auto threadsNum = app.get("threads_num", 1).asUInt64();
|
||||
HttpAppFramework::instance().setThreadNum(threadsNum);
|
||||
//session
|
||||
auto enableSession=app.get("enable_session",false).asBool();
|
||||
auto timeout=app.get("session_timeout",0).asUInt64();
|
||||
if(enableSession)
|
||||
auto enableSession = app.get("enable_session", false).asBool();
|
||||
auto timeout = app.get("session_timeout", 0).asUInt64();
|
||||
if (enableSession)
|
||||
HttpAppFramework::instance().enableSession(timeout);
|
||||
else
|
||||
HttpAppFramework::instance().disableSession();
|
||||
//document root
|
||||
auto documentRoot=app.get("document_root","").asString();
|
||||
if(documentRoot!="")
|
||||
auto documentRoot = app.get("document_root", "").asString();
|
||||
if (documentRoot != "")
|
||||
{
|
||||
HttpAppFramework::instance().setDocumentRoot(documentRoot);
|
||||
}
|
||||
//file types
|
||||
auto fileTypes=app["file_types"];
|
||||
if(fileTypes.isArray()&&!fileTypes.empty())
|
||||
auto fileTypes = app["file_types"];
|
||||
if (fileTypes.isArray() && !fileTypes.empty())
|
||||
{
|
||||
std::vector<std::string> types;
|
||||
for(auto fileType:fileTypes)
|
||||
for (auto fileType : fileTypes)
|
||||
{
|
||||
types.push_back(fileType.asString());
|
||||
LOG_TRACE<<"file type:"<<types.back();
|
||||
LOG_TRACE << "file type:" << types.back();
|
||||
}
|
||||
HttpAppFramework::instance().setFileTypes(types);
|
||||
}
|
||||
//max connections
|
||||
auto maxConns=app.get("max_connections",0).asUInt64();
|
||||
if(maxConns>0)
|
||||
auto maxConns = app.get("max_connections", 0).asUInt64();
|
||||
if (maxConns > 0)
|
||||
{
|
||||
HttpAppFramework::instance().setMaxConnectionNum(maxConns);
|
||||
}
|
||||
//max connections per IP
|
||||
auto maxConnsPerIP=app.get("max_connections_per_ip",0).asUInt64();
|
||||
if(maxConnsPerIP>0)
|
||||
auto maxConnsPerIP = app.get("max_connections_per_ip", 0).asUInt64();
|
||||
if (maxConnsPerIP > 0)
|
||||
{
|
||||
HttpAppFramework::instance().setMaxConnectionNumPerIP(maxConnsPerIP);
|
||||
}
|
||||
|
||||
//dynamic views
|
||||
auto enableDynamicViews=app.get("load_dynamic_views",false).asBool();
|
||||
if(enableDynamicViews)
|
||||
auto enableDynamicViews = app.get("load_dynamic_views", false).asBool();
|
||||
if (enableDynamicViews)
|
||||
{
|
||||
auto viewsPaths=app["dynamic_views_path"];
|
||||
if(viewsPaths.isArray()&&viewsPaths.size()>0)
|
||||
auto viewsPaths = app["dynamic_views_path"];
|
||||
if (viewsPaths.isArray() && viewsPaths.size() > 0)
|
||||
{
|
||||
std::vector<std::string> paths;
|
||||
for(auto viewsPath:viewsPaths)
|
||||
for (auto viewsPath : viewsPaths)
|
||||
{
|
||||
paths.push_back(viewsPath.asString());
|
||||
LOG_TRACE<<"views path:"<<paths.back();
|
||||
LOG_TRACE << "views path:" << paths.back();
|
||||
}
|
||||
HttpAppFramework::instance().enableDynamicViewsLoading(paths);
|
||||
}
|
||||
|
@ -145,45 +145,48 @@ static void loadApp(const Json::Value &app)
|
|||
//log
|
||||
loadLogSetting(app["log"]);
|
||||
//run as daemon
|
||||
auto runAsDaemon=app.get("run_as_daemon",false).asBool();
|
||||
if(runAsDaemon)
|
||||
auto runAsDaemon = app.get("run_as_daemon", false).asBool();
|
||||
if (runAsDaemon)
|
||||
{
|
||||
HttpAppFramework::instance().enableRunAsDaemon();
|
||||
}
|
||||
//relaunch
|
||||
auto relaunch=app.get("relaunch_on_error",false).asBool();
|
||||
if(relaunch)
|
||||
auto relaunch = app.get("relaunch_on_error", false).asBool();
|
||||
if (relaunch)
|
||||
{
|
||||
HttpAppFramework::instance().enableRelaunchOnError();
|
||||
}
|
||||
auto useSendfile=app.get("use_sendfile",true).asBool();
|
||||
auto useSendfile = app.get("use_sendfile", true).asBool();
|
||||
HttpAppFramework::instance().enableSendfile(useSendfile);
|
||||
auto useGzip = app.get("use_gzip", true).asBool();
|
||||
HttpAppFramework::instance().enableGzip(useGzip);
|
||||
}
|
||||
static void loadListeners(const Json::Value &listeners)
|
||||
{
|
||||
if(!listeners)
|
||||
if (!listeners)
|
||||
return;
|
||||
LOG_TRACE<<"Has "<<listeners.size()<<" listeners";
|
||||
for(auto listener:listeners)
|
||||
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;
|
||||
HttpAppFramework::instance().addListener(addr,port,useSSL,cert,key);
|
||||
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;
|
||||
HttpAppFramework::instance().addListener(addr, port, useSSL, cert, key);
|
||||
}
|
||||
}
|
||||
static void loadSSL(const Json::Value &sslFiles)
|
||||
{
|
||||
if(!sslFiles)
|
||||
if (!sslFiles)
|
||||
return;
|
||||
auto key=sslFiles.get("key","").asString();
|
||||
auto cert=sslFiles.get("cert","").asString();
|
||||
HttpAppFramework::instance().setSSLFiles(cert,key);
|
||||
auto key = sslFiles.get("key", "").asString();
|
||||
auto cert = sslFiles.get("cert", "").asString();
|
||||
HttpAppFramework::instance().setSSLFiles(cert, key);
|
||||
}
|
||||
void ConfigLoader::load() {
|
||||
void ConfigLoader::load()
|
||||
{
|
||||
//std::cout<<_configJsonRoot<<std::endl;
|
||||
loadApp(_configJsonRoot["app"]);
|
||||
loadSSL(_configJsonRoot["ssl"]);
|
||||
|
|
|
@ -29,160 +29,166 @@
|
|||
|
||||
namespace drogon
|
||||
{
|
||||
class HttpAppFrameworkImpl:public HttpAppFramework
|
||||
class HttpAppFrameworkImpl : public HttpAppFramework
|
||||
{
|
||||
public:
|
||||
HttpAppFrameworkImpl() : _connectionNum(0)
|
||||
{
|
||||
public:
|
||||
HttpAppFrameworkImpl():
|
||||
_connectionNum(0)
|
||||
{
|
||||
}
|
||||
virtual void addListener(const std::string &ip,
|
||||
uint16_t port,
|
||||
bool useSSL=false,
|
||||
const std::string & certFile="",
|
||||
const std::string & keyFile="") override;
|
||||
virtual void setThreadNum(size_t threadNum) override;
|
||||
virtual void setSSLFiles(const std::string &certPath,
|
||||
const std::string &keyPath) override;
|
||||
virtual void run() override ;
|
||||
virtual void registerWebSocketController(const std::string &pathName,
|
||||
const std::string &crtlName,
|
||||
const std::vector<std::string> &filters=
|
||||
std::vector<std::string>())override ;
|
||||
virtual void registerHttpSimpleController(const std::string &pathName,
|
||||
const std::string &crtlName,
|
||||
const std::vector<std::string> &filters=
|
||||
std::vector<std::string>())override ;
|
||||
virtual void enableSession(const size_t timeout=0) override { _useSession=true;_sessionTimeout=timeout;}
|
||||
virtual void disableSession() override { _useSession=false;}
|
||||
virtual const std::string & getDocumentRoot() const override {return _rootPath;}
|
||||
virtual void setDocumentRoot(const std::string &rootPath) override {_rootPath=rootPath;}
|
||||
virtual void setFileTypes(const std::vector<std::string> &types) override;
|
||||
virtual void enableDynamicViewsLoading(const std::vector<std::string> &libPaths) override;
|
||||
virtual void setMaxConnectionNum(size_t maxConnections) override;
|
||||
virtual void setMaxConnectionNumPerIP(size_t maxConnectionsPerIP) override;
|
||||
virtual void loadConfigFile(const std::string &fileName) override;
|
||||
virtual void enableRunAsDaemon() override {_runAsDaemon=true;}
|
||||
virtual void enableRelaunchOnError() override {_relaunchOnError=true;}
|
||||
virtual void setLogPath(const std::string &logPath,
|
||||
const std::string &logfileBaseName="",
|
||||
size_t logfileSize=100000000) override;
|
||||
virtual void enableSendfile(bool sendFile) override {_useSendfile=sendFile;}
|
||||
~HttpAppFrameworkImpl(){
|
||||
//Destroy the following objects before _loop destruction
|
||||
_sharedLibManagerPtr.reset();
|
||||
_sessionMapPtr.reset();
|
||||
}
|
||||
}
|
||||
virtual void addListener(const std::string &ip,
|
||||
uint16_t port,
|
||||
bool useSSL = false,
|
||||
const std::string &certFile = "",
|
||||
const std::string &keyFile = "") override;
|
||||
virtual void setThreadNum(size_t threadNum) override;
|
||||
virtual void setSSLFiles(const std::string &certPath,
|
||||
const std::string &keyPath) override;
|
||||
virtual void run() override;
|
||||
virtual void registerWebSocketController(const std::string &pathName,
|
||||
const std::string &crtlName,
|
||||
const std::vector<std::string> &filters =
|
||||
std::vector<std::string>()) override;
|
||||
virtual void registerHttpSimpleController(const std::string &pathName,
|
||||
const std::string &crtlName,
|
||||
const std::vector<std::string> &filters =
|
||||
std::vector<std::string>()) override;
|
||||
virtual void enableSession(const size_t timeout = 0) override
|
||||
{
|
||||
_useSession = true;
|
||||
_sessionTimeout = timeout;
|
||||
}
|
||||
virtual void disableSession() override { _useSession = false; }
|
||||
virtual const std::string &getDocumentRoot() const override { return _rootPath; }
|
||||
virtual void setDocumentRoot(const std::string &rootPath) override { _rootPath = rootPath; }
|
||||
virtual void setFileTypes(const std::vector<std::string> &types) override;
|
||||
virtual void enableDynamicViewsLoading(const std::vector<std::string> &libPaths) override;
|
||||
virtual void setMaxConnectionNum(size_t maxConnections) override;
|
||||
virtual void setMaxConnectionNumPerIP(size_t maxConnectionsPerIP) override;
|
||||
virtual void loadConfigFile(const std::string &fileName) override;
|
||||
virtual void enableRunAsDaemon() override { _runAsDaemon = true; }
|
||||
virtual void enableRelaunchOnError() override { _relaunchOnError = true; }
|
||||
virtual void setLogPath(const std::string &logPath,
|
||||
const std::string &logfileBaseName = "",
|
||||
size_t logfileSize = 100000000) override;
|
||||
virtual void enableSendfile(bool sendFile) override { _useSendfile = sendFile; }
|
||||
virtual void enableGzip(bool useGzip) override { _useGzip = useGzip; }
|
||||
virtual bool useGzip() const override { return _useGzip; }
|
||||
~HttpAppFrameworkImpl()
|
||||
{
|
||||
//Destroy the following objects before _loop destruction
|
||||
_sharedLibManagerPtr.reset();
|
||||
_sessionMapPtr.reset();
|
||||
}
|
||||
|
||||
trantor::EventLoop *loop();
|
||||
private:
|
||||
virtual void registerHttpApiController(const std::string &pathPattern,
|
||||
const HttpApiBinderBasePtr &binder,
|
||||
const std::vector<std::string> &filters=std::vector<std::string>()) override ;
|
||||
trantor::EventLoop *loop();
|
||||
|
||||
std::vector<std::tuple<std::string,uint16_t,bool,std::string,std::string>> _listeners;
|
||||
void onAsyncRequest(const HttpRequestPtr& req,const std::function<void (const HttpResponsePtr &)> & callback);
|
||||
void onNewWebsockRequest(const HttpRequestPtr& req,
|
||||
const std::function<void (const HttpResponsePtr &)> & callback,
|
||||
const WebSocketConnectionPtr &wsConnPtr);
|
||||
void onWebsockMessage(const WebSocketConnectionPtr &wsConnPtr,trantor::MsgBuffer *buffer);
|
||||
void onWebsockDisconnect(const WebSocketConnectionPtr &wsConnPtr);
|
||||
void onConnection(const TcpConnectionPtr &conn);
|
||||
void readSendFile(const std::string& filePath,const HttpRequestPtr& req,const HttpResponsePtr resp);
|
||||
void addApiPath(const std::string &path,
|
||||
const HttpApiBinderBasePtr &binder,
|
||||
const std::vector<std::string> &filters);
|
||||
void initRegex();
|
||||
//if uuid package found,we can use a uuid string as session id;
|
||||
//set _sessionTimeout=0 to make location session valid forever based on cookies;
|
||||
size_t _sessionTimeout= 0;
|
||||
bool _useSession= false;
|
||||
typedef std::shared_ptr<Session> SessionPtr;
|
||||
std::unique_ptr<CacheMap<std::string,SessionPtr>> _sessionMapPtr;
|
||||
private:
|
||||
virtual void registerHttpApiController(const std::string &pathPattern,
|
||||
const HttpApiBinderBasePtr &binder,
|
||||
const std::vector<std::string> &filters = std::vector<std::string>()) override;
|
||||
|
||||
std::unique_ptr<CacheMap<std::string,HttpResponsePtr>> _responseCacheMap;
|
||||
std::vector<std::tuple<std::string, uint16_t, bool, std::string, std::string>> _listeners;
|
||||
void onAsyncRequest(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback);
|
||||
void onNewWebsockRequest(const HttpRequestPtr &req,
|
||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
||||
const WebSocketConnectionPtr &wsConnPtr);
|
||||
void onWebsockMessage(const WebSocketConnectionPtr &wsConnPtr, trantor::MsgBuffer *buffer);
|
||||
void onWebsockDisconnect(const WebSocketConnectionPtr &wsConnPtr);
|
||||
void onConnection(const TcpConnectionPtr &conn);
|
||||
void readSendFile(const std::string &filePath, const HttpRequestPtr &req, const HttpResponsePtr resp);
|
||||
void addApiPath(const std::string &path,
|
||||
const HttpApiBinderBasePtr &binder,
|
||||
const std::vector<std::string> &filters);
|
||||
void initRegex();
|
||||
//if uuid package found,we can use a uuid string as session id;
|
||||
//set _sessionTimeout=0 to make location session valid forever based on cookies;
|
||||
size_t _sessionTimeout = 0;
|
||||
bool _useSession = false;
|
||||
typedef std::shared_ptr<Session> SessionPtr;
|
||||
std::unique_ptr<CacheMap<std::string, SessionPtr>> _sessionMapPtr;
|
||||
|
||||
void doFilters(const std::vector<std::string> &filters,
|
||||
const HttpRequestPtr& req,
|
||||
const std::function<void (const HttpResponsePtr &)> & callback,
|
||||
std::unique_ptr<CacheMap<std::string, HttpResponsePtr>> _responseCacheMap;
|
||||
|
||||
void doFilters(const std::vector<std::string> &filters,
|
||||
const HttpRequestPtr &req,
|
||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
||||
bool needSetJsessionid,
|
||||
const std::string &session_id,
|
||||
const std::function<void()> &missCallback);
|
||||
void doFilterChain(const std::shared_ptr<std::queue<std::shared_ptr<HttpFilterBase>>> &chain,
|
||||
const HttpRequestPtr &req,
|
||||
const std::function<void(const HttpResponsePtr &)> &callback,
|
||||
bool needSetJsessionid,
|
||||
const std::string &session_id,
|
||||
const std::function<void ()> &missCallback);
|
||||
void doFilterChain(const std::shared_ptr<std::queue<std::shared_ptr<HttpFilterBase>>> &chain,
|
||||
const HttpRequestPtr& req,
|
||||
const std::function<void (const HttpResponsePtr &)> & callback,
|
||||
bool needSetJsessionid,
|
||||
const std::string &session_id,
|
||||
const std::function<void ()> &missCallback);
|
||||
//
|
||||
struct ControllerAndFiltersName
|
||||
{
|
||||
std::string controllerName;
|
||||
std::vector<std::string> filtersName;
|
||||
std::shared_ptr<HttpSimpleControllerBase> controller;
|
||||
std::weak_ptr<HttpResponse> responsePtr;
|
||||
std::mutex _mutex;
|
||||
};
|
||||
std::unordered_map<std::string,ControllerAndFiltersName>_simpCtrlMap;
|
||||
std::mutex _simpCtrlMutex;
|
||||
struct WSCtrlAndFiltersName
|
||||
{
|
||||
WebSocketControllerBasePtr controller;
|
||||
std::vector<std::string> filtersName;
|
||||
};
|
||||
std::unordered_map<std::string,WSCtrlAndFiltersName> _websockCtrlMap;
|
||||
std::mutex _websockCtrlMutex;
|
||||
|
||||
struct ApiBinder
|
||||
{
|
||||
std::string pathParameterPattern;
|
||||
std::vector<size_t> parameterPlaces;
|
||||
std::map<std::string,size_t> queryParametersPlaces;
|
||||
HttpApiBinderBasePtr binderPtr;
|
||||
std::vector<std::string> filtersName;
|
||||
std::unique_ptr <std::mutex> binderMtx=std::unique_ptr<std::mutex>(new std::mutex);
|
||||
std::weak_ptr<HttpResponse> responsePtr;
|
||||
};
|
||||
//std::unordered_map<std::string,ApiBinder>_apiCtrlMap;
|
||||
std::vector<ApiBinder>_apiCtrlVector;
|
||||
std::mutex _apiCtrlMutex;
|
||||
|
||||
std::regex _apiRegex;
|
||||
bool _enableLastModify=true;
|
||||
std::set<std::string> _fileTypeSet={"html","js","css","xml","xsl","txt","svg","ttf",
|
||||
"otf","woff2","woff","eot","png","jpg","jpeg",
|
||||
"gif","bmp","ico","icns"};
|
||||
std::string _rootPath="./";
|
||||
|
||||
std::atomic_bool _running;
|
||||
|
||||
//tool funcs
|
||||
|
||||
|
||||
size_t _threadNum=1;
|
||||
std::vector<std::string> _libFilePaths;
|
||||
|
||||
std::unique_ptr<SharedLibManager>_sharedLibManagerPtr;
|
||||
|
||||
trantor::EventLoop _loop;
|
||||
|
||||
std::string _sslCertPath;
|
||||
std::string _sslKeyPath;
|
||||
|
||||
size_t _maxConnectionNum=100000;
|
||||
size_t _maxConnectionNumPerIP=0;
|
||||
|
||||
std::atomic<uint64_t> _connectionNum;
|
||||
std::unordered_map<std::string,size_t> _connectionsNumMap;
|
||||
|
||||
std::mutex _connectionsNumMapMutex;
|
||||
|
||||
|
||||
bool _runAsDaemon=false;
|
||||
bool _relaunchOnError=false;
|
||||
std::string _logPath="";
|
||||
std::string _logfileBaseName="";
|
||||
size_t _logfileSize=100000000;
|
||||
bool _useSendfile=true;
|
||||
const std::function<void()> &missCallback);
|
||||
//
|
||||
struct ControllerAndFiltersName
|
||||
{
|
||||
std::string controllerName;
|
||||
std::vector<std::string> filtersName;
|
||||
std::shared_ptr<HttpSimpleControllerBase> controller;
|
||||
std::weak_ptr<HttpResponse> responsePtr;
|
||||
std::mutex _mutex;
|
||||
};
|
||||
}
|
||||
std::unordered_map<std::string, ControllerAndFiltersName> _simpCtrlMap;
|
||||
std::mutex _simpCtrlMutex;
|
||||
struct WSCtrlAndFiltersName
|
||||
{
|
||||
WebSocketControllerBasePtr controller;
|
||||
std::vector<std::string> filtersName;
|
||||
};
|
||||
std::unordered_map<std::string, WSCtrlAndFiltersName> _websockCtrlMap;
|
||||
std::mutex _websockCtrlMutex;
|
||||
|
||||
struct ApiBinder
|
||||
{
|
||||
std::string pathParameterPattern;
|
||||
std::vector<size_t> parameterPlaces;
|
||||
std::map<std::string, size_t> queryParametersPlaces;
|
||||
HttpApiBinderBasePtr binderPtr;
|
||||
std::vector<std::string> filtersName;
|
||||
std::unique_ptr<std::mutex> binderMtx = std::unique_ptr<std::mutex>(new std::mutex);
|
||||
std::weak_ptr<HttpResponse> responsePtr;
|
||||
};
|
||||
//std::unordered_map<std::string,ApiBinder>_apiCtrlMap;
|
||||
std::vector<ApiBinder> _apiCtrlVector;
|
||||
std::mutex _apiCtrlMutex;
|
||||
|
||||
std::regex _apiRegex;
|
||||
bool _enableLastModify = true;
|
||||
std::set<std::string> _fileTypeSet = {"html", "js", "css", "xml", "xsl", "txt", "svg", "ttf",
|
||||
"otf", "woff2", "woff", "eot", "png", "jpg", "jpeg",
|
||||
"gif", "bmp", "ico", "icns"};
|
||||
std::string _rootPath = "./";
|
||||
|
||||
std::atomic_bool _running;
|
||||
|
||||
//tool funcs
|
||||
|
||||
size_t _threadNum = 1;
|
||||
std::vector<std::string> _libFilePaths;
|
||||
|
||||
std::unique_ptr<SharedLibManager> _sharedLibManagerPtr;
|
||||
|
||||
trantor::EventLoop _loop;
|
||||
|
||||
std::string _sslCertPath;
|
||||
std::string _sslKeyPath;
|
||||
|
||||
size_t _maxConnectionNum = 100000;
|
||||
size_t _maxConnectionNumPerIP = 0;
|
||||
|
||||
std::atomic<uint64_t> _connectionNum;
|
||||
std::unordered_map<std::string, size_t> _connectionsNumMap;
|
||||
|
||||
std::mutex _connectionsNumMapMutex;
|
||||
|
||||
bool _runAsDaemon = false;
|
||||
bool _relaunchOnError = false;
|
||||
std::string _logPath = "";
|
||||
std::string _logfileBaseName = "";
|
||||
size_t _logfileSize = 100000000;
|
||||
bool _useSendfile = true;
|
||||
bool _useGzip = true;
|
||||
};
|
||||
} // namespace drogon
|
||||
|
|
|
@ -179,11 +179,12 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestPtr &r
|
|||
response->setBody(std::string());
|
||||
auto &sendfileName = std::dynamic_pointer_cast<HttpResponseImpl>(response)->sendfileName();
|
||||
auto newResp = response;
|
||||
if (sendfileName.empty() &&
|
||||
response->getContentTypeCode() < CT_APPLICATION_OCTET_STREAM &&
|
||||
response->getBody().length() > 1024 &&
|
||||
if (HttpAppFramework::instance().useGzip() &&
|
||||
sendfileName.empty() &&
|
||||
req->getHeader("Accept-Encoding").find("gzip") != std::string::npos &&
|
||||
response->getHeader("Content-Encoding") == "")
|
||||
response->getHeader("Content-Encoding") == "" &&
|
||||
response->getContentTypeCode() < CT_APPLICATION_OCTET_STREAM &&
|
||||
response->getBody().length() > 1024)
|
||||
{
|
||||
//use gzip
|
||||
LOG_TRACE << "Use gzip to compress the body";
|
||||
|
|
Loading…
Reference in New Issue