dsh-http-client
v0.3.0
Published
Guarded HTTP client for DeepSeek Harness: domain allowlist, timeout, retry with backoff, response size cap, response-header whitelist. Only whitelisted hosts are reachable.
Readme
dsh-http-client
受控 HTTP 客户端插件(v0.3.0):让模型能调外部 API,但只能在明确划定的安全边界内。
安装
npm install dsh-http-client工具
http_get / http_post
| 参数 | 类型 | 说明 |
|------|------|------|
| url | string | 必填,完整 http(s) URL |
| body | string | POST 必填,请求体字符串(JSON 配 Content-Type: application/json) |
| headers | object | 可选,请求头 |
| timeout_ms | number | 可选,默认 15000,上限 60000 |
| allow_unlisted | boolean | 可选,主机不在白名单时首次放行并写入白名单文件 |
| retries | integer | 可选,失败重试次数,默认 0(不重试),上限 5 |
| retry_delay_ms | number | 可选,首次退避间隔,默认 300,上限 10000 |
| retry_backoff | string | 可选,exponential(默认,逐次翻倍)/ fixed(固定间隔) |
| headers_filter | string[] | 可选,echo_headers=true 时输出的响应头名称;省略用默认白名单,传 ["*"] 输出全部(上限 20 条) |
使用步骤
1. 配置域名白名单
插件读取工作目录下的 .http-allowlist.json,两种初始化方式:
方式 A:手动预配置(推荐,先划好边界)
{
"allow": [
"api.github.com",
"open.bigmodel.cn",
"*.deepseek.com"
]
}- 精确匹配:
api.github.com只放行这个子域 - 通配匹配:
*.deepseek.com放行所有子域(不含裸域deepseek.com,需要就两条都写)
方式 B:首次放行逐步累积——不预配置,调用时传 allow_unlisted: true,确认后自动把域名写进白名单文件,之后免确认。
2. 调用示例
GET 拉取数据:
http_get({ url: "https://api.github.com/zen" })POST 提交 JSON:
http_post({
url: "https://api.example.com/v1/notify",
headers: { "Content-Type": "application/json", "Authorization": "Bearer <token>" },
body: "{\"title\": \"构建完成\"}"
})3. 解读返回结果
每次调用返回固定结构:
URL: https://api.github.com/zen
状态: 200 OK
响应大小: 87 字节
白名单: api.github.com 在白名单内(共 3 条)
<body 内容>注意两个截断标记:[响应体超过 1024KB 上限,已截断](body 本身被砍)和 [输出已截断,完整长度 N 字符](返回给模型的文本被砍)。出现任一说明数据不完整,应缩小请求范围。
4. 重试与响应头输出
重试(默认关闭,按需开启):
http_get({ url: "...", retries: 3, retry_delay_ms: 500, retry_backoff: "exponential" })- 只对超时、网络错误和
408 / 425 / 429 / 500 / 502 / 503 / 504重试;4xx 里的 404、403 等不重试(重试无意义) - 退避间隔:
exponential为300 → 600 → 1200...(受 10s 上限约束),fixed则固定不变 - 响应带
Retry-After时优先遵循该头(限流场景的关键,避免盲目重试被持续拒绝) - 重试次数与上次失败原因会写进返回的元信息:
重试: 共尝试 2 次(上次失败: HTTP 503)
响应头白名单:echo_headers=true 时默认只回与结果相关的头(content-type、content-length、cache-control、etag、last-modified、location、retry-after、x-request-id 等),避免 set-cookie 之类的噪音与敏感信息进入上下文。需要看别的头时显式指定,或传 ["*"] 看全部:
http_get({ url: "...", echo_headers: true, headers_filter: ["x-ratelimit-remaining", "x-request-id"] })5. 日常维护
- 加域名:直接编辑
.http-allowlist.json,或让模型allow_unlisted放行 - 临时收回:从白名单删掉条目即可,立即生效(每次调用都重新读文件)
- 审计:白名单文件就是完整的信任域清单,定期过一遍即可
推荐工作流:项目里放一份只含必要 API 域名的白名单提交进 git,团队共享同一套边界;新需求碰到未覆盖域名时由使用者显式确认放行。
安全边界(本插件的核心)
- 域名白名单:工作目录
.http-allowlist.json({"allow": ["api.example.com", "*.example.com"]});白名单文件损坏时按空白名单处理(fail closed) - 首次放行机制:不在白名单的主机默认拒绝;
allow_unlisted=true时追加到白名单文件,之后无需重复确认 - 禁止 IP 直连:白名单基于域名,
http://192.168.1.1直接拒绝 - 禁止 userinfo:
http://user:pass@host拒绝 - 端口限制:远程主机仅允许 80/443(localhost 例外,方便本地开发调试)
- 超时:默认 15s,上限 60s,超时中止
- 响应体上限 1MB:流式读取,超限立即中止并标注截断
- 输出截断:返回给模型的文本超 8000 字符再截断,两道截断标记都保留在末尾
- 零依赖:基于 Node 内置
fetch,无第三方 HTTP 库
测试
npm test测试在本地临时 http 服务器上进行(localhost 任意端口的例外设计使然),覆盖白名单匹配/放行/持久化、5 类恶意 URL 拒绝、POST、超时、双重截断、重定向跟随、重试与退避、Retry-After 优先、响应头白名单筛选、重试参数校验,共 49 项断言。
版本历史
0.3.0(2026-09-30)
- 重试策略参数化:
retries/retry_delay_ms/retry_backoff(指数或固定退避),仅对超时、网络错误与 408/425/429/5xx 生效 - 响应
Retry-After优先于退避参数,避免限流下盲目重试 - 响应头白名单输出:
echo_headers默认只回相关头,headers_filter可指定名称或传["*"]输出全部 - 限速补上 localhost 例外(与文档一致,本地调试不再被同步等待阻塞)
0.2.0(2026-09-13)
- http_request 支持 PUT / DELETE / PATCH 方法
- 新增 echo_headers 工具:回显响应头,便于调试鉴权与跨域配置
- 进程内限速:rateLimitMs 可配置(默认 1000ms,localhost 例外)
- 204 空响应体兼容修复
Roadmap(v0.4 候选)
- multipart/表单上传支持
- 响应缓存(同 URL 短时复用,减少重复请求)
源码与发布地址
- 源码:https://github.com/geeklei/dsh-plugins/tree/main/dsh-http-client
- npm:https://www.npmjs.com/package/dsh-http-client
典型场景
1. 接口连通性排查
用户:这个接口能通吗、返回什么
http_get 发起请求并返回状态码、响应头与响应体摘要。
2. 提交表单/JSON
用户:帮我 POST 一段 JSON 到这个地址
http_post 发送请求体,返回服务端响应。
3. 自定义方法与请求头
用户:用 PUT 带上 Authorization 调一下
http_request 支持自定义 method/headers/body。
4. 与代理相关的网络问题定位
用户:为什么请求超时
先用 dsh-env-inspector 核对代理环境变量,再用本插件验证请求路径。
5. 响应内容进一步处理
用户:返回的 JSON 里某个字段是什么
把响应体交给 dsh-json-yaml-toolkit 的 query_json 提取。
其他插件集成说明
| 协作插件 | 集成方式 |
|---|---|
| dsh-json-yaml-toolkit | 响应 JSON 用 query_json 提取字段、convert_format 转 YAML |
| dsh-env-inspector | 请求异常时先核对代理/环境变量 |
| dsh-hash-checksum | 下载内容落盘后计算摘要,形成下载校验闭环 |
| dsh-base64-codec | 请求体需编码(base64/url)时先用本插件编码 |
| dsh-markdown-lint | 抓取网页/文档后检查其中链接可达性(check_http_links) |
FAQ
Q:会带上我的凭据吗?
只在显式传入 headers(如 Authorization)时携带,不会自动读取环境中的 token。
Q:超时怎么设置? 请求支持超时参数;超时后返回明确错误而不是无限等待。
Q:能下载二进制文件吗? 可以获取响应,但建议把二进制内容落盘后用 dsh-hash-checksum 校验,而不是在对话中展示。
Q:重定向会跟随吗? 默认跟随有限次数的重定向,并会报告最终 URL,便于发现跳转异常。
Q:为什么内网地址失败? 请确认代理环境变量(NO_PROXY 等)配置;用 dsh-env-inspector 核对最直接。
