互联网工程任务组 (IETF) K. Oku
请求评论: 8297 Fastly
类别: 实验性 2017年12月
ISSN: 2070-1721

用于指示提示的 HTTP 状态码


摘要

本备忘录引入了一个信息性 HTTP 状态码,可用于传达有助于客户端为处理最终响应做准备的提示。

本备忘录的状态

本文档不是互联网标准轨道的规范;其发布用于审查、实验性实现和评估。

本文档为互联网社区定义了一种实验性协议。本文档是互联网工程任务组 (IETF) 的产物。它代表了 IETF 社区的共识。该文档已接受公众审阅并已获互联网工程指导小组 (IESG) 批准发布。并非所有经 IESG 批准的文档都适合成为任何级别的互联网标准;参见 RFC 7841 的第 2 节

有关本文档当前状态、任何勘误以及如何提供反馈的信息,可在 https://www.rfc-editor.org/info/rfc8297 获取。

Copyright Notice

Copyright (c) 2017 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

1. 引言

HTTP 响应经常包含在使用之前需要提前获取的外部资源链接,例如,网页浏览器渲染 HTML 时。尽早向客户端提供这些链接有助于减少用户感知到的延迟。

“preload” [Preload] 链接关系可以在 HTTP 响应的 Link 首部字段中传达此类链接。然而,源服务器并不总是能够在收到请求后立即生成最终响应的首部块。例如,源服务器可能会将请求委派给运行在远端位置的上游 HTTP 服务器,或者状态码可能依赖于数据库查询的结果。

这里的困境在于,即便源服务器最好能在收到请求后尽快发送某些首部字段,但在最终 HTTP 响应的状态码和完整首部字段确定之前,它无法这样做。

HTTP/2 [RFC7540] 的服务器推送可以加速资源的传递,但仅限于服务器拥有权威的那些资源。服务器推送的另一个限制是,无论客户端是否已缓存响应,响应都会被传输。与服务器推送在最坏情况下相比额外花费一次往返时间不同,及时传递 Link 首部字段更灵活,并且可能消耗更少的带宽。

本备忘录定义了一个用于发送信息性响应的状态码([RFC7231]第 6.2 节),该响应包含很可能会出现在最终响应中的首部字段。服务器可以发送包含部分首部字段的信息性响应,帮助客户端开始为处理最终响应做准备,然后再运行耗时操作以生成最终响应。信息性响应也可被源服务器用于在具有缓存功能的中间设备上触发 HTTP/2 的服务器推送。

1.1. 记号约定

本文档中关键字 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", 和 "OPTIONAL" 应当按 BCP 14 [RFC2119] [RFC8174] 的描述来解释——仅当这些词以全大写形式出现时,才按上述含义解释,如本文所示。

2. HTTP 状态码 103:早期提示

103(Early Hints)信息性状态码向客户端指示,服务器很可能在最终响应中包含信息性响应中出现的那些首部字段。

通常,服务器会在最终响应中包含在 103(Early Hints)响应中发送的首部字段。然而,可能存在不希望这样做的情况,例如服务器在发送最终响应之前发现 103 响应中的首部字段不正确。

客户端可以在等待最终响应时对 103(Early Hints)响应中包含的首部字段进行推测性评估。例如,客户端可能识别出 Link 首部字段值中包含 rel="preload" 的情况并开始获取目标资源。然而,这些首部字段仅为对客户端的提示;它们不会替代最终响应中的首部字段。

除了性能优化之外,对 103(Early Hints)响应首部字段的此类评估 不得 影响最终响应的处理方式。客户端 不得 将 103(Early Hints)响应的首部字段解释为适用于信息性响应本身(例如,作为关于 103 响应的元数据)。

服务器可使用 103(Early Hints)响应仅指示预期在最终响应中出现的部分首部字段。客户端 不应 将 103 响应中某一首部字段的缺失解释为该首部字段不太可能出现在最终响应中的猜测。

