症状
读取失败并报 unexpected EOF,而非干净的 EOF。它出现在大响应、慢链路或代理超时之后,而小负载不受影响。
诊断
区分正常结束与截断,并统计字节数:
n, err := io.Copy(dst, resp.Body)
log.Printf("copied=%d content-length=%d err=%v", n, resp.ContentLength, err)
若复制字节数小于 Content-Length,即确认正文被截断。
修复
检测短读并对幂等请求重试:
data, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("read body: %w", err) // surface unexpected EOF
}
if int64(len(data)) != resp.ContentLength {
return fmt.Errorf("short body: got %d want %d", len(data), resp.ContentLength)
}
验证
重复该请求,确认接收长度与 Content-Length 一致、校验和匹配。unexpected EOF 不再出现,任何截断都会抛出具象、可处理的错误。