From 93a07ed17ab321eccc7dd779d24f081ae2480a5e Mon Sep 17 00:00:00 2001 From: antao Date: Sun, 14 Oct 2018 11:53:05 +0800 Subject: [PATCH] 1.Add gzip option in config file; 2.rename config example file's name --- config.json.example => config.example.json | 42 ++- drogon_ctl/create_project.cc | 35 ++- examples/simple_example/main.cc | 2 +- lib/inc/drogon/HttpAppFramework.h | 152 +++++------ lib/src/ConfigLoader.cc | 139 +++++----- lib/src/HttpAppFrameworkImpl.h | 304 +++++++++++---------- lib/src/HttpServer.cc | 9 +- 7 files changed, 357 insertions(+), 326 deletions(-) rename config.json.example => config.example.json (80%) diff --git a/config.json.example b/config.example.json similarity index 80% rename from config.json.example rename to config.example.json index 01da8b67..1514148d 100644 --- a/config.json.example +++ b/config.example.json @@ -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 } } diff --git a/drogon_ctl/create_project.cc b/drogon_ctl/create_project.cc index c57dbe51..dd533ebf 100644 --- a/drogon_ctl/create_project.cc +++ b/drogon_ctl/create_project.cc @@ -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"; } diff --git a/examples/simple_example/main.cc b/examples/simple_example/main.cc index cc3ff5c8..c77b0081 100755 --- a/examples/simple_example/main.cc +++ b/examples/simple_example/main.cc @@ -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(); } diff --git a/lib/inc/drogon/HttpAppFramework.h b/lib/inc/drogon/HttpAppFramework.h index 5fdf7b44..3930d0c9 100755 --- a/lib/inc/drogon/HttpAppFramework.h +++ b/lib/inc/drogon/HttpAppFramework.h @@ -39,80 +39,80 @@ #include 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 &filters= - std::vector())=0; - virtual void registerHttpSimpleController(const std::string &pathName, - const std::string &crtlName, - const std::vector &filters=std::vector())=0; - template - static void registerHttpApiMethod(const std::string &pathPattern, - FUNCTION && function, - const std::vector &filters=std::vector()) - { - LOG_TRACE<<"pathPattern:"< - >(std::forward(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 &types)=0; - virtual void enableDynamicViewsLoading(const std::vector &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 &filters=std::vector())=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 &filters = + std::vector()) = 0; + virtual void registerHttpSimpleController(const std::string &pathName, + const std::string &crtlName, + const std::vector &filters = std::vector()) = 0; + template + static void registerHttpApiMethod(const std::string &pathPattern, + FUNCTION &&function, + const std::vector &filters = std::vector()) + { + LOG_TRACE << "pathPattern:" << pathPattern; + HttpApiBinderBasePtr binder; + + binder = std::make_shared< + HttpApiBinder>(std::forward(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 &types) = 0; + virtual void enableDynamicViewsLoading(const std::vector &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 &filters = std::vector()) = 0; +}; +} // namespace drogon diff --git a/lib/src/ConfigLoader.cc b/lib/src/ConfigLoader.cc index fec20912..5e603fd1 100644 --- a/lib/src/ConfigLoader.cc +++ b/lib/src/ConfigLoader.cc @@ -21,123 +21,123 @@ #include 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 "<>_configJsonRoot; + try + { + infile >> _configJsonRoot; } catch (const std::exception &exception) { - std::cerr<<"Configuration file format error! in "< types; - for(auto fileType:fileTypes) + for (auto fileType : fileTypes) { types.push_back(fileType.asString()); - LOG_TRACE<<"file type:"<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 paths; - for(auto viewsPath:viewsPaths) + for (auto viewsPath : viewsPaths) { paths.push_back(viewsPath.asString()); - LOG_TRACE<<"views path:"< &filters= - std::vector())override ; - virtual void registerHttpSimpleController(const std::string &pathName, - const std::string &crtlName, - const std::vector &filters= - std::vector())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 &types) override; - virtual void enableDynamicViewsLoading(const std::vector &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 &filters = + std::vector()) override; + virtual void registerHttpSimpleController(const std::string &pathName, + const std::string &crtlName, + const std::vector &filters = + std::vector()) 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 &types) override; + virtual void enableDynamicViewsLoading(const std::vector &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 &filters=std::vector()) override ; + trantor::EventLoop *loop(); - std::vector> _listeners; - void onAsyncRequest(const HttpRequestPtr& req,const std::function & callback); - void onNewWebsockRequest(const HttpRequestPtr& req, - const std::function & 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 &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 SessionPtr; - std::unique_ptr> _sessionMapPtr; + private: + virtual void registerHttpApiController(const std::string &pathPattern, + const HttpApiBinderBasePtr &binder, + const std::vector &filters = std::vector()) override; - std::unique_ptr> _responseCacheMap; + std::vector> _listeners; + void onAsyncRequest(const HttpRequestPtr &req, const std::function &callback); + void onNewWebsockRequest(const HttpRequestPtr &req, + const std::function &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 &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 SessionPtr; + std::unique_ptr> _sessionMapPtr; - void doFilters(const std::vector &filters, - const HttpRequestPtr& req, - const std::function & callback, + std::unique_ptr> _responseCacheMap; + + void doFilters(const std::vector &filters, + const HttpRequestPtr &req, + const std::function &callback, + bool needSetJsessionid, + const std::string &session_id, + const std::function &missCallback); + void doFilterChain(const std::shared_ptr>> &chain, + const HttpRequestPtr &req, + const std::function &callback, bool needSetJsessionid, const std::string &session_id, - const std::function &missCallback); - void doFilterChain(const std::shared_ptr>> &chain, - const HttpRequestPtr& req, - const std::function & callback, - bool needSetJsessionid, - const std::string &session_id, - const std::function &missCallback); - // - struct ControllerAndFiltersName - { - std::string controllerName; - std::vector filtersName; - std::shared_ptr controller; - std::weak_ptr responsePtr; - std::mutex _mutex; - }; - std::unordered_map_simpCtrlMap; - std::mutex _simpCtrlMutex; - struct WSCtrlAndFiltersName - { - WebSocketControllerBasePtr controller; - std::vector filtersName; - }; - std::unordered_map _websockCtrlMap; - std::mutex _websockCtrlMutex; - - struct ApiBinder - { - std::string pathParameterPattern; - std::vector parameterPlaces; - std::map queryParametersPlaces; - HttpApiBinderBasePtr binderPtr; - std::vector filtersName; - std::unique_ptr binderMtx=std::unique_ptr(new std::mutex); - std::weak_ptr responsePtr; - }; - //std::unordered_map_apiCtrlMap; - std::vector_apiCtrlVector; - std::mutex _apiCtrlMutex; - - std::regex _apiRegex; - bool _enableLastModify=true; - std::set _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 _libFilePaths; - - std::unique_ptr_sharedLibManagerPtr; - - trantor::EventLoop _loop; - - std::string _sslCertPath; - std::string _sslKeyPath; - - size_t _maxConnectionNum=100000; - size_t _maxConnectionNumPerIP=0; - - std::atomic _connectionNum; - std::unordered_map _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 &missCallback); + // + struct ControllerAndFiltersName + { + std::string controllerName; + std::vector filtersName; + std::shared_ptr controller; + std::weak_ptr responsePtr; + std::mutex _mutex; }; -} + std::unordered_map _simpCtrlMap; + std::mutex _simpCtrlMutex; + struct WSCtrlAndFiltersName + { + WebSocketControllerBasePtr controller; + std::vector filtersName; + }; + std::unordered_map _websockCtrlMap; + std::mutex _websockCtrlMutex; + + struct ApiBinder + { + std::string pathParameterPattern; + std::vector parameterPlaces; + std::map queryParametersPlaces; + HttpApiBinderBasePtr binderPtr; + std::vector filtersName; + std::unique_ptr binderMtx = std::unique_ptr(new std::mutex); + std::weak_ptr responsePtr; + }; + //std::unordered_map_apiCtrlMap; + std::vector _apiCtrlVector; + std::mutex _apiCtrlMutex; + + std::regex _apiRegex; + bool _enableLastModify = true; + std::set _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 _libFilePaths; + + std::unique_ptr _sharedLibManagerPtr; + + trantor::EventLoop _loop; + + std::string _sslCertPath; + std::string _sslKeyPath; + + size_t _maxConnectionNum = 100000; + size_t _maxConnectionNumPerIP = 0; + + std::atomic _connectionNum; + std::unordered_map _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 diff --git a/lib/src/HttpServer.cc b/lib/src/HttpServer.cc index 902bb293..e96a9d40 100755 --- a/lib/src/HttpServer.cc +++ b/lib/src/HttpServer.cc @@ -179,11 +179,12 @@ void HttpServer::onRequest(const TcpConnectionPtr &conn, const HttpRequestPtr &r response->setBody(std::string()); auto &sendfileName = std::dynamic_pointer_cast(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";