diff --git a/CMakeLists.txt b/CMakeLists.txt index 17eb2d1..ad820dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,8 @@ set_target_properties(${FASTWEBCORE} PROPERTIES OUTPUT_NAME_DEBUG "${FASTWEBCORE + + link_directories(/usr/lib/x86_64-linux-gnu) link_directories(/usr/local/lib) @@ -127,6 +129,7 @@ endif() add_executable(${PROJECT_NAME} tests/main.cpp) target_link_libraries(${PROJECT_NAME} ${FASTWEBCORE}) +set_target_properties(${PROJECT_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}") ######################## 安装 ######################## install(TARGETS ${FASTWEBCORE} DESTINATION $,bin/debug,bin/release>) install(TARGETS ${PROJECT_NAME} DESTINATION $,bin/debug,bin/release>) diff --git a/config.ini b/config.ini index b66711a..c2cda5d 100644 --- a/config.ini +++ b/config.ini @@ -1,5 +1,6 @@ [variable] base=${current_dir} + [scripts] ; 应用目录(可执行脚本) ; 考虑安全性,请勿放置于网站静态文件目录 @@ -9,7 +10,7 @@ lib_dir=${base}/scripts/lib ; LUA虚拟机缓存数量(并发越高越大)-建议:10 lua_cache_size=3000 ; 脚本映射网站目录 -; 例如 D:/root/scripts/app/regist.lua 是脚本路径,app_mapping_dir设置的是/scripts,浏览器访问地址:http://127.0.0.1/scripts/regist.lua +; 例如 app_mapping_dir设置的是/api,app_dir目录下有regist.lua,则浏览器访问地址:http://127.0.0.1/scripts/regist.lua ; 注意:必须/结尾 app_mapping_dir=/scripts/ ; 自动检测文件修改时间(秒) @@ -32,15 +33,32 @@ Initialization_script=${base}/scripts/init.lua interceptor_scripts= [["${base}/scripts/interceptor.lua","/scripts/*.*"]] ; 调试模式,开启后控制台输出异常错误信息 (0=关闭 1=开启) debug=1 -[server] -; TCP服务监听地址 -address=0.0.0.0 -; TCP服务监听端口 -; 启用SSL:443 -; 不启用SSL:80或其它 -port=8888 - - +; 绑定域名 +domain=["local.newobj.org","127.0.0.1"] +; 域名配置信息,具体根据 website->domain 而定 +[local.newobj.org] +; 是否为HTTPS +https=1 +;HTTPS证书,完全兼容Nginx证书 +; 证书KEY +ssl_key=${base}/config/ssl/local.newobj.org.key +; 证书PEM文件 +ssl_pem=${base}/config/ssl/local.newobj.org.pem +; 证书CA文件(默认:空) +ssl_ca= +; 证书密码(默认:空) +ssl_pwd= +; ================验证类型================= +; 0 = 完全忽略验证证书的结果。当握手必须完成的话,就选中这个选项。其实真正有证书的人很少,尤其是在中国,那么如果 SSL 运用于一些免费的服务,比如 EMAIL 的时候,SERVER 端最好采用这个模式。 +; 1 = 希望验证对方的证书。这个是最一般的模式。对 CLIENT 来说,如果设置了这样的模式,验证SERVER的证书出了任何错误,SSL 握手都告吹。对 SERVER 来说,如果设置了这样的模式,CLIENT 倒不一定要把自己的证书交出去。如果 CLIENT 没有交出证书,SERVER 自己决定下一步怎么做。 +; 2 = 这是 SERVER 使用的一种模式,在这种模式下, SERVER 会向 CLIENT 要证书。如果 CLIENT 不给,SSL 握手告吹 +; 3 = 这是仅能使用在 SSL SESSION RENEGOTIATION 阶段的一种方式。如果不是用这个模式的话,那么在 RENEGOTIATION 的时候,CLIENT 都要把自己的证书送给 SERVER,然后做一番分析。这个过程很消耗 CPU 时间的,而这个模式则不需要 CLIENT 在 RENEGOTIATION 的时候重复送自己的证书了。 +ssl_ver_type=0 +; 端口,默认https为443,http为80 +port=8566 +[127.0.0.1] +https=0 +port=8866 diff --git a/config/ssl/local.newobj.org.key b/config/ssl/local.newobj.org.key new file mode 100644 index 0000000..6efa2d5 --- /dev/null +++ b/config/ssl/local.newobj.org.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDBiTdJOfaHJ0L4 +BYyiN+CF5uL82wFjfrn5evWwKZ6Ie0JxDkzG/okswhtwvU75g5uhWbWzdQR47EmP +uGJnrw1apVOnzV9e6XuTc2o6YMAInXn1JAfKx5bJCJJr+EnxEw9orsfXk3KGfPBC +vWjzrUcm5oKvC08eCv5Na1w3ukaObQBOwGRp9QY8o046KtmR95V8RKUbtW9W1Ldp +GOJDKHgSC0Os4urHxYpt11tx0u3jjzSphkE/+6F2SDGCza46huzdoYmdaY0d2F0S +jiuve+6pfS8iCyMa05aHq35stWk1PWmtCYzzJXnmbWdMkadJNuQRJUyEOLQ3U2hp +m+ZbJ9zjAgMBAAECggEAIQuCyxgAhfcoMh0QdCpCRdq0ayQhypE6w+RAywFwNjGF +mLQuW9PeLCxAbzGDqIrWKeidY7TZPKRrswRymO2ExDNyYzZn0FbhaL3OJ4WZhF8P +EdJDGlaV4mF6TsEoLudoPCGLsb1VUq1GgL7CisjNW1EEg0rVCXYrEaEBL+q4XVzm +rdUFuui0qNNjSomVTMaiEjyziMQ3k1vKaMvXG8h3eO5O31z67Muy90T6eJ3nBq+3 +qbyfgnj3MAly1nKCQRA2IBW7by9beIz2pSz40u207d+PoCcv2/FMsXkuQ4jxji/m +8VIz1jwd5cwBfMxjZ0hcXO1Nq06WfqHnOyF+zMlfEQKBgQD5XZP6L2+qrOtOIf0U +eDWAGRBCLpc16nevQ7jaovHWdIqFiqZMdnELbpYerTT17XcJx/03EIl1x7P/TJA9 +OaMlDG5SoY9XcFTVieZgr0osqgFixi54EEB49HuzxWDj6BMwss39ntVSTAkRzJhx +D9bY5tlCvEaQpFyGPpjfVv4+xwKBgQDGr2JqgTPgrH9mCeIYOr/GwqHWhBHoibT6 +f16oyLdnPtctvPAzZJ/cOVHCy0nssSuPR77pK7qb2cHW+n+txq23bhkCEeNkNn6m +6yzNnG+fO9LKTm/oazqQle9UIaba4if0aIWoHl5tYbQZ//QVJpNAcMR/cwS4V4T0 +z/z9Q5NFBQKBgQCfyBdOYuDRYvVvXhX07MWTK/wf/AyFzpQb6G/lIC2HtasgwGOo +cOgkZBqq018xCZSR3uRgSSdbIbgzKNLveCQSVDHInp7jbyXcofzNDOShU9mJeeVC +p184Yad13E4mGolZVejpzsFvdysEja1MHNMUrm6d9VfdzINAvZFk4jAM9wKBgQCU +NINfGt2NvF6TyM+Eb15abxi1oXKSWRZMvPHpST+1niR4k7VBQNAWQBODEI0mJ8ps +aII6AEqEstxq9hSDle5DI7c32gwa1qOG82pKPWTuDHviOLw1TLc03wLVaPzDzWss +X0ND8tNRGE52Dn0NweaZbQTGZQ+iSnZ8/yCh8uRJ2QKBgENPTd40kx9aP2r1/j+D +ONBU8ky3MhoJ056aqYQGRIYCMCCqbXM3wXLgAN/x+75usjFz/iN8rbWcIQjw65nC +SV8x721hl12U+JWvvmGV9owjGLK1pzYfdqa7ixkPO8/O3Uut48Mem/k5rSTxCTwT +W+8UqBhoku6UbW3LTx5hJh4K +-----END PRIVATE KEY----- diff --git a/config/ssl/local.newobj.org.pem b/config/ssl/local.newobj.org.pem new file mode 100644 index 0000000..35b2636 --- /dev/null +++ b/config/ssl/local.newobj.org.pem @@ -0,0 +1,60 @@ +-----BEGIN CERTIFICATE----- +MIIE7TCCA9WgAwIBAgISA/3ZsdoAxQjKqccTsHCsEyu4MA0GCSqGSIb3DQEBCwUA +MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD +EwJSMzAeFw0yNDA1MjgxNDAyMTBaFw0yNDA4MjYxNDAyMDlaMBsxGTAXBgNVBAMT +EGxvY2FsLm5ld29iai5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDBiTdJOfaHJ0L4BYyiN+CF5uL82wFjfrn5evWwKZ6Ie0JxDkzG/okswhtwvU75 +g5uhWbWzdQR47EmPuGJnrw1apVOnzV9e6XuTc2o6YMAInXn1JAfKx5bJCJJr+Enx +Ew9orsfXk3KGfPBCvWjzrUcm5oKvC08eCv5Na1w3ukaObQBOwGRp9QY8o046KtmR +95V8RKUbtW9W1LdpGOJDKHgSC0Os4urHxYpt11tx0u3jjzSphkE/+6F2SDGCza46 +huzdoYmdaY0d2F0Sjiuve+6pfS8iCyMa05aHq35stWk1PWmtCYzzJXnmbWdMkadJ +NuQRJUyEOLQ3U2hpm+ZbJ9zjAgMBAAGjggISMIICDjAOBgNVHQ8BAf8EBAMCBaAw +HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYD +VR0OBBYEFIAYfAsnvnBYyPfyH8teZNpOI/2RMB8GA1UdIwQYMBaAFBQusxe3WFbL +rlAJQOYfr52LFMLGMFUGCCsGAQUFBwEBBEkwRzAhBggrBgEFBQcwAYYVaHR0cDov +L3IzLm8ubGVuY3Iub3JnMCIGCCsGAQUFBzAChhZodHRwOi8vcjMuaS5sZW5jci5v +cmcvMBsGA1UdEQQUMBKCEGxvY2FsLm5ld29iai5vcmcwEwYDVR0gBAwwCjAIBgZn +gQwBAgEwggEEBgorBgEEAdZ5AgQCBIH1BIHyAPAAdgB2/4g/Crb7lVHCYcz1h7o0 +tKTNuyncaEIKn+ZnTFo6dAAAAY+/uRqTAAAEAwBHMEUCIFFn3GO/G0kr8XhbTm0O +bI08Pz6OzkvqGjcPDXJMmSUzAiEAsfrW5DVMPj/Uhm0f3oWGfRbvmUxj4xiwA+Q2 +h0sHGZIAdgDf4VbrqgWvtZwPhnGNqMAyTq5W2W6n9aVqAdHBO75SXAAAAY+/uRr+ +AAAEAwBHMEUCIExO427ffujJmSQzGq9EwnT7gfwvldQNH7wavYKJEP6HAiEAhaNl +dfSMqepd+DCasm73LghCqKAmqcPU6STUkI6qi08wDQYJKoZIhvcNAQELBQADggEB +AFNono1dy2oT+8p1q39n/WqdrdlcjnpT0ogzm+tKlvHFQnFadE35yCSV983AK4hE +rzkHH07rVq82cHTK61n7KA1m6C4ZwS/wx8th6gdhDVMmEpYXT+oMmmK9pnsxoei1 +N6rDHNSXiEumqqk/cu/7aTwWT7Qjd4Hxzw8kvY6pCGx68OQxkjvBQkL0ZVSTNfrr +IGgqgkouku+IhDDuiq4Kf7MNaWINQ+8mvQcxy8xjh8+DMcqxO+ThgjJhx5OTc4/K +PjBh4B98Nv0t5w8ClWWP1yFXUggldfJGgjrPhjeK1tSb8zZQFZqfKWRvWRcClbiL +GaOgdXDbz4ZDeFQRri+Cx9M= +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw +WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg +RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP +R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx +sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm +NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg +Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG +/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB +Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA +FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw +Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB +gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W +PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl +ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz +CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm +lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4 +avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2 +yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O +yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids +hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+ +HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv +MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX +nLRbwHOoq7hHwg== +-----END CERTIFICATE----- diff --git a/src/core/config.cpp b/src/core/config.cpp index 1a0249e..b6bc8b7 100644 --- a/src/core/config.cpp +++ b/src/core/config.cpp @@ -35,6 +35,15 @@ bool config::open(const std::string& ini_filepath) cache(); return true; } +bool config::have_https() +{ + for_iter(iter, domain) + { + if (iter->second.https) + return true; + } + return false; +} std::vector config::extractVariableNames(const std::string& text) { std::regex pattern("\\$\\{([^}]+)\\}"); // 使用捕获组提取中间的内容 @@ -51,8 +60,6 @@ std::vector config::extractVariableNames(const std::string& text) void config::cache() { - server.address = m_ini.read("server", "address"); - server.port = ylib::stoi(m_ini.read("server", "port")); scripts.app_dir = m_ini.read("scripts","app_dir"); scripts.lib_dir = m_ini.read("scripts", "lib_dir"); @@ -67,6 +74,7 @@ void config::cache() website.session_timeout_sec = ylib::stoi(m_ini.read("website", "session_timeout_sec")); website.Initialization_script = m_ini.read("website", "Initialization_script"); website.debug = m_ini.read("website", "debug") == "1"; + website.domain = ylib::json::from(m_ini.read("website", "domain")).to>(); { ylib::json interceptors = ylib::json::from(m_ini.read("website", "interceptor_scripts")); @@ -83,4 +91,45 @@ void config::cache() website.interceptor_scripts.push_back(inr); } } + + // website 域名参数 + for(size_t i=0;i< website.domain.size();i++) + { + if (website.domain[i].empty()) + continue; + + struct config::domain dm; + dm.port = ylib::stoi(m_ini.read(website.domain[i], "port")); + dm.https = m_ini.read(website.domain[i],"https")=="1"; + dm.ssl.pem_key = ylib::file::read(m_ini.read(website.domain[i], "ssl_key")); + dm.ssl.pem_cert = ylib::file::read(m_ini.read(website.domain[i], "ssl_pem")); + dm.ssl.pem_ca = ylib::file::read(m_ini.read(website.domain[i], "ssl_ca")); + dm.ssl.pem_password = m_ini.read(website.domain[i], "ssl_pwd"); + dm.ssl.type = (network::http::ssl_verify_type)ylib::stoi(m_ini.read(website.domain[i], "ssl_ver_type")); + if (dm.port == 0) + { + LOG_ERROR("domain("+website.domain[i] + ") name unavailable, port is 0"); + continue; + } + if (dm.https) + { + dm.ssl.enable = true; + if (dm.ssl.pem_key.empty()) + { + LOG_ERROR("domain(" + website.domain[i] + ") ssl_key file is read as empty, please check the ssl_key"); + continue; + } + if (dm.ssl.pem_cert.empty()) + { + LOG_ERROR("domain(" + website.domain[i] + ") ssl_pem file is read as empty, please check the ssl_pem"); + continue; + } + if (dm.ssl.type < 0 || dm.ssl.type > 3) + { + LOG_ERROR("domain(" + website.domain[i] + ") ssl_ver_type is not filled in correctly, it should be: 0~3"); + continue; + } + } + domain.emplace(website.domain[i],dm); + } } diff --git a/src/core/config.h b/src/core/config.h index f862d04..58c7e7a 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -3,8 +3,14 @@ #include "base/error.h" #include "base/singleton.hpp" #include "util/ini.h" +#include "net/http_define.h" class config:public ylib::error_base,public ylib::singleton{ public: + struct domain { + bool https = false; + ushort port = 0; + network::http::ssl_config ssl; + }; struct scripts { std::string app_dir; std::string lib_dir; @@ -25,14 +31,17 @@ public: std::string Initialization_script; std::vector<__interceptor> interceptor_scripts; bool debug = false; - }; - struct server { - std::string address; - ushort port = 0; + std::vector domain; }; public: config() = default; bool open(const std::string& ini_filepath); + + /// + /// 是否含有https + /// + /// + bool have_https(); private: // INI配置文件 ylib::ini m_ini; @@ -50,5 +59,5 @@ private: public: scripts scripts; website website; - server server; + std::map domain; }; \ No newline at end of file diff --git a/src/core/fastweb.cpp b/src/core/fastweb.cpp index 8a1060c..0acad29 100644 --- a/src/core/fastweb.cpp +++ b/src/core/fastweb.cpp @@ -24,26 +24,36 @@ bool fastweb::start() m_center = new network::http::center(); network::http::start_config config; network::http::website_config ws_config; - network::http::host_config host_config; - host_config.domain = "0.0.0.0"; - host_config.port =(ushort)sConfig->server.port; - - host_config.ssl = false; + + for_iter(iter, sConfig->domain) + { + network::http::host_config host_config; + host_config.domain = iter->first; + host_config.port = iter->second.port; + host_config.ssl = iter->second.https; + ws_config.host.push_back(host_config); + } ws_config.name = "master"; - ws_config.host.push_back(host_config); + ws_config.router.threadpool.size = 40; ws_config.router.threadpool.queuemax = 10000; ws_config.session.dirpath = sConfig->website.session_dir; ws_config.session.timeout_sec = sConfig->website.session_timeout_sec; config.website.push_back(ws_config); + for_iter(iter, sConfig->domain) + { + if(iter->second.https) + config.cert.emplace(iter->first, iter->second.ssl); + } + if (!m_center->create(config)) { m_lastErrorDesc = "start failed," + m_center->last_error(); stop(); return false; } - auto website = m_center->website(sConfig->server.address); + auto website = m_center->website_byname(ws_config.name); auto router = website->router(); // 初始化脚本