HTTP 中端到端头和逐跳头有什么区别?Connection 头为什么特殊?
简化版
HTTP 头可以按传播范围分为端到端头和逐跳头。
端到端头会跟随请求或响应穿过代理传到最终接收方,例如 Content-Type、Cache-Control。逐跳头只对当前连接的下一跳有效,不能被代理原样转发,例如 Connection、Keep-Alive、Transfer-Encoding、Upgrade。
Connection 头特殊在于它还能声明哪些头是当前连接专用的,代理转发时必须移除。
详细版
端到端头:
Content-Type: application/json
Cache-Control: max-age=60
这些头描述资源、缓存或业务语义,应传到最终目标。
逐跳头:
Connection: keep-alive
Transfer-Encoding: chunked
Upgrade: websocket
这些头只和当前 TCP 连接或当前 HTTP hop 有关。
如果中间代理错误转发逐跳头,可能造成协议混乱、安全漏洞或连接管理异常。
所以代理必须识别并处理 Connection 指定的逐跳字段。
完整版教学
1. 先解释 hop 是什么
HTTP 请求从客户端到源站,中间可能经过多个代理。
Client -> CDN -> Nginx -> App
每一段连接都可以看作一个 hop。
逐跳头只在某一段连接上有意义。
端到端头则描述最终请求或响应语义,要传给最终接收方。
判断一个头是否逐跳,要问它描述的是资源语义,还是当前连接语义。
2. 端到端头的特点
端到端头会穿过代理。
例如:
Content-Type: application/json
Accept: application/json
Cache-Control: no-cache
ETag: "abc"
这些头与资源表示、缓存、内容协商有关。
代理可以根据协议规则处理它们,但通常不能因为换了一段连接就随便删除。
它们的目标是最终服务端或最终客户端。
3. 逐跳头的特点
逐跳头只对当前连接有效。
常见逐跳头包括:
Connection
Keep-Alive
Proxy-Authenticate
Proxy-Authorization
TE
Trailer
Transfer-Encoding
Upgrade
例如 Transfer-Encoding: chunked 描述当前连接上消息如何分块。
代理收到后,可以解码再重新编码给下一跳。
但它不能简单把所有连接级语义原样透传。
4. Connection 头的特殊作用
Connection 不只表示连接是否保持。
它还可以声明一些头字段只对当前连接有效。
Connection: keep-alive, X-Debug-Hop
X-Debug-Hop: abc
这里 X-Debug-Hop 也被声明为逐跳头。
代理转发给下一跳时,应移除 Connection 和其中列出的逐跳字段。
这是很多 HTTP 代理实现必须小心的地方。
5. 为什么错误转发有风险
如果代理把逐跳头错误传给后端,可能造成问题。
| 错误行为 | 可能后果 | 示例 |
|---|---|---|
| 转发 Connection 指定字段 | 后端误解连接语义 | 误把内部头当业务头 |
| 错转 Transfer-Encoding | 请求体解析异常 | 请求走私风险 |
| 错转 Upgrade | 协议升级混乱 | WebSocket 失败 |
| 错转 Proxy-Authorization | 凭证泄漏 | 代理认证信息外传 |
网络安全题里常提到的 HTTP Request Smuggling,就和消息边界解析差异有关。
6. HTTP/2 中的变化
HTTP/2 不再使用很多 HTTP/1.1 连接级头。
例如 HTTP/2 请求中不应出现 Connection 这类逐跳头。
因为 HTTP/2 的连接管理、多路复用和分帧机制不同。
从 HTTP/1.1 转 HTTP/2 的网关必须转换或移除不合法头。
这也是协议网关比普通反向代理更复杂的原因之一。
7. 常见误区与追问
- 误区:所有 HTTP 头都会一路传到后端。 逐跳头只对当前连接有效,代理应处理或移除。
- 误区:Connection 只控制 keep-alive。 它还能声明其他连接级头字段。
- 误区:Transfer-Encoding 是业务内容属性。 它描述当前连接传输编码,不是最终资源类型。
- 追问:为什么代理要移除 Connection 里列出的字段? 因为这些字段被声明为当前 hop 专用。
- 追问:端到端头能不能被代理修改? 有些可以按规则修改,但语义上目标是最终端点。
- 追问:HTTP/2 为什么禁止 Connection? HTTP/2 有自己的连接和流管理机制,不使用 HTTP/1.1 逐跳语义。
8. 加强记忆
端到端头跟资源走,逐跳头跟连接走。
看到 Connection,要想到“当前连接专用”和“代理转发要清理”。