症状
本篇指南处理“HTTP Content-Length 不匹配 — 响应被截断或多余”。请从症状出发,按顺序执行诊断,在推进前确认每个假设;随后通过修复与验证步骤闭环。
可观察到的症状包括:
- 客户端报 “premature end of Content-Length delimited message body”
- 下载被截断或在即将完成时挂起
- 处理器中手动设置 Content-Length 导致错误
诊断
先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。
步骤 1
curl -s -D - https://api.example.com/file -o out.bin && wc -c out.bin
实际大小与 Content-Length 头不同即证明不匹配。
步骤 2
grep -rn "Content-Length\|content-length" src/
手动设置长度是常见原因;应让框架自行计算。
常见诱因(按出现频率排序):
- 手动设置的 Content-Length 与实际字节数不符
- 处理器写入的字节多于或少于声明
- 代理重新压缩或截断字节却保留原长度
根因
存在 Content-Length 时,客户端会恰好读取该字节数。若服务端或代理发送的数量不同,客户端会报过早结束,或等待永不到达的字节。
修复
让 HTTP 层依据实际响应体计算 Content-Length,避免手动设置;对长度未知的流采用分块传输(省略 Content-Length),使客户端读到终止块为止。
注意:压缩与手动 Content-Length 组合是非法的;压缩中间件应在压缩后设置长度或使用分块。
// Express: let the framework set Content-Length from the body
res.json(payload); // length computed automatically
// streaming unknown-length response: use chunked (no Content-Length)
res.setHeader('Transfer-Encoding', 'chunked');
res.setHeader('Content-Type', 'text/event-stream');
stream.pipe(res); // ends with a terminating chunk
验证
重新下载并确认字节数与头一致;验证完整文件的哈希正确。
修复后补充一条回归测试,复现原始症状,防止问题再次出现。
这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。