增加https及多域名支持

This commit is contained in:
xx
2024-05-29 00:00:14 +08:00
parent 02caa22548
commit 99aa41abba
7 changed files with 201 additions and 24 deletions

View File

@@ -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 $<IF:$<CONFIG:Debug>,bin/debug,bin/release>)
install(TARGETS ${PROJECT_NAME} DESTINATION $<IF:$<CONFIG:Debug>,bin/debug,bin/release>)

View File

@@ -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设置的是/apiapp_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服务监听端口
; 启用SSL443
; 不启用SSL80或其它
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为443http为80
port=8566
[127.0.0.1]
https=0
port=8866

View File

@@ -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-----

View File

@@ -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-----

View File

@@ -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<std::string> config::extractVariableNames(const std::string& text)
{
std::regex pattern("\\$\\{([^}]+)\\}"); // 使用捕获组提取中间的内容
@@ -51,8 +60,6 @@ std::vector<std::string> 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<std::vector<std::string>>();
{
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);
}
}

View File

@@ -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<config>{
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<std::string> domain;
};
public:
config() = default;
bool open(const std::string& ini_filepath);
/// <summary>
/// 是否含有https
/// </summary>
/// <returns></returns>
bool have_https();
private:
// INI配置文件
ylib::ini m_ini;
@@ -50,5 +59,5 @@ private:
public:
scripts scripts;
website website;
server server;
std::map<std::string, domain> domain;
};

View File

@@ -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();
// 初始化脚本