改进 (http1): 在 req/header.go 中请求头解析的可靠性
说明
在审查 pkg/protocol/http1/req/header.go 中的 HTTP/1.1 请求头解析代码时,我发现了几个地方,通过防御性检查或小幅调整,可以使代码更加稳健且符合 RFC 规范。
发现的问题
1. parse() 在确认 ext.ReadRawHeaders() 成功之前先设置了 RawHeaders
parse() 第 131 行调用了 h.SetRawHeaders(rawHeaders),然后检查 ext.ReadRawHeaders() 是否返回了错误。当读取失败时,它在退出之前不必要地修改了头部状态。
https://GitHub.com/cloudwego/hertz/blob/main/pkg/protocol/http1/req/header.go#L130-L136
2. parseFirstLine() 中缺少了空缓冲区保护
当 buf 为空时,方法字符验证循环(for i, c := range buf) 变成了无效操作,并通过了。明确地添加 len(buf) == 0 保护使控制流立即变得明显,这是一种标准的防御性措施。
https://GitHub.com/cloudwego/hertz/blob/main/pkg/protocol/http1/req/header.go#L163-L176
3. ReadHeaderWithLimit() 中的 n=0 退化路径
当 r.Len() 返回 0 时,n 变为 0,并且下一个 tryReadWithLimit(h, r, 0, ...) 将读取 0 个字节(退化路径)。在 r.Len() 返回 0 时设置 n=1 可使读取器阻塞以等待输入数据,这是更清晰和正确的行为。
https://GitHub.com/cloudwego/hertz/blob/main/pkg/protocol/http1/req/header.go#L90
内容来源: cloudwego/hertz