175 Commits

Author SHA1 Message Date
xfy911
dd41464b9c feat(middleware): 实现中间件框架(CORS / Basic Auth / Rate Limit)
- 新增 middleware.c/middleware.h:注册表 + 链式执行机制
  - 内置 CORS 中间件:支持预检请求、跨域头
  - 内置 Basic Auth 中间件:HTTP 基础认证
  - 内置 Rate Limit 中间件:基于 IP 的秒级限流
- 修复 config_merge 参数不匹配(新增 has_cors_enabled/has_auth_user/has_auth_pass/has_rate_limit)
- 修复 server_destroy 与 main() 双重释放字符串指针
- 修复 main.c 启动段错误(access_log_path 未初始化)
- 修复 rate_limit 哈希函数包含端口导致同一 IP 不同 bucket 的问题
- 修复 rate_limit 中间件 user_data 悬空指针(改为 ctx->mw_config)
- 修复 401/429 响应 Content-Length 与 body 长度不匹配导致 curl 挂起
- 修复集成测试服务器启动循环:使用 nc 代替 curl,避免触发限流计数
- 修复集成测试 kill_server:使用 kill -9 确保进程退出,并检查端口释放
- 单元测试 18/18 通过,集成测试 66/66 通过
2026-06-06 00:32:22 +08:00
xfy911
e542890e26 docs(plan): 更新路线图,标记 WebSocket 广播完成,新增中间件/插件待办 2026-06-05 18:13:50 +08:00
xfy911
035e4bebb4 feat(websocket): 实现 WebSocket 广播与频道路由系统
新增功能:
- ws_registry_add/remove: 连接注册/注销,自动管理活跃连接链表
- ws_broadcast(): 向所有活跃连接广播文本消息
- ws_broadcast_to_path(): 按握手路径(频道)定向广播
- ws_connection_count(): 获取当前 WebSocket 连接数
- ws_handle_connection() 新增 path 参数,用于频道标识

实现细节:
- 全局链表 + pthread_mutex 保证多线程安全
- 原子计数器统计连接数
- 连接建立时自动注册,关闭/异常时自动注销
- 默认行为保持 echo 不变

编译零警告,61 项集成测试 + 127 个单元测试全部通过。
2026-06-05 18:12:46 +08:00
xfy911
2f6d86c5cd fix(coco): 修正子模块指向 v2.2.0 最新提交 62dbb13
之前 merge commit 中子模块树对象误指向旧版本 b45045e,
实际工作区已使用 62dbb13(v2.2.0 后代)编译并全部测试通过。
2026-06-05 18:12:38 +08:00
xfy911
22c933a99d merge main into feature/windows-compat-impl: resolve conflicts for TLS, HTTP/2, WebSocket, access log 2026-06-05 16:17:55 +08:00
xfy911
3ded38f331 docs(plan): 更新路线图,标记 WebSocket 完成,调整待办优先级 2026-06-05 15:19:07 +08:00
xfy911
2775033198 feat(websocket): 实现 RFC 6455 WebSocket 支持
- 新增 websocket.h / websocket.c:帧解析、编码、握手、连接管理
- server.c: 检测 Upgrade: websocket 请求,执行握手后进入 ws_handle_connection
- 支持文本/二进制帧 echo、ping/pong、close 帧
- 使用 OpenSSL SHA1 计算 Sec-WebSocket-Accept
- 集成测试:新增 2 项 WebSocket 测试(Python 标准库实现)
- 61 项集成测试全部通过,127 项单元测试全部通过
2026-06-05 15:18:01 +08:00
xfy911
0ebf8b997d fix(server): 修复多线程模式下服务器无法处理请求的问题
问题根因:
1. coco_accept/coco_sleep/coco_timer 在多线程全局调度器下不工作,
   因为 main_sched 的 poll_fd 和 timer_wheel 无人轮询
2. client_handler 协程栈上分配了约 40KB+ 的 http_request_t,
   超出默认 2KB 协程栈,导致栈溢出 SIGSEGV

