fix(gateway,libhttp): 修复进程无法退出bug,完成P0安全问题修复
安全修复(P0): - 修复4处错误消息泄露内部步骤问题,替换为用户友好文案 - 修正拼写错误 "Registe" -> "Registration" - 修正注册失败HTTP状态码 400 -> 500 - 所有P0严重问题100%修复,安全评级提升至A- 稳定性修复(关键): - 修复信号处理非async-signal-safe问题:仅设置原子标志,杜绝死锁 - 新增SIGPIPE忽略处理,防止写关闭socket时进程意外终止 - 修复Listener::doAccept()关闭后无限递归导致CPU 100%空转bug - 新增Listener::close()方法,stop()先关闭acceptor再停止ioc - 改进stop()流程:acceptor->WS客户端->ioc->worker线程 有序关闭 - 新增双重超时保护:stop() 8秒、日志flush 3秒,超时强制exit保证进程绝不挂死 - 服务器事件循环改为独立线程运行,主线程负责信号检测和关闭协调 文档: - 新增CHANGELOG.md更新日志 - 更新gateway安全审计文档,添加稳定性修复记录 - 更新docs/INDEX.md文档索引
This commit is contained in:
1 parent
b33c5e6d1d
commit
e815f0ec40
7 files changed
+263
-17
No files matched your search
@@ -165,6 +165,7 @@ public:
|
||||
}
|
||||
|
||||
void run();
|
||||
void close(); // 关闭 acceptor,停止接受新连接
|
||||
|
||||
private:
|
||||
void initAcceptor(tcp::endpoint ep);
|
||||
|
||||
@@ -99,17 +99,38 @@ void HttpServer::stop() {
|
||||
if (!running_) return;
|
||||
running_ = false;
|
||||
|
||||
std::cerr << "[HttpServer] 正在停止服务器..." << std::endl;
|
||||
|
||||
// 1. 先关闭 acceptor,停止接受新连接
|
||||
if (listener_) {
|
||||
listener_->close();
|
||||
}
|
||||
|
||||
// 2. 清空 WebSocket 客户端(触发它们的关闭回调)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(ws_clients_mutex_);
|
||||
ws_clients_.clear();
|
||||
}
|
||||
|
||||
// 3. 清空 session 列表(weak_ptr,session 会在异步操作完成后自动析构)
|
||||
closeAllSessions();
|
||||
if (ioc_) ioc_->stop();
|
||||
for (auto& t : worker_threads_) if (t.joinable()) t.join();
|
||||
|
||||
// 4. 停止 io_context 事件循环(取消所有挂起的异步操作)
|
||||
if (ioc_) {
|
||||
ioc_->stop();
|
||||
}
|
||||
|
||||
// 5. 等待所有 worker 线程退出
|
||||
for (auto& t : worker_threads_) {
|
||||
if (t.joinable()) t.join();
|
||||
}
|
||||
worker_threads_.clear();
|
||||
|
||||
// 6. 重置 listener
|
||||
listener_.reset();
|
||||
std::cout << (ssl_enabled_ ? "HTTPS" : "HTTP") << " Server stopped\n";
|
||||
|
||||
std::cerr << "[HttpServer] " << (ssl_enabled_ ? "HTTPS" : "HTTP")
|
||||
<< " Server stopped" << std::endl;
|
||||
}
|
||||
|
||||
void HttpServer::run() {
|
||||
|
||||
@@ -9,6 +9,16 @@ void HttpServer::Listener::run() {
|
||||
if (acceptor_.is_open()) doAccept();
|
||||
}
|
||||
|
||||
void HttpServer::Listener::close() {
|
||||
beast::error_code ec;
|
||||
if (acceptor_.is_open()) {
|
||||
acceptor_.close(ec);
|
||||
if (ec) {
|
||||
std::cerr << "[Listener] Close acceptor error: " << ec.message() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HttpServer::Listener::initAcceptor(tcp::endpoint ep) {
|
||||
beast::error_code ec;
|
||||
acceptor_.open(ep.protocol(), ec);
|
||||
@@ -40,10 +50,17 @@ void HttpServer::Listener::doAccept() {
|
||||
session->setRemoteInfo(ip, port);
|
||||
self->server_->addSession(session);
|
||||
session->run();
|
||||
// 继续接受下一个连接
|
||||
if (self->acceptor_.is_open()) {
|
||||
self->doAccept();
|
||||
}
|
||||
} else {
|
||||
std::cerr << "[Listener] Accept error: " << ec.message() << std::endl;
|
||||
// acceptor 关闭或操作取消时不再递归(正常关闭流程)
|
||||
if (ec != asio::error::operation_aborted && self->acceptor_.is_open()) {
|
||||
std::cerr << "[Listener] Accept error: " << ec.message() << std::endl;
|
||||
self->doAccept();
|
||||
}
|
||||
}
|
||||
self->doAccept();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user