cHttpClient 异步事件增强
日期: 2026-07-13 作者: 伟哥 + 小微
概述
为 cHttpClient 新增 4 个异步事件,支持重定向检测、响应进度追踪和超时识别,使异步模式具备与同步模式同等的可观测性。
新增功能
1. OnRedirect(url As String)
- 当
FollowRedirects = False且收到 3xx 状态码时触发 - 从响应头
Location字段提取目标 URL - 需要在 Fetch 前设置
.FollowRedirects = False,默认为 True
2. OnResponseStart(Status As Long, ContentType As String)
- WinHttp 原生事件,透传 Status 和 ContentType
- 额外解析
Content-Length头,为进度追踪提供 TotalBytes - 3xx 重定向检测:在禁用自动重定向时,解析 Location 头触发 OnRedirect
3. OnResponseDataAvailable(Data() As Byte, BytesReceived As Long, TotalBytes As Long)
- WinHttp 原生事件扩展,增加累计已接收字节数和总字节数
- BytesReceived 为累计值(非本次分片大小)
- TotalBytes 来自 Content-Length,未知时为 -1
- 可用于下载进度条实现
4. OnTimeout()
- WinHttp 错误码 12002 (ERROR_WINHTTP_TIMEOUT) 时触发
- 区分于普通 OnError,便于上层做重试逻辑
5. FollowRedirects 属性
- 布尔值,默认 True(保持原有行为)
- 设为 False 后,3xx 响应不会自动跟随,而是触发 OnRedirect 事件
- 内部通过
Inst.Option(6)控制 WinHttp 的 EnableRedirects 选项
修改文件
| 文件 | 变更 |
|---|---|
src/HttpClient/cHttpClient.cls | 新增 4 个 Event 声明、3 个成员变量、FollowRedirects 属性、事件处理实现 |
src/Collection/Dictionary.cls | Keys/Items 返回类型从 Variant() 改为 Variant(上一个 commit 的修复) |
关键设计决策
- OnRedirect 不是 WinHttp 原生事件:WinHttp 没有 OnRedirect,通过在 OnResponseStart 中检测 3xx + Location 头手动实现
- m_FollowRedirects 默认 True:不破坏现有代码,新功能 opt-in
- 异步超时仅 IsAsync 时设置:同步模式通过 WaitForResponse 控制,避免干扰
- OnTimeout 与 OnError 分离:12002 错误码走 OnTimeout 而非 OnError,便于不同处理策略
- 进度变量在 Fetch 开头重置:m_BytesReceived=0, m_TotalBytes=-1,CLEAN 段也重置
测试结果
编译 VBMAN.dll 成功(exit code 0),使用独立测试 EXE 验证:
=== Async Event Test ===
Time: 2026/7/13 0:03:22
[Test1] Async GET http://httpbin.org/get
[OnResponseStart] Status=200 ContentType=application/json
[OnResponseDataAvailable] 359/359 (100.0%)
[OnResponseFinished] Status=200 BodyLen=359
[Test1] PASS
[Test2] Async GET FollowRedirects=False http://httpbin.org/redirect/1
[OnRedirect] -> /get
[Test2] PASS- OnResponseStart: 状态码和 ContentType 正确传递
- OnResponseDataAvailable: 进度回调正常,BytesReceived/TotalBytes 计算正确
- OnRedirect: 302 响应中 Location 头正确解析
- OnTimeout: 未在自动测试中触发(需模拟超时场景)
遗留事项
- OnTimeout 事件需在模拟超时场景下补充测试
- 3xx 响应在 FollowRedirects=False 时也会触发 OnResponseFinished,上层需检查 StatusCode 做区分
AI生成