修复方案:
- 主线程直接 accept_loop(poll 阻塞),不使用协程
- accept 成功后通过 coco_go_with_opts 创建 client_handler 协程,
  显式指定 1MB 栈大小
- 单线程模式保持原有行为不变

测试:
- 59/59 集成测试通过
- 127/127 单元测试通过
- curl 多线程模式 HTTP 请求正常返回
2026-06-05 12:37:40 +08:00
xfy911
c5162db508 docs(plan): 更新 coco 子模块升级记录,标记多线程模式问题 2026-06-05 03:14:22 +08:00
xfy911
d2c6dc3617 chore(coco): 升级子模块到 v2.2.0,包含调度器负载重分配与修复 2026-06-05 03:03:42 +08:00
xfy
782bce9122 docs(plan): 更新 Windows 兼容性状态
- 将 Windows 兼容性标记为已完成
- 更新当前状态:跨平台抽象层 platform.h + platform.c
- 更新待办池:移除 Windows 任务,聚焦 HTTPS/TLS 和 HTTP/2
- 添加 Windows 兼容性实现详情章节
2026-06-05 00:51:09 +08:00
xfy
556caf4412 build(makefile): 添加 platform.c 和 Windows 链接选项
- 源文件列表添加 platform.c
- LDFLAGS 添加 -lbrotlienc
- Windows (MinGW) 下自动链接 ws2_32
- 单元测试编译规则添加 platform.c
2026-06-05 00:51:02 +08:00
xfy
e92354d292 refactor(static): 使用跨平台 API 替代 POSIX 依赖
- 文件操作: open/read/close/seek → cocoon_file_open/read/close/seek
- 目录遍历: opendir/readdir/closedir → cocoon_dir_open/next/close
- socket 发送: sendfile → cocoon_sendfile (POSIX) / read+send 64KB (Windows)
- 路径处理: realpath → cocoon_path_resolve
- 文件元数据: stat → cocoon_file_stat
- mkdir 跨平台处理
2026-06-05 00:50:56 +08:00
xfy
7df6ada99e refactor(server): 使用跨平台 API 替代 POSIX 依赖
- int fd → cocoon_socket_t 类型统一
- fcntl O_NONBLOCK → cocoon_socket_nonblock()
- close(fd) → cocoon_socket_close()
- 信号处理 → cocoon_signal_setup()
- 文件元数据 → cocoon_file_stat()
- 路径处理 → cocoon_path_join()
- CPU 核心数 → cocoon_cpu_count()
2026-06-05 00:50:34 +08:00
xfy
78507084c4 refactor(main): 使用跨平台 API 替代 POSIX 依赖
- 移除 <signal.h> 头文件
- 新增 cocoon_socket_init() / cocoon_socket_cleanup() 调用
- 信号处理改用 cocoon_signal_setup() 统一封装
- Windows 下自动 WSAStartup/WSACleanup
2026-06-05 00:50:28 +08:00
xfy
adeeda1fc1 feat(build): 添加 CMakeLists.txt 跨平台构建配置
- 自动检测 Windows/POSIX 平台
- Windows 下链接 ws2_32、查找 brotlienc
- POSIX 下使用 pkgconfig 查找 zlib、libbrotlienc
- 支持 MinGW 和 MSVC 编译器
- 包含安装规则
2026-06-05 00:50:23 +08:00
xfy
c9693612bd feat(platform): 新增跨平台抽象层 platform.h + platform.c
- platform.h: 定义跨平台类型 cocoon_socket_t / cocoon_file_t / cocoon_dir_iter_t
- POSIX 路径: fcntl O_NONBLOCK, sendfile 零拷贝, opendir/readdir, sysconf
- Windows 路径: ioctlsocket(FIONBIO), WSAStartup/WSACleanup, FindFirstFile
- 错误码统一: WSAEWOULDBLOCK→EAGAIN, WSAEINTR→EINTR, WSAECONNRESET→ECONNRESET
- 全部中文注释,Doxygen 风格
2026-06-05 00:50:18 +08:00
xfy911
3ba9fcea62 feat(access_log): 实现 Nginx combined 格式访问日志
- 新增 access_log.c / access_log.h:Nginx combined 格式,线程安全
- cocoon.h / config.c / config.h:支持 access_log 配置字段
- main.c:新增 --access-log CLI 选项,'-' 表示 stdout
- server.c:connection_t 扩展 client_addr/addr_len/response_status
- server.c:handle_request 中记录 response_status 并调用 access_log_write
- Makefile:加入 access_log.c,更新单元测试编译规则
- cocoon.json:示例配置添加 access_log
- 集成测试:新增 5 项访问日志测试
- 59 项集成测试全部通过,35 个单元测试全部通过
2026-06-05 00:20:24 +08:00
xfy911
3374130c8c docs(plan): 更新行动记录,http2.c 注释完成
标记 Doxygen 中文注释任务进度(http2.c 已完成)。
更新最近行动记录:添加本轮 http2.c 注释详情。
2026-06-04 21:08:03 +08:00
xfy911
d0f3bb860f docs(http2): 添加完整的中文 Doxygen 注释
为 http2.c 所有 29 个函数添加中文文档注释:
- 压缩辅助函数(is_compressible_mime, gzip_compress, brotli_compress)
- 会话管理(init, cleanup, create, destroy, is_http2, get, set_context, upgrade)
- 数据收发(recv, send_pending, want_read, want_write)
- nghttp2 回调(send, begin_headers, header, frame_recv, stream_close, data_chunk)
- 静态文件服务(format_http_time, generate_etag, parse_http_time, match_etag,
  data_source_read, serve_directory, serve_static)
