Skip to content

refactor(config): 删掉 14 个从未被读取的配置字段与 4 个假旋钮 API - #472

Merged
adam-ikari merged 1 commit into
mainfrom
refactor/config-dead-fields
Oct 11, 2026
Merged

adam-ikari merged 1 commit into
mainfrom
refactor/config-dead-fields

Conversation

@adam-ikari

Copy link
Copy Markdown
Owner

问题

uvhttp_config_t 原 26 个字段中,14 个从不被任何执行路径读取 —— 它们被 set_defaults 填默认值、被 validate 校验范围、被 print 打印,然后被整个库忽略。

三个公共 API 因此报告成功、打 INFO 日志、返回 OK,而对服务器行为零影响:

  • uvhttp_config_update_size_limits —— 写完 max_body_size/max_header_size 后打 Limits updated - Body: %zu -> %zu
  • uvhttp_set_timeout(builder)—— 写 request_timeout/keepalive_timeout
  • uvhttp_set_max_body_size(builder)—— 写 max_body_size
  • uvhttp_config_update_read_buffer_size —— 写 read_buffer_size

与 [[api-atomization-orthogonalization]] 记录的结论一致:这不是"配置可能失效",是必然失效且静默。

14 个字段的真实权威(逐字段核实)

字段 真正决定行为的
read_buffer_size 编译期 UVHTTP_READ_BUFFER_SIZE(connection.c:647)
max_body_size 编译期 UVHTTP_MAX_BODY_SIZE(request.c:308 / response.c:462,1170 / utils.c:79)
max_url_size MAX_URL_LEN 2048(request.h:60)
max_header_size 无任何实现
max_requests_per_connection 无任何实现(keep-alive 无上限)
request_timeout / keepalive_timeout config->connection_timeout(connection.c:1551-1553,二者是同一裁决者的两个别名)
rate_limit_window / _max_requests / _max_window_seconds / _min_timeout_seconds server->rate_limit_*(uvhttp_server_enable_rate_limit)
cache_default_max_entries / cache_default_ttl 编译期常量
lru_cache_batch_eviction_size 编译期常量

决策:删,而不是接上执行点

max_body_size 这类看起来"一条线就能接上",但 request body、response body、compress 阈值三条路径各自独立 —— 接一个留三个就是两套权威,正是本轮要治的病。需要可调时,把字段与读取它的代码一起加回来。

改动面

  • uvhttp_config_t 26 → 12 字段,set_defaults / validate / print 同步收敛
  • 4 个假旋钮 API 删除;头文件写下"字段要么权威要么不存在"的规则与 14 个字段的归属表
  • 11 组测试用例随 API 消失(validate 边界 / update API / 全字段)
  • ConfigSetDefaultsValid 强化为钉住存活 12 个字段的默认值 —— 它是清单守门人(变异验证:删掉任一默认值赋值 → 该用例变红)
  • 6 个示例改为只演示真实生效字段(原 helloworld / config_demo 把死字段当卖点演示并打印)
  • docs/spec/config-api.md 重写:14 字段"真实权威归属表" + 存活 12 字段的真实默认值/范围。该表改动前已失真:列了结构体里根本不存在的 max_headers / tcp_nodelay / tcp_keepalive
  • 中英文档 10 处配置示例同步(FAQ / performance / introduction / TUTORIAL 参数表 / PERFORMANCE_TESTING_STANDARD)

验证

  • ctest 119/119(main 基线构建,独立构建目录)
  • 变异测试:删任一默认值赋值 → ConfigSetDefaultsValid 红
  • cppcheck(CI 同参数)零告警;test-validity 门禁 PASS
  • examples 全量构建通过;门禁口径内文件 clang-format 18.1.8 合规

迁移

  • 设 request_timeout / keepalive_timeout 的 → 改设 connection_timeout(5-300 秒)
  • 设 max_body_size / read_buffer_size / max_url_size 的 → 改为编译期常量(uvhttp_constants.h)或自行在应用层限流
  • 设 rate_limit_* 的 → 改走 uvhttp_server_enable_rate_limit()
  • uvhttp_config_set_cache_config(shared)经 uvhttp_static_set_cache_config 的用法不变