下面的示例说明了涉及 103(Early Hints)响应的典型消息交换。

客户端请求:

  GET / HTTP/1.1
  Host: example.com

服务器响应:

  HTTP/1.1 103 Early Hints
  Link: </style.css>; rel=preload; as=style
  Link: </script.js>; rel=preload; as=script

  HTTP/1.1 200 OK
  Date: Fri, 26 May 2017 10:02:11 GMT
  Content-Length: 1234
  Content-Type: text/html; charset=utf-8
  Link: </style.css>; rel=preload; as=style
  Link: </script.js>; rel=preload; as=script

  <!doctype html>
  [... 响应正文的其余部分在示例中省略 ...]

与任何信息性响应一样,服务器在发送最终响应之前可能发出多个 103(Early Hints)响应。例如,当缓存中介基于过期缓存响应的首部字段生成 103(Early Hints)响应,然后在对原点服务器的重新验证请求中转发来自原点服务器的 103(Early Hints)响应和最终响应时,就可能发生这种情况。

服务器可以在请求处理过程中随着新信息的可用而发出多个带有附加首部字段的 103(Early Hints)响应。它无需重复已经发送过的字段,但也可以选择包含它们。客户端在预期最终响应中可能包含的首部字段列表时,可以考虑从多个 103 响应中收到的任意组合的首部字段。

下面的示例说明了服务器可能发出的一个响应序列。在该示例中,服务器使用两个 103(Early Hints)响应通知客户端,它很可能在最终响应中发送三个 Link 首部字段。最终响应中包含了三者中的两个首部字段,另一个首部字段被替换为包含不同值的另一个 Link 首部字段。

  HTTP/1.1 103 Early Hints
  Link: </main.css>; rel=preload; as=style

  HTTP/1.1 103 Early Hints
  Link: </style.css>; rel=preload; as=style
  Link: </script.js>; rel=preload; as=script

  HTTP/1.1 200 OK
  Date: Fri, 26 May 2017 10:02:11 GMT
  Content-Length: 1234
  Content-Type: text/html; charset=utf-8
  Link: </main.css>; rel=preload; as=style
  Link: </newstyle.css>; rel=preload; as=style
  Link: </script.js>; rel=preload; as=script

  <!doctype html>
  [... 响应正文的其余部分在示例中省略 ...]

3. 安全性考虑

一些客户端可能在处理 103(Early Hints)响应时出现问题,因为信息性响应在回复不包含 Expect 首部字段的请求时很少使用([RFC7231]第 5.1.1 节)。

特别是,一个错误地将信息性响应当作最终响应处理的 HTTP/1.1 客户端,很可能会将随后在同一连接上发送的所有响应都视为该最终响应的一部分。这种行为在客户端将对不同原点的请求复用到同一个持久连接上时,可能构成跨源信息泄露漏洞。

因此,服务器在 HTTP/1.1 上可能会避免发送 103(Early Hints)响应,除非已知客户端能正确处理信息性响应。

HTTP/2 客户端由于响应首部字段的处理不影响响应主体结束的确定,较不可能遭受错误帧处理的问题。

4. IANA 注意事项

以下条目已在 “HTTP Status Codes” 注册表中注册:

  • Code: 103
  • Description: Early Hints
  • Specification: RFC 8297 (this document)

5. 参考文献

5.2. 说明性参考文献

[Preload]
Grigorik, I., Ed. and Y. Weiss, Ed., “Preload”, W3C 候选推荐, October 2017, <https://www.w3.org/TR/preload/>.

Appendix A. 致谢

感谢 Tatsuhiro Tsujikawa 提出使用信息性响应发送 Link 首部字段的想法。

Mark Nottingham 和 Willy Tarreau 在澄清该状态码语义方面提供了大量帮助。

作者在起草本文档的早期阶段的工作,曾在其受雇于 DeNA 有限公司期间得到支持。

作者地址

Kazuho Oku
Fastly
EMail: kazuhooku@gmail.com