- 连接处理(on_connection_accepted)

所有注释包含功能说明、参数说明和返回值说明。
2026-06-04 21:07:05 +08:00
xfy911
606c7b6b4e feat(http2): 添加 HTTP/2 目录浏览支持
- 新增 http2_serve_directory() 函数,生成 HTML 目录列表页面
- 目录无 index.html 时自动返回目录浏览(与 HTTP/1.1 行为一致)
- 支持 HTML 转义、文件大小格式化、修改时间显示、上级目录链接
- 支持 HEAD 请求(不发送 body)
- 新增 2 项集成测试:HTTPS h2 目录浏览 + h2c 目录浏览
- 54 项集成测试全部通过,35 个单元测试全部通过
2026-06-04 18:13:48 +08:00
xfy911
a93e9f32f5 feat(h2c): 添加明文 HTTP/2 升级支持
- server.c: 检测 PRI 魔术字直接连接 + Upgrade: h2c 协商
- server.c: 101 Switching Protocols 响应,正确会话生命周期管理
- http2.h/c: 新增 http2_session_upgrade() 注册 stream 1
- http2.c: 修复 nghttp2_session_upgrade2 head_request 参数误用
- tests: 新增 4 项 h2c 集成测试(prior knowledge、Upgrade、404)
- plan: 标记 h2c 完成,更新测试计数 52 项
2026-06-04 17:56:44 +08:00
xfy911
8a80ec9d96 docs(plan): 修正测试计数,单元测试 35 个 2026-06-04 16:21:48 +08:00
xfy911
158c2a894e docs(plan): HTTP/2 压缩已完成,更新待办池 2026-06-04 16:17:53 +08:00
xfy911
e9d7af80b8 feat(http2): HTTP/2 静态文件服务支持 gzip/brotli 压缩
- http2.c: 文件内容读取到内存后按需压缩(优先 brotli,回退 gzip)
- 响应头自动添加 content-encoding: br 或 gzip
- 不可压缩类型(图片等)跳过压缩
- 修复 curl 测试:添加 --compressed 自动解压
- 新增 4 项 HTTP/2 压缩集成测试(HTML/CSS/JS brotli、图片不压缩)
- 49 项集成测试全部通过,35 个单元测试全部通过
2026-06-04 16:15:29 +08:00
xfy911
2436218d3e docs(plan): 整理 Phase 3 完成状态,HTTP/2 完全可用 2026-06-04 15:51:12 +08:00
xfy911
094ae103ee feat(http2): 实现 HTTP/2 静态文件服务
- http2.c: 新增 http2_serve_static(),支持 GET/HEAD 请求
- 支持 304 缓存协商(If-None-Match / If-Modified-Since)
- 支持目录转 index.html、路径遍历防护
- 使用 nghttp2_data_provider 发送文件内容
- server.c: 创建 HTTP/2 会话后设置上下文(root_dir、压缩配置)
- 新增 6 项 HTTP/2 集成测试(ALPN 协商、GET/HEAD/404、缓存)
- 45 项集成测试 + 35 单元测试全部通过
2026-06-04 15:50:22 +08:00
xfy911
88c6597748 docs(plan): 更新 HTTP/2 完成状态,调整待办优先级 2026-06-04 15:47:16 +08:00
xfy911
22c9f74e76 feat(http2): 实现 HTTP/2 静态文件服务,修复 ALPN 协商与 send_callback 返回值
主要变更:
- http2.c: 实现完整的 HTTP/2 静态文件服务(GET/HEAD、路径安全、ETag、304 缓存)
- http2.c: 修复 :path 伪头长度解析 bug(4→5)和路径空终止问题
- http2.c: 修复 send_callback 返回值 bug(send_all 返回 0 而非已发送字节数)
- http2.c: 添加 If-None-Match / If-Modified-Since 缓存头解析
- http2.h: 扩展 http2_session_t 结构体,添加 root_dir/gzip/brotli 字段
- http2.h: 新增 http2_session_set_context() 接口
- server.c: 在 handle_http2() 中调用 set_context 传入连接配置
- tls.c: 实现 ALPN 选择回调,优先协商 h2 次选 http/1.1
- tls.c: 修正 ALPN 协议格式解析(长度前缀字符串序列)
- tests/integration_test.sh: 新增 6 项 HTTP/2 集成测试(ALPN、GET、HEAD、404、缓存)

