3. Alt-Svc HTTP 头字段 (The Alt-Svc HTTP Header Field)
HTTP(S) 源服务器可以在响应中加入 Alt-Svc 头字段, 向客户端宣告替代服务可用.
Alt-Svc = clear / 1#alt-value
clear = %s"clear"; "clear", case-sensitive
alt-value = alternative *( OWS ";" OWS parameter )
alternative = protocol-id "=" alt-authority
protocol-id = token ; percent-encoded ALPN protocol name
alt-authority = quoted-string ; containing [ uri-host ] ":" port
parameter = token "=" ( token / quoted-string )
该字段值要么由一个值列表组成, 其中每个值表示一个替代服务, 要么为关键词 "clear".
包含特殊值 "clear" 的字段值表示, 该源请求使该源的所有替代服务失效. 这也包括同一响应中指定的替代服务, 以处理同时包含 "clear" 和替代服务的无效回复.
ALPN 协议名称 (ALPN protocol name) 是八位组序列, 对格式没有额外限制. token 中不允许出现的八位组 ([RFC7230] 第 3.2.6 节) MUST 按 [RFC3986] 第 2.1 节进行百分号编码. 因此, 表示百分号字符 "%" 的八位组 (十六进制 25) 也 MUST 进行百分号编码.
为了让任意 ALPN 协议名称都只有一种精确定义的表示方式, 还适用以下额外约束:
- 如果 ALPN 协议名称中的八位组是有效 token 字符且不是 "%", 则 MUST NOT 对其进行百分号编码.
- 使用百分号编码时, MUST 使用大写十六进制数字.
有了这些约束, 接收方可以使用简单的字符串比较来匹配协议标识符.
"alt-authority" 组件由一个 OPTIONAL 的 uri-host ([RFC3986] 第 3.2.2 节中的 "host"), 一个冒号 (":"), 以及一个端口号组成.
例如:
Alt-Svc: h2=":8000"
这表示同一主机上使用所指示端口 8000 的 "h2" 协议 ([RFC7540]).
涉及主机变更的示例如下:
Alt-Svc: h2="new.example.org:80"
这表示主机 "new.example.org" 上运行于端口 80 的 "h2" 协议. 注意, 这里需要使用 "quoted-string" 语法, 因为 ":" 不是 "token" 中允许的字符.
协议名称转义示例:
| ALPN 协议名称 | protocol-id | 说明 |
|---|---|---|
| h2 | h2 | 不需要转义 |
| w=x:y#z | w%3Dx%3Ay#z | "=" 和 ":" 被转义 |
| x%y | x%25y | "%" 需要转义 |
Alt-Svc MAY 出现在任何 HTTP 响应消息中, 不受状态码影响. 注意, Alt-Svc 的接收方可以忽略该头字段, 并且在某些情况下必须忽略它; 参见第 2.1 节和第 6 节.
Alt-Svc 字段值可以包含多个值:
Alt-Svc: h2="alt.example.com:8000", h2=":443"
当存在多个值时, 值的顺序反映服务器偏好, 第一个值表示最优先的替代服务.
客户端可以使用 Alt-Svc 宣告的值打开到替代服务的新连接. 后续请求可以立即开始使用这个新连接, 也可以在创建新连接期间继续使用现有连接.
使用 HTTP/2 ([RFC7540]) 时, 服务器 SHOULD 改为发送 ALTSVC 帧 (第 4 节). 一个连接可以发送单个 ALTSVC 帧; 不需要为每个请求发送新帧. 注意, 尽管有这一建议, 通过 HTTP/2 交付的响应中 Alt-Svc 头字段仍然有效.
每个 "alt-value" 后面可以跟随一个 OPTIONAL 的分号分隔附加参数列表, 每个这样的 "parameter" 都由名称和值组成.
本规范定义两个参数: "ma" 和 "persist", 见第 3.1 节. 未知参数 MUST 被忽略. 也就是说, 对包含未知参数的值 (alt-value) 进行处理时, MUST 将其视为该未知参数不存在.
新的参数可以在扩展规范中定义; 注册细节见第 7.3 节.
注意, 所有允许 "quoted-string" 语法的字段元素都 MUST 按 [RFC7230] 第 3.2.6 节处理.
3.1. 缓存 Alt-Svc 头字段值 (Caching Alt-Svc Header Field Values)
当使用 Alt-Svc 宣告替代服务时, 从消息生成时起, 该替代服务会被视为在 24 小时内新鲜 (fresh). 这一时长可以通过 "ma" (max-age) 参数修改.
语法:
ma = delta-seconds; see [RFC7234], Section 1.2.1
delta-seconds 值表示从响应生成开始, 该替代服务被视为新鲜的秒数.
Alt-Svc: h2=":443"; ma=3600
有关确定响应年龄 (response age) 的细节, 参见 [RFC7234] 第 4.2.3 节.
例如, 以下响应:
HTTP/1.1 200 OK
Content-Type: text/html
Cache-Control: max-age=600
Age: 30
Alt-Svc: h2=":8000"; ma=60
表示某个替代服务可用, 且可在接下来的 60 秒内使用. 然而, 该响应已经被缓存了 30 秒 (由 Age 头字段值给出); 因此, 从接收该响应开始, 该替代服务只在 30 秒内保持新鲜, 还要减去估计的传输时间.
注意, HTTP 缓存的新鲜生命周期 (此处为 600 秒) 不影响 Alt-Svc 值的缓存.
当从某个源收到 Alt-Svc 响应头字段时, 其值会使该源所有已缓存的替代服务失效, 并替换它们.
默认情况下, 当客户端检测到网络变化时, 已缓存的替代服务会被清除. 如果某个替代服务预期具有更长生命周期, 例如并不特定于客户端接入网络, 则可以携带值为 "1" 的 "persist" 参数, 作为提示表示该服务在网络配置变化之后可能仍然有用.
语法:
persist = "1"
例如:
Alt-Svc: h2=":443"; ma=2592000; persist=1
本规范只为 "persist" 定义了一个取值. 客户端 MUST 忽略值不为 "1" 的 "persist" 参数.
关于缓存替代服务的一般要求, 参见第 2.2 节.