科技 · 实用指南
curl 收到 100 或 103 仍报 Empty reply?检查最终响应
收到响应头不代表请求完整结束。6 组 curl 8.5.0 对照实验区分信息响应、合法空正文与错误 52。

HTTP/1.1 日志已经出现 100 Continue 或 103 Early Hints,最后仍可能报 curl: (52) Empty reply from server。我们的 curl 8.5.0 对照实验中,只发送 103 后关闭连接,保存了 71 字节响应头,response_code 为 103,但退出码仍是 52。响应头文件非空、状态码不是 000,都不能证明最终响应已经到达。
关键是信息响应后有没有最终响应,以及传输和预期业务结果是否完成。本文补充的是这个具体例外,承认现有空响应排障说明已经解决的基础问题;它不会仅凭错误码判断哪个组件中断了连接。
分别记录 HTTP 状态和进程退出码
先保留 curl --version、完整方法和 URL、运行环境、代理选择、错误原文与时间。对已获授权且无害的请求,将响应头和正文分开保存。例如 curl -sS -D response.headers -o response.body -w 'code=%{response_code} headers=%{size_header} body=%{size_download}\n' 'https://example.com/';随后立即保存 shell 退出状态,POSIX shell 可用 rc=$?。替换成真正要检查的端点,必要认证信息仅私下保留。
第一次对照不要把正文送入另一个程序,也不要用管道末尾命令的状态代替 curl 退出码。write-out 输出的 HTTP 状态与进程退出状态含义不同。示例没有添加 --fail,因此完整收到 HTTP 4xx/5xx 时 curl 仍可能退出 0,而业务依旧失败。必须检查真正的最终状态及预期内容。
按顺序读完每个响应块
RFC 9110 区分临时 1xx 响应与最终响应;RFC 8297 明确 103 的响应头提示不能替代最终响应头。阅读保存的全部响应块,不要看到第一条 HTTP 状态行就停止。对本问题而言,100 或 103 后断连,与 103 后又收到最终 200,是两种结果。
代理 CONNECT 响应及重定向历史也会产生多个响应块,所以要把请求方法、对端与顺序一起保留,不能把所有较早的响应都当作信息响应。100 Continue 反映请求进度,不能证明上传的业务动作已经完成;103 的 Link 只是提示,也不能证明被提示的资源或主请求已成功。
对照六组已知字节实验
我们用 Python 3.12.14 在 127.0.0.1 提供六组人工响应,先完整读走 GET 请求头,再有序关闭连接。客户端为 Ubuntu curl 8.5.0-2ubuntu10.13,使用 --http1.1、--noproxy '*'、两秒连接上限和三秒总时限。绕过代理仅用于隔离这个本地实验,不是要求绕过生产环境的必需代理。实验没有 TLS、应用服务器或中间代理。
完全不返回字节时,状态为 000、响应头和正文均为零、退出 52。最终 204 为状态 204、46 字节头、无正文、退出 0;最终 200 加 Content-Length: 0 为状态 200、57 字节头、无正文、退出 0。仅 100 的结果是状态 100、25 字节头、退出 52;仅 103 是状态 103、71 字节头、退出 52,二者均无正文。在同一个 103 后补上最终 200、Content-Length: 2 和正文 OK,结果变成状态 200、128 字节头、两字节正文、退出 0。仅 100 是故意不完整的解析器输入,不是正常的完整响应;精确字节数取决于本实验所选响应头。
定位最终响应在哪一段没有送达
OpenLiteSpeed 社区已有对应疑问:客户端收到了 100 后报 52,上游日志却记录 200。这个历史帖子证明用户确实遇到过这种困惑,不能据此认定当前产品仍有已确认缺陷。本地实验只复现客户端看见的响应形态,没有复现那个部署或其成因。
在你有权管理的系统中,用时间和请求标识关联同一次安全请求的客户端、代理和源站日志,核实哪一段记录了真实最终响应,哪一段确实向下游交付。源站日志出现 200,不等于这些字节已到 curl。务必保留实际构建版本;另一段 2026 年 curl-library 讨论涉及不同复现中的 52 与 56,不能保证不同版本和故障形态一定返回同一码。
用最终结果验收修复
只做一项范围明确、可撤销的修复后,在真实路径重跑预期的安全请求,同时要求最终状态符合预期、curl 传输完整、正文正确或确实合法为空。204 本来就没有响应内容;明确零长度 framing 的 200 也可以有效。这两者都不同于只收到信息响应块。
对上传或会改变状态的 API,重试前先核实业务动作是否已发生;错误 52 不能证明它没有发生。保留认证和证书校验,不要通过隐藏错误、增加无关超时或把 100/103 当完成来制造成功。无法确定责任边界时,提交脱敏后的有序响应块、退出码、构建版本及关联日志。