集成测试:45 项全部通过(新增 6 项 HTTP/2 测试)
单元测试:127 项全部通过
2026-06-04 15:45:16 +08:00
xfy911
832ff3dbf6 docs(plan): 更新 HTTP/2 完成状态,调整待办优先级 2026-06-04 14:44:55 +08:00
xfy911
bc7505dc02 feat(http2): 集成 HTTP/2 到服务器主循环
- server.c: 添加 handle_http2() 函数,在 client_handler 中检测 HTTP/2 连接
- TLS ALPN 协商后自动创建 HTTP/2 会话
- HTTP/2 连接走独立处理路径(handle_http2),支持帧读写
- 连接清理时销毁 HTTP/2 会话
- tls.c: 新增 tls_negotiated_http2(),检查 ALPN 是否协商为 h2
- tls.h: 添加 tls_negotiated_http2() 声明
- 编译通过,39 项集成测试 + 127 单元测试全部通过
2026-06-04 14:43:39 +08:00
xfy911
42879cdafd docs(plan): 记录 HTTP/2 骨架完成状态 2026-06-04 14:40:27 +08:00
xfy911
6bb9635b2d feat(http2): 添加 HTTP/2 支持骨架(nghttp2)
- 新增 http2.c / http2.h:基于 nghttp2 的 HTTP/2 会话管理
- 支持 TLS ALPN 协商和明文 h2c 升级
- 流级请求/响应处理,集成现有 http_request_t 结构
- 编译通过,链接 -lnghttp2
- Makefile 更新:包含 http2.c 和 nghttp2 库链接
- 待完成:server.c 集成(ALPN 协商、h2c 升级检测)
2026-06-04 14:40:02 +08:00
xfy911
cffb433c1e docs(plan): 更新 TLS/HTTPS 完成状态,调整待办优先级 2026-06-04 14:36:16 +08:00
xfy911
7747ec921f feat(tls): 添加 TLS/HTTPS 支持
- 新增 tls.c/tls.h,使用 OpenSSL Memory BIO 与 coco 协程 I/O 集成
- 支持 TLS 1.2+,通过命令行 --cert/--key 或配置文件启用
- 所有静态文件、目录浏览、POST/文件上传功能均已支持 HTTPS
- 集成测试新增 TLS 握手 + HTTPS 响应验证
- 单元测试 127 项通过,集成测试 39 项通过
2026-06-04 12:50:28 +08:00
xfy911
8f9d420447 docs(plan): 更新发展规划,记录本轮测试扩展
- 单元测试总数:125 个(server 从 5→17)
- 更新待办池优先级和状态
2026-06-04 09:04:54 +08:00
xfy911
4a979a105f fix(api): 修正 COCOONForbidden 为 COCOON_FORBIDDEN
test(server): 扩展 server 单元测试覆盖(17个测试)

