1
0
Files
DiAL/openspec/specs/http-checker/spec.md
lanyuanxiaoyao cfca03b4d6 refactor: 规范审查与重组,合并细粒度规范,清理过时内容
- 合并 20+ 细粒度 spec 为粗粒度主题规范:dashboard、data-store、probe-engine、probe-api、probe-config 等
- 删除完全冗余规范:data-retention(被 probe-engine+data-store 覆盖)、backend-code-quality(DEVELOPMENT.md 已记录)
- 补充 http-checker 规范至完整标准(配置+执行+expect+校验+observation),匹配代码 440 行实现
- 清理 tcp/udp/llm checker 规范中已废弃 defaults 配置段的残留 Scenario
- 清理 checker-cohesion-structure 中的实现路径引用(src/server/...)
- 统一所有 spec 格式(## Purpose 开头,去除 # Capability/Title 形式)
- 更新 prompt-spec-review.md 审查提示文档
2026-05-22 18:55:18 +08:00

197 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Purpose
定义 HTTP 类型拨测目标:通过 `type: http` 配置 HTTP/HTTPS 探测支持请求方法、headers、body、SSL 校验、重定向和响应体大小限制,捕获 HTTP 状态码、响应头、响应体和执行耗时,按 expect 规则校验并生成 matched 判定。
## Requirements
### Requirement: HTTP target 配置
系统 SHALL 支持 `type: http` 的 target 配置,通过 `http.url` 描述目标 HTTP 地址并通过可选字段控制请求方法、请求体、headers、SSL 校验、重定向和响应体大小限制。
#### Scenario: 解析最简 HTTP target
- **WHEN** YAML 中 target 配置 `type: http``http.url: "https://example.com"`
- **THEN** 系统 SHALL 将其解析为 HTTP checker并填充 `method=GET``maxBodyBytes=100MB``ignoreSSL=false``maxRedirects=0`、headers、body、interval、timeout、group 和 expect 配置
#### Scenario: HTTP target 缺少 url
- **WHEN** YAML 中 target 配置 `type: http` 但缺少 `http.url`
- **THEN** 系统 SHALL 以配置错误退出,并提示该 target 缺少 http.url 字段
#### Scenario: HTTP target 覆盖请求方法
- **WHEN** YAML 中某个 HTTP target 显式配置 `http.method: POST`
- **THEN** 该 target SHALL 使用自身 method 字段的值,而不是内置默认值 GET
#### Scenario: HTTP target 覆盖响应体大小限制
- **WHEN** YAML 中某个 HTTP target 显式配置 `http.maxBodyBytes`
- **THEN** 该 target SHALL 使用自身 maxBodyBytes 字段的值,而不是内置默认值 100MB
#### Scenario: HTTP target 覆盖 headers
- **WHEN** YAML 中某个 HTTP target 显式配置 `http.headers`
- **THEN** 该 target SHALL 使用自身 headers 字段的值
#### Scenario: HTTP target 配置 ignoreSSL
- **WHEN** YAML 中 HTTP target 设置 `http.ignoreSSL: true`
- **THEN** 系统 SHALL 解析该字段并在执行时跳过 SSL 证书校验
#### Scenario: HTTP target 配置 maxRedirects
- **WHEN** YAML 中 HTTP target 设置 `http.maxRedirects: 5`
- **THEN** 系统 SHALL 解析该字段并在执行时允许最多跟随 5 次重定向
#### Scenario: HTTP 序列化展示摘要
- **WHEN** 系统同步 HTTP target 到 targets 表
- **THEN** `target` 展示摘要 SHALL 为 HTTP URL`config` JSON SHALL 包含 resolved 后的 url、method、headers、body、ignoreSSL、maxBodyBytes 和 maxRedirects
### Requirement: HTTP checker 执行
系统 SHALL 按 HTTP target 配置发起 HTTP 请求,使用引擎注入的 `ctx.signal` 响应超时。系统 SHALL 支持手动重定向跟随(`redirect: "manual"`),在 `maxRedirects` 限制内跟随 301/302/303/307/308 重定向。系统 SHALL 记录完整执行耗时和 HTTP observation并在网络错误、超时、响应体超限或字符编码不支持时产生结构化失败信息。
#### Scenario: HTTP 请求成功
- **WHEN** HTTP target 指向可正常响应的 HTTP 服务,且未配置 expect 或 `expect.status``[200]`
- **THEN** 系统 SHALL 记录 `matched=true``durationMs` 和包含 statusCode、headers、bodyPreview、contentType、contentLength 的 observation
#### Scenario: 使用 ctx.signal 响应超时
- **WHEN** 引擎注入的 `ctx.signal` 在 HTTP 请求过程中 abort
- **THEN** 系统 SHALL 记录 `matched=false`observation SHALL 为 nullfailure 的 kind 为 `error`phase 为 `request`message 包含超时信息
#### Scenario: 网络错误
- **WHEN** HTTP 请求因网络错误DNS 解析失败、连接被拒绝等)失败
- **THEN** 系统 SHALL 记录 `matched=false`observation SHALL 为 nullfailure 的 kind 为 `error`phase 为 `request`
#### Scenario: 重定向跟随
- **WHEN** HTTP target 配置 `http.maxRedirects: 3` 且服务端返回 301/302/303/307/308 重定向
- **THEN** 系统 SHALL 在 maxRedirects 限制内自动跟随重定向,并返回最终响应供 expect 校验
#### Scenario: 重定向次数耗尽
- **WHEN** HTTP target 配置 `http.maxRedirects: 1` 且服务端返回超过 1 次重定向
- **THEN** 系统 SHALL 将最后一次重定向响应作为最终结果返回,不继续跟随
#### Scenario: POST 重定向为 GET
- **WHEN** HTTP target 使用 POST 方法且收到 301 或 302 重定向,或收到 303 重定向
- **THEN** 系统 SHALL 将后续请求方法改为 GET移除 Content-Type 和 Content-Length 请求头,并移除 body
#### Scenario: 跨域重定向移除敏感头
- **WHEN** 重定向到不同 origin 的目标
- **THEN** 系统 SHALL 移除 Authorization 和 Cookie 请求头
#### Scenario: 响应体读取与大小限制
- **WHEN** HTTP target 配置了 body expect 且响应体未超过 `maxBodyBytes`
- **THEN** 系统 SHALL 读取完整响应体,按 Content-Type 字符编码解码,并用于 body expect 校验
#### Scenario: 响应体超过大小限制
- **WHEN** HTTP target 配置了 body expect 且响应体超过 `maxBodyBytes`
- **THEN** 系统 SHALL 停止读取,记录 `matched=false`failure 的 kind 为 `error`phase 为 `body`message 包含响应体超过大小限制的信息
#### Scenario: 不支持的字符编码
- **WHEN** HTTP 响应的 Content-Type 指定了不支持的 charset
- **THEN** 系统 SHALL 记录 `matched=false`failure 的 kind 为 `error`phase 为 `body`message 包含不支持的字符编码信息
#### Scenario: 无 body expect 时不读取响应体
- **WHEN** HTTP target 未配置 `expect.body` 或 body expect 为空数组
- **THEN** 系统 SHALL NOT 读取响应体内容bodyPreview SHALL 为 null
#### Scenario: GET/HEAD 请求不发送 body
- **WHEN** HTTP target 配置 `http.method: GET``http.method: HEAD`
- **THEN** 系统 SHALL NOT 发送请求体,即使配置了 `http.body`
### Requirement: HTTP expect 校验
系统 SHALL 支持 HTTP 专属 expect包括 `status``headers``body``durationMs`,并按 status、headers、early-timeout仅当配置了 body expect 时、body、durationMs 的阶段顺序快速失败。`status` SHALL 保持状态码数组语义支持精确数字100-599和范围模式`1xx``5xx`),未配置时在 Resolved expect 中默认 `[200]``headers` SHALL 使用共享 `RawKeyedExpectations` 输入并在运行期使用 `KeyedExpectations`header key 大小写不敏感。`body` MUST 使用共享 `RawContentExpectations` 数组输入并在运行期使用 `ContentExpectations`,支持直接 ValueMatcher 以及 json/css/xpath 提取器。`durationMs` SHALL 使用共享 `RawValueExpectation` 输入并在运行期使用 `ValueExpectation` 校验完整执行耗时。
#### Scenario: 默认 status 成功语义
- **WHEN** HTTP target 未显式配置 `expect.status`
- **THEN** 系统 SHALL 在 Resolved HTTP expect 中使用默认 `status: [200]` 进行校验
#### Scenario: status 精确值匹配
- **WHEN** HTTP target 配置 `expect.status: [200, 201]` 且响应状态码为 201
- **THEN** 系统 SHALL 判定 status 阶段通过,继续后续 expect 阶段
#### Scenario: status 范围模式匹配
- **WHEN** HTTP target 配置 `expect.status: ["2xx"]` 且响应状态码为 204
- **THEN** 系统 SHALL 判定 status 阶段通过
#### Scenario: status 不匹配快速失败
- **WHEN** HTTP target 配置 `expect.status: [200]` 且响应状态码为 500
- **THEN** 系统 SHALL 立即返回 `matched=false`failure 的 phase 为 `status`
#### Scenario: headers 校验通过
- **WHEN** HTTP target 配置 `expect.headers: {Content-Type: {contains: "application/json"}}` 且响应包含对应 header
- **THEN** 系统 SHALL 判定 headers 阶段通过header key 匹配大小写不敏感
#### Scenario: headers 校验失败
- **WHEN** HTTP target 配置 `expect.headers: {X-Custom: {exists: true}}` 且响应不包含该 header
- **THEN** 系统 SHALL 返回 `matched=false`failure 的 phase 为 `headers`
#### Scenario: body ContentExpectations 校验通过
- **WHEN** HTTP target 配置 `expect.body: [{contains: "ok"}, {json: {path: "$.status", equals: "success"}}]` 且响应体满足全部条件
- **THEN** 系统 SHALL 判定 body 阶段通过
#### Scenario: body ContentExpectations 快速失败
- **WHEN** HTTP target 配置两条 body expectation 且第一条失败
- **THEN** 系统 SHALL 返回第一条失败 expectation 的 failurephase 为 `body`,并 MUST NOT 执行第二条 expectation
#### Scenario: body 非 JSON 响应触发 JSONPath 失败
- **WHEN** HTTP target 配置 json body expectation 但响应体不是合法 JSON
- **THEN** 系统 SHALL 记录 `matched=false`failure 的 kind 为 `error`phase 为 `body`
#### Scenario: early-timeout 快速失败
- **WHEN** HTTP target 配置了 body expect 和 `expect.durationMs: {lte: 500}`,且请求状态码和 headers 通过后已耗时超过 500ms
- **THEN** 系统 SHALL 在读取响应体之前判定 durationMs 超限,不读取响应体,直接返回 `matched=false`failure 的 phase 为 `duration`
#### Scenario: durationMs 校验
- **WHEN** HTTP target 配置 `expect.durationMs: {lte: 1000}` 且完整执行耗时超过 1000ms
- **THEN** 系统 SHALL 返回 `matched=false`failure 的 phase 为 `duration`
### Requirement: HTTP checker 启动期配置校验
系统 SHALL 在启动期对 HTTP checker 的配置契约和语义执行严格校验。HTTP target 的 `http` 分组 SHALL 只允许 `url``method``headers``body``ignoreSSL``maxBodyBytes``maxRedirects` 字段。HTTP expect SHALL 只允许 `status``headers``body``durationMs` 字段。未知字段、非法类型、非法 URL 协议、非法 status 值、非法 maxBodyBytes、非法 ContentExpectations 和不可编译正则 MUST 导致启动期配置错误。语义校验 MUST NOT 修改 Raw HTTP expect 输入。
#### Scenario: http.url 为空字符串
- **WHEN** YAML 中 HTTP target 配置 `http.url: ""`
- **THEN** 系统 SHALL 以配置错误退出,提示缺少 http.url 字段
#### Scenario: http.url 协议非法
- **WHEN** YAML 中 HTTP target 的 `http.url` 不以 `http://``https://` 开头
- **THEN** 系统 SHALL 以配置错误退出,提示 URL 格式不合法
#### Scenario: http.url 格式非法
- **WHEN** YAML 中 HTTP target 的 `http.url` 不是合法 URL
- **THEN** 系统 SHALL 以配置错误退出,提示 URL 格式不合法
#### Scenario: http.maxBodyBytes 格式非法
- **WHEN** YAML 中 HTTP target 的 `http.maxBodyBytes` 不是合法 size 值
- **THEN** 系统 SHALL 以配置错误退出,提示 maxBodyBytes 格式错误
#### Scenario: http 分组未知字段失败
- **WHEN** YAML 中 HTTP target 的 `http` 分组包含未知字段
- **THEN** 系统 SHALL 以配置错误退出,提示 http 分组包含未知字段
#### Scenario: expect.status 数字非法
- **WHEN** YAML 中 HTTP target 的 `expect.status` 包含非整数或不在 100-599 范围内的数字
- **THEN** 系统 SHALL 以配置错误退出,提示 status 数字不合法
#### Scenario: expect.status 模式非法
- **WHEN** YAML 中 HTTP target 的 `expect.status` 包含不符合 `1xx``5xx` 格式的字符串
- **THEN** 系统 SHALL 以配置错误退出,提示 status 模式不合法
#### Scenario: expect.body 必须为数组
- **WHEN** YAML 中 HTTP target 的 `expect.body` 已配置但不是数组
- **THEN** 系统 SHALL 以配置错误退出,提示 expect.body 必须为数组
#### Scenario: HTTP expect 未知字段失败
- **WHEN** YAML 中 HTTP target 的 expect 包含 `connected``exitCode``maxDurationMs` 或其他非 HTTP expect 字段
- **THEN** 系统 SHALL 以配置错误退出,提示 expect 包含未知字段
### Requirement: HTTP observation 与 detail
HTTP checker SHALL 在 observation 中记录 statusCodenumber、headersRecord<string, string>,截断至前 20 个、bodyPreviewstring | null截断至前 1024 字符、contentTypestring | null、contentLengthnumber | null。API detail SHALL 由 `buildDetail` 从 observation 动态构造,格式为 `HTTP {statusCode}`。网络错误或超时导致无法收集 observation 时observation SHALL 为 nulldetail SHALL 为 null。
#### Scenario: 正常响应 observation
- **WHEN** HTTP 请求成功返回
- **THEN** observation SHALL 包含 statusCode、截断后的 headers、截断后的 bodyPreview、contentType 和 contentLength
#### Scenario: 未读取响应体时 bodyPreview 为 null
- **WHEN** HTTP target 未配置 body expect
- **THEN** observation.bodyPreview SHALL 为 null
#### Scenario: 请求失败 observation 为 null
- **WHEN** HTTP 请求因网络错误或超时失败
- **THEN** observation SHALL 为 nulldetail SHALL 为 null
#### Scenario: detail 格式
- **WHEN** API 序列化 HTTP CheckResult
- **THEN** detail SHALL 为 `HTTP {statusCode}` 格式(如 `HTTP 200`