v2.10 roadmap d2(配置静默失效全线)。核实结论:`uvhttp_config_t` 原 26 个
字段中 14 个从不被任何执行路径读取 —— 它们被 set_defaults 填默认值、被
validate 校验范围、被 print 打印,然后被整个库忽略。

三个公共 API 报告成功、打 INFO 日志,对服务器行为零影响:
- uvhttp_config_update_size_limits:写 max_body_size/max_header_size 后打
  "Limits updated - Body: %zu -> %zu"
- uvhttp_set_max_body_size(builder):写 max_body_size,返回 builder
- uvhttp_set_timeout(builder):写 request_timeout/keepalive_timeout
- uvhttp_config_update_read_buffer_size:写 read_buffer_size

这些字段的真实权威(逐个核实):
- read_buffer_size  → 编译期 UVHTTP_READ_BUFFER_SIZE(connection.c:647)
- max_body_size    → 编译期 UVHTTP_MAX_BODY_SIZE(request.c:308 等 4 处)
- max_url_size     → MAX_URL_LEN 2048(request.h:60)
- max_header_size  → 无任何实现
- max_requests_per_connection → 无任何实现(keep-alive 无上限)
- request_timeout / keepalive_timeout → config->connection_timeout
  (connection.c:1551-1553,二者是同一裁决者的两个别名)
- rate_limit_* 四项 → server->rate_limit_*(uvhttp_server_enable_rate_limit)
- cache_default_max_entries / cache_default_ttl → 编译期常量
- lru_cache_batch_eviction_size → 编译期常量

取舍:删而非接。max_body_size 看似一条线就能接上,但 request body、
response body、compress 阈值三条路径各自独立,接一个留三个就是"两套权威"
—— 正是本轮要治的病。需要可调时,把字段与读取它的代码一起加回来。

改动面:
- uvhttp_config_t 26 → 12 字段,validate/print/set_defaults 同步收敛
- 4 个假旋钮 API 删除,头文件补"字段要么权威要么不存在"的规则说明
- 11 个测试用例组(validate 边界 / update API / 全字段用例)随 API 消失
- ConfigSetDefaultsValid 强化为钉住**存活** 12 个字段的默认值 —— 它是那份
  清单的守门人:字段增减必须与"谁读它"同步
- 6 个示例改为只演示真实生效的字段(原先 helloworld/config_demo 把死字段
  当卖点演示并打印)
- docs/spec/config-api.md 重写:列出 14 字段的"真实权威归属表" + 存活 12
  字段的真实默认值/范围(该表改动前就已失真:列了结构体里根本不存在的
  max_headers / tcp_nodelay / tcp_keepalive)
- 中英文档 10 处配置示例同步(FAQ / performance / introduction /
  TUTORIAL 参数表 / PERFORMANCE_TESTING_STANDARD)

顺带修一个既有 ASan 泄漏(与本次配置改动无关,但会卡住 ASan release 门禁):
test_server_simple_handlers_coverage 的 GetHeader 用例在 #455 改成用
uvhttp_request_add_header 构造可查询 header 后,没有释放它堆分配的
headers_extra —— request 本身在栈上,不会有人替你调析构。main 上即复现。

验证:ctest 120/120(含 ASan 全量);cppcheck(CI 同参数)零告警;
test-validity 门禁 PASS(零断言测试新增 0);examples 全量构建通过;
本 PR 触达的 src/include/test 文件 clang-format 18.1.8 全合规(release
门禁口径)。
@adam-ikari
adam-ikari force-pushed the refactor/config-dead-fields branch from 68fb2a7 to 0ab35f8 Compare October 11, 2026 04:23
@adam-ikari
adam-ikari merged commit d257c92 into main Oct 11, 2026
10 checks passed
@adam-ikari
adam-ikari deleted the refactor/config-dead-fields branch October 11, 2026 04:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant