HTTP Hop-by-Hop请求
什么是Hop-by-Hop请求头
在HTTP协议中,传输层和应用层之间存在多种类型的请求和响应头(Headers)。其中有一类头部被称为"Hop-by-Hop"请求头,这些头部在HTTP请求和响应链中每个节点(即每个代理服务器或网关)之间传递,而不是端到端传递。这意味着这些头部在传递过程中会被中间代理服务器处理、修改或移除,而不会被直接传递到最终的接收者。
翻看相关的HTTP协议标准,
- https://datatracker.ietf.org/doc/html/rfc2616#page-92
- https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-p1-messaging-14#section-7.1.3
会看到如下相关描述:
For the purpose of defining the behavior of caches and non-caching proxies, we divide HTTP header fields into two categories:
- End-to-end header fields, which are transmitted to the ultimate recipient of a request or response. End-to-end header fields in responses MUST be stored as part of a cache entry and MUST be transmitted in any response formed from a cache entry.
- Hop-by-hop header fields, which are meaningful only for a single transport-level connection, and are not stored by caches or forwarded by proxies.
有两个主要的方面需要注意:
-
Hop-by-hop 头部列表:代理服务器必须移除或自行处理hop-by-hop头部,并且不能将其传递给下一个节点。
-
Connection 头部:Connection头部包含了其他自定义的hop-by-hop头部的列表,告诉接收者这些头部不能被转发。
根据 HTTP/1.1 规范,Hop-by-Hop 头部只在两个直接相连的节点之间传递,不应在代理链条上透传。这些头部通常用于控制连接行为,例如连接保持活跃,如果传递下去可能会引起意想不到的问题或者不必要的负担。
常见的Hop-by-Hop请求头
- Connection:指定HTTP连接选项,该头部通常指定某些头部是Hop-by-Hop头部。
- Keep-Alive:与持久连接有关的参数,如超时和最大请求数。
- Proxy-Authenticate:与代理身份验证相关的信息。
- Proxy-Authorization:提供客户端发送给代理服务器的认证凭据。
- TE:表示传输编码的愿望,但不会在最终响应中传递。
- Trailer:指定在分块传输编码中,响应消息末尾会有的头部集合。
- Transfer-Encoding:指定如果请求消息被中间节点压缩过,将以哪个编码传输。
- Upgrade: 用于升级协议,例如从HTTP/1.1升级到WebSocket。
示例
以下是一个带有Hop-by-Hop头部的HTTP请求示例:
GET /example HTTP/1.1
Host: www.example.com
Connection: keep-alive
Keep-Alive: timeout=5, max=1000
在这个例子中:
Connection
头部指定了当前连接应保持活跃状态。Keep-Alive
头部提供了更多关于保持连接活跃的信息,例如超时和最大请求数。
在反向代理服务器中的支持和表现
1. Nginx
-
默认行为: Nginx默认会自动移除Hop-by-Hop头部,确保这些头部不会传递给下一个节点。
-
自定义处理: 可以通过
proxy_set_header
指令显式地设置或移除特定的头部,如下所示:server { listen 80; server_name example.com; location / { proxy_pass http://upstream_server; # 删除 Hop-by-Hop headers proxy_set_header Connection ""; proxy_set_header Keep-Alive ""; proxy_set_header Proxy-Authenticate ""; proxy_set_header Proxy-Authorization ""; proxy_set_header TE ""; proxy_set_header Trailer ""; proxy_set_header Transfer-Encoding ""; proxy_set_header Upgrade ""; # 添加或者修改其他所需headers proxy_set_header X-Request-ID $request_id; } }
通过这些配置,你可以确保代理请求中不会包含这些 Hop-by-Hop 头部,从而避免对下游服务器产生不必要的影响。
2. Apache HTTP Server
- 默认行为: Apache HTTP Server通过
mod_proxy
模块处理反向代理请求时,会自动移除Hop-by-Hop头部。 - 自定义处理: 可以通过Apache配置指令(如
ProxyPass
和ProxyPassReverse
)自定义头部行为。
3. HAProxy
- 默认行为: HAProxy会根据HTTP规范处理和移除Hop-by-Hop头部,不会将这些头部传递到下一个节点。
- 自定义处理: 通过HAProxy配置文件,可以使用不同的指令和ACL(访问控制列表)规则自定义头部处理。
4. Spring Cloud Gateway
-
默认行为: Spring Cloud Gateway遵循HTTP规范,会自动处理并移除Hop-by-Hop头部。
-
自定义处理: 可以通过定义全局或局部过滤器在网关中处理这些头部,例如:
spring: cloud: gateway: routes: - id: custom_route uri: http://example.com predicates: - Path=/somepath/** filters: - RemoveRequestHeader=Connection - RemoveRequestHeader=Keep-Alive - RemoveRequestHeader=Proxy-Authenticate - RemoveRequestHeader=Proxy-Authorization - RemoveRequestHeader=TE - RemoveRequestHeader=Trailers - RemoveRequestHeader=Transfer-Encoding - RemoveRequestHeader=Upgrade
重要性
理解Hop-by-Hop头部对于构建健壮的HTTP客户端和服务器,以及设计使用代理服务器的网络应用程序至关重要,确保HTTP请求和响应被正确地中继和处理。
总结来说,Hop-by-Hop头部在HTTP通信中的每个跳之间传递和处理,而不会传递到最终目的地。这类头部通常由中间代理服务器和网关解析和管理,以确保HTTP通信的稳定和高效。