Releases: Hical61/Hical
Releases · Hical61/Hical
v2.3.0
What's New
🗄️ 协程数据库中间件(Boost.MySQL 后端)
- 四层架构:DbConfig / DbResult / DbConnection 接口 / 连接池 / HTTP 中间件 / 查询日志
MysqlConnection:基于 Boost.MySQLany_connection,支持 PreparedStatement LRU 缓存DbConnectionPool:协程信号量、LIFO 复用、后台健康检查、空闲淘汰、ping 宽限期优化DbMiddleware:自动事务提交/回滚、连接注入、洋葱模型集成DbQueryLog:装饰器模式查询日志、慢查询检测回调StmtCache:LRU 预编译语句缓存,透明string_view零分配查找- 通过
cmake -DHICAL_WITH_DATABASE=ON启用,编译期HICAL_HAS_DATABASE宏隔离
📝 文档更新
- API 参考、架构文档、构建指南、示例文档全面补充数据库中间件内容
- 新增
scripts/bump_version.py版本号管理脚本
依赖
- Boost >= 1.85(数据库中间件需要 Boost.MySQL + charconv)
- 核心框架仍仅需 Boost >= 1.82
Full Changelog: v2.2.0...v2.3.0
v2.2.0
详见 CHANGELOG.md
Full Changelog: v2.1.0...v2.2.0
v2.1.0
Breaking Changes
- HttpRequest 返回类型收紧:
header()返回string_view(原string)、cookie()/param()返回const string&(原string)、contentType()返回string_view、jsonBody()返回const json::value&(原值拷贝)——大多数调用点源码兼容,仅存储到auto的场景可能需确认 - serveStatic 异步化:返回类型从
function<HttpResponse(...)>改为function<Awaitable<HttpResponse>(...)>,调用方需在协程中co_await - Boost 最低版本:1.70 → 1.78(
random_access_file依赖) - Linux 新增依赖:
liburing-dev(Boost.Asiorandom_access_file在 Linux 上依赖 io_uring)
Added
- 文件异步发送:
TcpConnection::sendFile(path, offset, length)+WriteNode多态写队列(MemoryWriteNode/FileWriteNode),支持random_access_file异步读取 + 64KB 分块发送 - macOS 平台回退:
GenericConnection::sendFileNode()和serveStatic()在无BOOST_ASIO_HAS_FILE平台自动回退到std::ifstream同步读取 - WebSocket Origin 白名单:
Router::ws()新增WsOptions重载,支持allowedOrigins集合,不在白名单内的 Origin 返回 403(CSWSH 防护) - WebSocket 中间件链:WS 升级请求经过预构建的中间件链,中间件可返回非 200 阻止升级(认证/限流)
- WebSocket 空闲超时:复用
idleTimeout_设置,超时无消息的 WS 连接自动断开 - 空闲连接超时清理:
TcpServer::setIdleTimeout(seconds)+idleCheckLoop()协程定期扫描,断开超时连接 - fd 耗尽防护:
IdleFd类(POSIX 预留/dev/nullfd),EMFILE 时临时释放→accept→close→重新预留,避免 accept 循环忙转 - Session 重建:
SessionManager::regenerate(oldId)生成新 ID 并迁移数据,旧 ID 失效(Session 固定攻击防护) - Session 数据迁移:
Session::migrateFrom(other)原子迁移数据,地址序双锁防死锁 - MetaJson 装饰器:C++20 宏路径新增
ALIAS(field, "key")、REQUIRED(field)、REQUIRED_ALIAS(field, "key")、HICAL_IGNORE(field),__VA_OPT__递归展开无字段数上限 - MetaJson C++26 属性:
[[hical::json_name("alias")]]、[[hical::json_required]]、[[hical::json_ignore]]+jsonSchema<T>()/toJsonSnakeCase<T>() - MetaJson unsigned 支持:
valueToJson()/valueFromJson()正确处理uint64_t,防止大无符号数据丢失 - 中间件预构建 API:
MiddlewarePipeline::buildFor(finalHandler)返回可缓存的MiddlewareNext - Multipart 双 API:新增
getFile(parts, fieldName)/getField(parts, fieldName)重载,搜索预解析结果避免重复解析 - HTTP Header 注入防护:
HttpRequest::setHeader()和HttpResponse::setHeader()拒绝含 CR/LF 的头部名/值 - SSL 懒包含:
SslConnection.h独立类型别名头文件,非 SSL 场景不拉 OpenSSL 头文件 - Session 测试补充:
RegenerateSession、RegenerateNonExistent、MigrateFromSession、RegenerateConcurrent4 个测试
Changed
- Session 读写锁:
SessionManager::mutex_从std::mutex升级为std::shared_mutex,find()使用shared_lock提升读并发 - Session 懒 GC:
find()不再立即删除过期条目(避免 shared→unique 锁升级竞态),过期条目由gc()定期清理;create()达上限时先强制 GC 再拒绝 - 路由参数分组:参数路由从全局
vector改为unordered_map<HttpMethod, vector>,dispatch 仅扫描匹配方法的子集 - 路径 DoS 防护:单遍扫描同时计算 URL 解码需求和段深度,>256 段早期拒绝(
hMaxPathSegments) - 连接存储优化:
TcpServer连接集合从set改为unordered_set(O(1) 插入/删除) - 连接活跃时间:
GenericConnection新增lastActiveTimeMs_原子字段,读写循环更新 - HttpRequest path params:存储从
unordered_map改为vector<pair>,小参数集更少分配 - jsonBody() 缓存:多次调用只解析一次,后续返回缓存引用
- PmrBuffer 自适应:
retrieveAll()超过 2× 初始容量时自动缩容;ensureWritableBytes()改为 2× 指数增长 - StaticFiles 路径缓存:
PathCache(4096 条目 / 60s TTL)避免每请求canonical()系统调用 - Multipart toLowerInPlace:头部键原地小写,消除临时 string 拷贝
- GenericConnection 写队列:从
deque<shared_ptr<string>>改为deque<shared_ptr<WriteNode>>,统一内存/文件节点
Security
- WebSocket Origin 白名单(CSWSH 防护)
- HTTP Header CR/LF 注入防护(Response Splitting 防护)
- Session
regenerate()防 Session 固定攻击 - 路径段深度限制防 DoS
Full Changelog: v2.0.1...v2.1.0
v2.0.1
What's Changed
Bug Fixes
- CMake: 添加
WINDOWS_EXPORT_ALL_SYMBOLS属性,修复 MSVC 下 shared 库构建时无法生成导入库 (.lib) 的问题
Package Manager Support
- 新增 Conan Center Index (CCI) 提交支持
Full Changelog: v2.0.0...v2.0.1
v2.0.0 — 安全加固与性能优化
Fixed
- [P0] Middleware 悬空引用:
build()和execute()中 lambda 按引用捕获middlewares_[i]改为按值捕获,防止协程帧中 use-after-free - [P0] HttpServer timer 竞态:超时
steady_timer移到循环外复用,引入shared_ptr<atomic<bool>>存活标志 + RAII 守卫,消除 timer 回调访问已销毁 socket 的竞态 - [P0] GenericConnection 数据竞争:
reading_从bool改为std::atomic<bool>,修复stopRead()跨线程写入与readLoop()读取之间的数据竞争 - [P0] TcpServer acceptLoop use-after-this:协程 lambda 捕获
alive_标志,循环条件和co_await恢复后均检查存活性,防止析构后访问this - [P1] Multipart DoS 检查位置:Part 数量上限检查从
push_back之后移到之前,避免先分配后丢弃
Changed
- Middleware 重构:提取公共
buildChain()方法消除build()/execute()逻辑重复;新增无参execute(HttpRequest&)重载走缓存路径,双参execute(req, finalHandler)始终动态构建 - Session ID 生成:从
std::mt19937_64(伪随机)改为OpenSSL RAND_bytes(密码学安全),hex 编码改为查表法消除ostringstream开销 - Cookie 安全默认值:
CookieOptions默认httpOnly=true、secure=true、sameSite="Lax";SessionOptions::secure同步改为true - Session 嵌套锁消除:
Session::lastAccess_从chrono::time_point(mutex 保护)改为atomic<int64_t>纳秒时间戳,touch()/lastAccess()无锁操作 - send(PmrBuffer&&) 语义修复:改为调用
buffer.readAll()走send(std::string&&)的 move 通道,不再退化为拷贝 - Router urlDecode 快速路径:先扫描路径是否含
%/+,无编码字符时跳过urlDecode分配;RouteKey引入透明哈希(RouteKeyView+is_transparent),staticRoutes_.find()直接用string_view查找,消除每请求的std::string堆分配 - HttpServer 中间件调用:已
build()场景改用无参execute(req),每请求省去一次std::function堆分配
Added
SessionOptions::maxSessions(默认 100000):Session 存储上限,create()达到上限时返回nullptr,中间件返回 503
Full Changelog: v1.0.1...v2.0.0
Full Changelog: v1.0.1...v2.0.0
v1.0.1
v1.0.1
Added
- vcpkg overlay port(
ports/hical/),支持vcpkg install hical --overlay-ports=./ports HICAL_BUILD_TESTS/HICAL_BUILD_EXAMPLESCMake 选项(默认 ON),作为库分发时可关闭hical::hical_coreALIAS 目标docs/integration_guide.md:vcpkg overlay、FetchContent、cmake install 三种集成方式说明
Fixed
INSTALL_INTERFACEinclude 路径修正,修复find_package后头文件找不到的问题- Windows
ws2_32/mswsock统一移至hical_core目标,消费者无需手动添加
Changed
- 移除全局
include_directories,改为完全依赖target_include_directories传递 GTest改为按需查找,仅HICAL_BUILD_TESTS=ON时才find_package
Full Changelog: v1.0.0...v1.0.1
v1.0.0:首次公开发布
Full Changelog: https://github.com/Hical61/Hical/commits/v1.0.0