- 修复 cocoon.h 中 COCOONForbidden 拼写错误,统一为 COCOON_FORBIDDEN
- 新增 server 测试:
  - 空 root_dir 边界测试
  - port=0 和 port=65535 边界测试
  - 多线程配置测试
  - workers=0 自动检测测试
  - timeout 和 max_connections 配置测试
  - gzip/brotli 压缩标志测试
  - stop_then_destroy 生命周期测试
  - 多实例创建测试
  - server_start NULL 参数测试
- 单元测试总数:125 个(server 从 5→17)
- 集成测试 37 项全部通过
2026-06-04 09:03:55 +08:00
xfy(claw)
9041d8dfc4
Merge pull request #1 from xfy911/feature/windows-compat
docs(plan): 添加 Windows 兼容性任务及详细技术方案
2026-06-04 08:17:40 +08:00
xfy
ca7b33aa10 docs(plan): 添加 Windows 兼容性详细技术方案
- 描述目标:在 Windows 上编译运行 cocoon
- 分析核心发现:coco 库已有 Windows 支持,问题在 cocoon 的 POSIX 依赖
- 提出方案:引入 platform.h + platform.c 平台抽象层
- 列出关键 API 映射:POSIX → Windows 对照表
- 记录零拷贝策略:Windows 暂时回退到 read+send,后续用 TransmitFile 优化
- 指定执行方式:Subagent-Driven 逐个 Task 实现
2026-06-04 08:16:27 +08:00
xfy
0fd5ebc043 docs(plan): 在待办池中添加 Windows 兼容性任务
将 Windows 兼容性标记为 [高] 优先级,插入到待办池首位。
当前 cocoon 仅支持 Linux/macOS,Windows 支持是重要演进方向。
2026-06-04 08:16:11 +08:00
xfy911
ea5436febb feat(compression): 添加 Brotli 压缩支持,优先于 Gzip
- static.c: 新增 brotli_compress(),使用 libbrotlienc(质量 11,窗口 22)
- static_serve_file(): 优先 Brotli,回退 Gzip,二进制文件跳过
- http.c: 解析 Accept-Encoding: br,http_request_t 新增 accept_brotli
- cocoon.h: cocoon_config_t 新增 brotli_enabled(默认 true)
- config.c/h: 解析 brotli_enabled JSON 字段,config_merge() 新增 has_brotli_enabled
- main.c: --no-brotli 命令行选项
- server.c: 连接结构体新增 brotli_enabled
- Makefile: 链接 -lbrotlienc
- 单元测试: test_static.c 新增 4 个 Brotli 测试;test_config.c 新增 brotli 配置测试
- 集成测试: 新增 5 项 Brotli 测试(br 压缩、优先策略、图片不压缩)
- cocoon.json: 添加 brotli_enabled 字段
- README: 更新特性描述、curl 示例、命令行参数、路线图
- 113 个单元测试全部通过,37 项集成测试全部通过
2026-06-04 06:19:42 +08:00
xfy911
3801f3ac0d feat(config): 添加 JSON 配置文件支持 + gzip_enabled 控制 + README 修正
- config.c/config.h: 极简 JSON 解析器,支持数字/字符串/布尔//注释
- cocoon_config_t 新增 gzip_enabled 字段(默认 true)
- main.c: -c <file> 加载配置,--no-gzip 禁用压缩,命令行覆盖配置
- 修复 -r 参数 strdup 崩溃(避免 free 野指针)
- 修复 signal handler 双重 free 问题
- 单元测试: test_config.c 17 个测试全部通过
- 集成测试: 32 项全部通过
- README 修正过时描述(配置方式、安全设计、-v 说明)
2026-06-04 03:14:32 +08:00
xfy911
c036615d58 chore: 添加 test_server 到 gitignore + 更新待办池
- .gitignore: 补充 tests/unit/test_server,避免误提交编译产物
- .cocoon-plan.md: 新增 signal handler cleanup bug 和中文注释完善到待办池
2026-06-04 00:29:31 +08:00
xfy911
fb457e35ec test(server): 新增服务器核心 null 安全与生命周期测试
- test_create_null_config: NULL config 返回 NULL
- test_create_null_root_dir: 无 root_dir 提前返回 NULL
- test_stop_null / test_destroy_null: NULL 指针不 crash
- test_create_and_destroy: 正常创建+停止+销毁生命周期(高位端口避免冲突)
- Makefile: 添加 test_server 编译规则,链接全部依赖 + libcoco
2026-06-04 00:26:29 +08:00
xfy911
19c97ae6a9 test(config): 补充边界与异常路径测试
- test_load_invalid_field_type: 字段类型非法(port 为字符串),验证不 crash
- test_load_log_level_invalid: 非法 log_level 值保持默认 INFO
- test_load_nested_ignored: 嵌套对象——极简解析器返回 false 但不 crash
- test_load_array_ignored: 数组——同上,不 crash 即可
- test_merge_cmdline_null_root_dir: cmdline root_dir 为 NULL 时不覆盖 base
2026-06-04 00:24:29 +08:00
xfy911
c78086f2e5 test(log): 补充日志输出过滤与调用稳定性测试
- test_log_calls_no_crash: 直接调用 log_error/warn/info/debug 确认不崩溃
- test_log_level_filter: 用 pipe 重定向 stderr,验证 ERROR 级别下 INFO 被过滤、ERROR 正常输出
- 修复缺失 string.h 头文件警告
2026-06-04 00:23:10 +08:00
xfy911
e5bfc75d98 chore: 删除误提交的编译产物
- tests/unit/test_{config,http,log,static} 是编译生成的二进制文件
- 不应纳入版本控制,已通过 .gitignore 规避
2026-06-04 00:18:36 +08:00
xfy911
763e46d493 test(integration): 新增 POST/multipart 端到端测试
- 新增 curl 测试:multipart 文件上传、JSON 回显、表单回显
- 验证 uploads/ 目录创建和文件保存
- 补充现有测试的覆盖范围
2026-06-04 00:18:31 +08:00
xfy911
df8707ea69 test(multipart): 新增 multipart 解析单元测试
- test_multipart.c (Unity 框架):
  - test_extract_boundary: 提取带引号和不带引号的 boundary
  - test_parse_simple: 单文件上传解析
  - test_parse_multi: 多字段混合(文件 + 普通字段)
  - test_parse_empty: 空 body / 无效 boundary 的错误处理
- 覆盖正常/异常路径,验证内存正确释放
2026-06-04 00:18:25 +08:00
xfy911
8ee487f64d feat(multipart): 新增 multipart/form-data 解析模块
- multipart.h: 定义 multipart_part_t 结构体 + parse/extract_boundary/free API
- multipart.c: 轻量级解析器实现
  - find_line_end: 查找行尾(\n 或文件尾)
  - parse_content_disposition: 解析 name/filename 字段
  - multipart_parse: 两阶段解析(先计数再提取),跳过 preamble
  - multipart_extract_boundary: 从 Content-Type 提取 boundary 值
  - multipart_parts_free: 释放所有分配的字段内存
- 零外部依赖,仅使用标准库
2026-06-04 00:18:09 +08:00