├── 1-zh-cn.md ├── 2-zh-cn.md ├── 4-zh-cn.md ├── 7-zh-cn.md ├── 10-zh-cn.md ├── README.md ├── 9-zh-cn.md ├── 3-zh-cn.md ├── 5-zh-cn.md ├── 8-zh-cn.md └── 6-zh-cn.md /1-zh-cn.md: -------------------------------------------------------------------------------- 1 | ## 介绍 2 | 3 | 超文本传输​​协议(HTTP)获得了巨大的成功。然而, HTTP/1.1使用底层传输通道(见[RFC 7230 第六章](https://tools.ietf.org/html/rfc7230#section-6))的方式有几个特性给今天的应用程序性能带来了整体的负面效果。 4 | 5 | 尤其是对于一个给定的TCP连接,在同一时间内,HTTP/1.0只允许进行一个请求。虽然HTTP/1.1增加了管道,但这也仅仅部分解决了请求并发问题,而且仍然存在报头阻塞的问题。因此,为了实现并发性,进而减少服务器的延迟,使用HTTP/1.0和HTTP/1.1协议的客户端需要同时与服务端建立多个连接。 6 | 7 | 此外,HTTP报头通常重复而冗长,这将产生不必要的网络流量,并且会快速填满初始TCP拥塞窗口。当多个请求在同一个新建的TCP连接上发起时,将会产生过多的等待延迟。 8 | 9 | HTTP/2通过定义一个优化的HTTP语义到底层连接的映射来解决这些问题。具体来说,它允许请求和响应交错地使用同一个连接,并可以使用高效编码的HTTP报头。它还允许请求具有优先级,让更重要的请求更快速地完成,这进一步提高了性能。 10 | 11 | 由此产生的协议对网络更加友好,因为相比HTTP/1.x它可以使用更少的TCP连接来完成同样的功能。这意味着流量的竞争更少,连接的生命周期更长。这就能更好地利用现有的网络容量。 12 | 13 | 此外,通过使用二进制消息帧,HTTP/2也能更有效地处理消息。 14 | -------------------------------------------------------------------------------- /2-zh-cn.md: -------------------------------------------------------------------------------- 1 | # 2.HTTP/2 协议综述 2 | 3 | HTTP/2基于HTTP语义提供了优化的传输机制。HTTP/2 支持所有HTTP/1.1的核心特性,并在如下几个方面对其进行了改进。 4 | 5 | HTTP/2中基础的协议单元是帧(见第4.1节)。每个类型的帧都服务于不同的目的。例如 HEADERS和DATA 帧构成了基本的HTTP请求与应答(8.1节); 其他诸如SETTINGS, WINDOW_UPDATE, PUSH_PROMISE等帧类型用于支持其他的HTTP/2 特性。 6 | 7 | 请求的多路复用即每个HTTP请求/应答在各自的流(stream)中完成数据交换。由于每个流之间都是相互独立的,因此即使请求和应答被阻塞或速度很慢也不会影响各自流中的处理进程。 8 | 9 | 流量控制以及优先级机制可以保证有效的利用流的多路复用。流量控制(见 5.2节)确保只有接受者会使用的数据被传输。优先级机制可以确保有限的资源被优先传输到最重要的流。 10 | 11 | HTTP/2中增加了一种新的交互模式,即服务端可以将应答推送给客户端(见8.2节)。服务器推送机制允许服务器预测客户端可能需要的数据,并将其推送给客户端,这是一种以增加网络使用来减少延迟的折衷设计。服务器首先合成一个带有 PUSH_PROMISE帧的请求,随后服务器可以在另一个流中响应这个请求。 12 | 13 | 由于连接中使用的HTTP头包含大量冗余数据,因此包含它们的帧均需进行压缩(见 4.3节)。一般情况下,经过压缩后对于请求大小的影响很显著,可以将多个请求压缩到一个包(packet)中。 14 | 15 | ## 2.1 文档结构 16 | 17 | HTTP/2 标准说明包含以下四个部分: 18 | 19 | + 发起HTTP/2请求(见第3节) 主要讨论一个HTTP/2链接是如何初始化的 20 | + 帧(见第4节)与 流(见第5节) 主要讨论HTTP/2帧的结构以及如何组成多路复用的流 21 | + 帧(见第6节)与 错误定义(见第7节) 主要讨论帧的细节以及HTTP/2中的错误类型 22 | + HTTP 映射(见第8节)及附加要求(见第9节)主要讨论如何使用帧和流来表述HTTP语义 23 | 24 | 由于部分帧与流中的层的定义与HTTP无关,因此该标准中并没有提供完整的帧层的定义。帧与流的层均针对HTTP协议与服务器推送进行一定程度的裁剪。 25 | 26 | ## 2.2 约定与术语 27 | 28 | 对于关键词"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" 的定义以 RFC 2119[RFC2119]中解释为准。 29 | 30 | 所有数值均使用网络字节序。如未特别指出,所有值均为无符号的。本文中数值根据需要可以为十进制和十六进制。十六进制数值以“0x”开头,以示区分。 31 | 32 | 该标准中主要使用的术语包括: 33 | 34 | + 客户端(client):即发起HTTP/2连接的端点(endpoint). 客户端发出HTTP请求,并接收HTTP应答。 35 | + 连接(connection): 两个端点之间的传输层连接 36 | + 连接错误(connection error):影响HTTP/2连接的错误 37 | + 端点(endpoint): 连接的客户端或服务端 38 | + 帧(frame): HTTP/2连接中的最小通讯单元,由帧头与任意长度的字节流组成,字节流的具体结构由帧类型决定。 39 | + 节点(peer): 一类特殊的端点,主要用来代指在讨论中与主要端点对应的远端端点 40 | + 接收端: 接收帧的端点 41 | + 发送端: 发送帧的端点 42 | + 服务器: 接收HTTP/2连接的端点。服务器接收HTTP请求,并发送HTTP应答 43 | + 流: HTTP/2中的双向帧传输流 44 | + 流错误:发生在单独的HTTP/2流中的错误 45 | 46 | 最后,术语"网关(gateway)", "中间人(intermediary)", "代理(proxy)", "隧道(tunnel)"均在 [RFC7230]的第2.3节进行了定义。中间人在不同时段可分别担当客户端或者服务器。 47 | 48 | 术语"请求体(payload body)"在[RFC7230]的3.3节中定义。 49 | -------------------------------------------------------------------------------- /4-zh-cn.md: -------------------------------------------------------------------------------- 1 | # 4. HTTP帧 2 | 3 | 一旦建立了HTTP/2连接, 终端之间就可以开始交换帧了. 4 | 5 | ## 4.1 帧格式 6 | 7 | 所有的帧都以一个9字节的报头开始, 后接变长的载荷: 8 | 9 | ``` 10 | +-----------------------------------------------+ 11 | | Length (24) | 12 | +---------------+---------------+---------------+ 13 | | Type (8) | Flags (8) | 14 | +-+-------------+---------------+-------------------------------+ 15 | |R| Stream Identifier (31) | 16 | +=+=============================================================+ 17 | | Frame Payload (0...) ... 18 | +---------------------------------------------------------------+ 19 | ``` 20 | 21 | 报头部分的字段定义如下: 22 | 23 | + `Length`: 载荷的长度, 无符号24位整型. **对于发送值大于2^14 (长度大于16384字节)的载荷, 只有在接收方设置`SETTINGS_MAX_FRAME_SIZE`为更大的值时才被允许** 24 | 25 | 注: 帧的报头9字节不算在length里. 26 | + `Type`: 8位的值表示帧类型, 决定了帧的格式和语义. 协议实现上必须忽略任何未知类型的帧. 27 | + `Flags`: 为Type保留的bool标识, 大小是8位. 对确定的帧类型赋予特定的语义, 否则发送时必须忽略(设置为0x0). 28 | + `R`: 1位的保留字段, 尚未定义语义. 发送和接收必须忽略(0x0). 29 | + `Stream Identifier`: 31位无符号整型的流标示符. 其中0x0作为保留值, 表示与连接相关的frames作为一个整体而不是一个单独的流. 30 | 31 | ## 4.2 帧大小 32 | 33 | 载荷的大小受接收方设置的`SETTINGS_MAX_FRAME_SIZE`所限, 而这个值的取值区间是[2^14 (16384), 2^24-1 (16777215)] 字节. 34 | 35 | 必须能够接收并且至少能够处理2^14字节大小的帧, 外加9字节的报头. 在描述帧的大小时, 不包含帧的报头部分. 36 | 37 | 注: 某些类型的帧, 如PING, 会在允许传输的载荷大小上附加额外的限制. 38 | 39 | 终端必须响应一个错误码FRAME_SIZE_ERROR ----如果帧大小超过了SETTINGS_MAX_FRAME_SIZE中的定义或超过了对特定类型帧的大小限制, 抑或是帧太小以至于无法容纳下必要的元信息. 如果一个帧的*帧大小错误*可能改变整个连接的状态, 那么必须作为连接错误来对待; 这包括任何携带报头区块(HEADERS, PUSH_PROMISE, CONTINUATION)的帧, SETTINGS帧, 以及任何带有流标识符为0x0的帧. 40 | 41 | 终端不必完整填充一个帧的所有空间. 更小的帧能提高响应速度. 对于时间敏感的帧来讲(如RST_STREAM, WINDOW_UPDATE, PRIORITY), 发送大块的帧可能导致延迟, 如果传输链路被一个大块帧阻塞, 很可能会带来性能损耗. 42 | 43 | ## 4.3 Header压缩和解压 44 | 45 | HTTP/2与HTTP/1的报头结构一样, 一键多值. 除了用于HTTP请求和响应之外还用于server push操作. 46 | 47 | ### 压缩&分片 48 | 报头列表包含0个或多个报头字段. 传输过程是: 先用压缩把报头列表序列化成一个报头区块. 然后将这个区块分割成一个或多个字节序列, 称之为区块分片. 分片可以作为HEADERS帧, PUSH_PROMISE帧或者CONTINUATION帧的载荷. 49 | 50 | 其中Cookie字段通过HTTP mapping特殊处理. 51 | 52 | ### 解压&重组 53 | 报文接收端将分片拼接起来以重组报头区块, 然后解压区块得到原始的报头列表. 54 | 55 | 一个完整地报头区块可以由下面任意一种结构组成: 56 | 57 | + 一个设置了`END_HEADERS`标记的`HEADERS`或`PUSH_PROMISE`帧. 58 | + 一个`END_HEADERS`标记置空的`HEADERS`或`PUSH_PROMISE` 帧, 后接一个或多个`CONTINUATION`帧, 并且最后一个`CONTINUATION`帧`END_HEADERS`标记. 59 | 60 | 报头压缩是个**有状态**的过程. 整个连接复用同一个压缩和解压上下文. 61 | 报头区块中发生的解码错误必须当成连接错误处理, 类型为`COMPRESSION_ERROR`. 62 | 63 | 每个报头区块被当做离散的单元处理. 必须确保这些区块传输的连续性, 期间不能交叉其他类型的或来自任何其他流的帧. `HEADERS`与`PUSH_PROMISE`的`CONTINUATION`传输序列中最后一帧一定设置了`END_HEADERS`标记. 这保证了报头区块在逻辑上等价于单个帧. 64 | 65 | 报头区块的分片只能作为`HEADERS`, `PUSH_PROMISE`以及`CONTINUATION`帧的载荷存在. 因为这些帧携带的数据可能修改接收方维护的压缩上下文: 接收方拿到这三种类型之一的帧之后需要重组区块并解压, 即便这些帧将被丢弃. 如果无法解压区块, 接收方必须以一个类型为`COMPRESSION_ERROR`的错误断开连接. 66 | -------------------------------------------------------------------------------- /7-zh-cn.md: -------------------------------------------------------------------------------- 1 | # 错误码 2 | 3 | > Error codes are 32-bit fields that are used in RST_STREAM and GOAWAY frames to convey the reasons for the stream or connection error. 4 | 5 | 错误码是32位字段,用在`RST_STREAM`和超时帧中去标识流或者连接错误的原因。 6 | 7 | > Error codes share a common code space. Some error codes apply only to either streams or the entire connection and have no defined semantics in the other context. 8 | 9 | 错误码共享一个代码空间。 一些错误码仅仅适用于其中的一些流或者整个连接,在其他的情况下并没有明确的意义。 10 | 11 | > The following error codes are defined: 12 | 13 | 错误码有如下定义: 14 | 15 | > * NO_ERROR (0x0): The associated condition is not a result of an error. For example, a GOAWAY might include this code to indicate graceful shutdown of a connection. 16 | > * PROTOCOL_ERROR (0x1): The endpoint detected an unspecific protocol error. This error is for use when a more specific error code is not available. 17 | > * INTERNAL_ERROR (0x2): The endpoint encountered an unexpected internal error. 18 | > * FLOW_CONTROL_ERROR (0x3): The endpoint detected that its peer violated the flow-control protocol. 19 | > * SETTINGS_TIMEOUT (0x4): The endpoint sent a SETTINGS frame but did not receive a response in a timely manner. See Section 6.5.3 ("Settings Synchronization"). 20 | > * STREAM_CLOSED (0x5): The endpoint received a frame after a stream was half-closed. 21 | > * FRAME_SIZE_ERROR (0x6): The endpoint received a frame with an invalid size. 22 | > * REFUSED_STREAM (0x7): The endpoint refused the stream prior to performing any application processing (see Section 8.1.4 for details). 23 | > * CANCEL (0x8): Used by the endpoint to indicate that the stream is no longer needed. 24 | > * COMPRESSION_ERROR (0x9): The endpoint is unable to maintain the header compression context for the connection. 25 | > * CONNECT_ERROR (0xa): The connection established in response to a CONNECT request (Section 8.3) was reset or abnormally closed. 26 | > * ENHANCE_YOUR_CALM (0xb): The endpoint detected that its peer is exhibiting a behavior that might be generating excessive load. 27 | > * INADEQUATE_SECURITY (0xc): The underlying transport has properties that do not meet minimum security requirements (see Section 9.2). 28 | > * HTTP_1_1_REQUIRED (0xd): The endpoint requires that HTTP/1.1 be used instead of HTTP/2. 29 | 30 | + **NO_ERROR(0x0)**: 相关环境不作为错误处理。 例如: 超时帧可能包含该错误码来表明连接的正常关闭。 31 | + **PROTOCOL_ERROR (0x1)**: 终端检测到一个不确定性质的协议错误。 这个错误码用在一个更加确切的错误码不可用的情况下。 32 | + **INTERNAL_ERROR (0x2)**: 终端遇到了一个意外的内部错误。 33 | + **FLOW_CONTROL_ERROR (0x3)**: 终端检测到对等端违背了流量控制协议。 34 | + **SETTINGS_TIMEOUT (0x4)**: 终端发送了一个设置帧,但是没有在指定时间内得到响应。 [参见Section 6.5.3 ("Settings Synchronization")](https://tools.ietf.org/html/rfc7540#section-6.5.3)。 35 | + **STREAM_CLOSED (0x5)**: 终端在流的半封闭状态接收到了帧。 36 | + **FRAME_SIZE_ERROR (0x6)**: 终端接收到一个超出最大尺寸的帧。 37 | + **REFUSED_STREAM (0x7)**: 终端拒绝流之前执行了程序处理。 [参见Section 8.1.4](https://tools.ietf.org/html/rfc7540#section-8.1.4)。 38 | + **CANCEL (0x8)**: 标识这个流不再是需要的。 39 | + **COMPRESSION_ERROR (0x9)**: 终端无法维护报头压缩上下文的连接。 40 | + **CONNECT_ERROR (0xa)**: 为响应一个连接请求的而建立的连接[参见:Section 8.3](https://tools.ietf.org/html/rfc7540#section-8.3)被重置或者异常关闭。 41 | + **ENHANCE_YOUR_CALM (0xb)**: 终端检测到其对等端的某行为可能负荷超载。 42 | + **INADEQUATE_SECURITY (0xc)**: 底层传输特性不符合最低安全要求。 [参见 Section 9.2](https://tools.ietf.org/html/rfc7540#section-9.2)。 43 | + **HTTP_1_1_REQUIRED (0xd)**: 终端应该使用`HTTP/1.1`, 而不是`HTTP/2`。 44 | 45 | > Unknown or unsupported error codes MUST NOT trigger any special behavior. These MAY be treated by an implementation as being equivalent to INTERNAL_ERROR. 46 | 47 | 未知或者不支持的错误码**绝不会**触发任何特殊的行为。 它们可能会被当做内部错误(INTERNAL_ERROR)来处理。 -------------------------------------------------------------------------------- /10-zh-cn.md: -------------------------------------------------------------------------------- 1 | ## 10. Security Considerations 2 | ## 10. 安全性考虑 3 | 4 | ### 10.1. Server Authority 5 | ### 10.1. 服务器授权 6 | 7 | > HTTP/2 relies on the HTTP/1.1 definition of authority for determining 8 | whether a server is authoritative in providing a given response (see 9 | [RFC7230], Section 9.1). This relies on local name resolution for 10 | the "http" URI scheme and the authenticated server identity for the 11 | "https" scheme (see [RFC2818], Section 3). 12 | 13 | HTTP/2根据HTTP/1.1中授权的定义来判断在给定响应中一个服务器是否已授权. 这由http URI的本地名字解析以及https中已授权的服务器的身份决定. 14 | 15 | ### 10.2. Cross-Protocol Attacks 16 | ### 10.2. 跨协议攻击 17 | 18 | > In a cross-protocol attack, an attacker causes a client to initiate a 19 | transaction in one protocol toward a server that understands a 20 | different protocol. An attacker might be able to cause the 21 | transaction to appear as a valid transaction in the second protocol. 22 | In combination with the capabilities of the web context, this can be 23 | used to interact with poorly protected servers in private networks. 24 | 25 | 在跨协议攻击下, 攻击者让一个客户端与服务器之间开始一个事务, 然而客户端使用了服务器不理解的协议进行交流. 攻击者可以构造这个事务, 使其在服务其使用的协议中是合法的. 结合web环境下的功能, 就可以在私有网络下与防护能力弱的服务器进行交互. 26 | 27 | > Completing a TLS handshake with an ALPN identifier for HTTP/2 can be 28 | considered sufficient protection against cross-protocol attacks. 29 | ALPN provides a positive indication that a server is willing to 30 | proceed with HTTP/2, which prevents attacks on other TLS-based 31 | protocols. 32 | 33 | 在HTTP/2中用一个ALPN标记进行TLS握手会提供足够的保护以免遭受跨协议攻击. ALPN提供了一个正向指标表示服务器愿意使用HTTP/2, 这防止了对其他基于TLS的协议上的攻击. 34 | 35 | > The encryption in TLS makes it difficult for attackers to control the 36 | data that could be used in a cross-protocol attack on a cleartext 37 | protocol. 38 | 39 | TLS中的加密措施使得跨协议攻击者难以控制一个明文协议上的数据. 40 | 41 | > The cleartext version of HTTP/2 has minimal protection against cross- 42 | protocol attacks. The connection preface (Section 3.5) contains a 43 | string that is designed to confuse HTTP/1.1 servers, but no special 44 | protection is offered for other protocols. A server that is willing 45 | to ignore parts of an HTTP/1.1 request containing an Upgrade header 46 | field in addition to the client connection preface could be exposed 47 | to a cross-protocol attack. 48 | 49 | HTTP/2的明文版本具有抵御跨协议攻击的最小保护. 在3.5节的序言中有一段字符串用于混淆HTTP/1.1服务器, 但是对其他协议并没有提供特别的保护. 如果服务器希望忽略HTTP/1.1请求中包含除了客户端连接序言的upgrade头部字段的那部分, 可能会受跨协议攻击影响. 50 | 51 | ### 10.3. Intermediary Encapsulation Attacks 52 | ### 10.3. 伪装中介攻击 53 | 54 | > The HTTP/2 header field encoding allows the expression of names that 55 | are not valid field names in the Internet Message Syntax used by 56 | HTTP/1.1. Requests or responses containing invalid header field 57 | names MUST be treated as malformed (Section 8.1.2.6). An 58 | intermediary therefore cannot translate an HTTP/2 request or response 59 | containing an invalid field name into an HTTP/1.1 message. 60 | 61 | HTTP/2头部字段编码允许那些在HTTP/1.1所使用的互联网消息语法格式中并不合法的字段名. 62 | 对于那些包含非法头部字段名的请求或者响应必须视为格式错误(见第8.1.2.6小节描述). 63 | 因此中介者不可以把包含非法字段名的HTTP/2请求或响应转换成HTTP/1.1兼容的报文. 64 | 65 | > Similarly, HTTP/2 allows header field values that are not valid. 66 | While most of the values that can be encoded will not alter header 67 | field parsing, carriage return (CR, ASCII 0xd), line feed (LF, ASCII 68 | 0xa), and the zero character (NUL, ASCII 0x0) might be exploited by 69 | an attacker if they are translated verbatim. Any request or response 70 | that contains a character not permitted in a header field value MUST 71 | be treated as malformed (Section 8.1.2.6). Valid characters are 72 | defined by the "field-content" ABNF rule in Section 3.2 of [RFC7230]. 73 | 74 | 同样, HTTP/2允许非法的头部字段值. 75 | 然而大多数可以被编码的值并不会影响头部字段的解析, 如果把他们一字不差进行解析, 76 | 那么像回车(CR, ASCII 0xd), 换行(LF, ASCII 0xa), 以及零字符(NUL, ASCII 0x0)就有可能会被攻击者利用. 77 | 如果请求或响应的头部字段值包含了非法的字符, 必须视之为格式错误(见第8.1.2.6小节描述). 78 | "field-content" ABNF规则(RFC7230的第3.2节给出了描述)中定义了什么是**合法的字符**. 79 | 80 | ### 10.4. Cacheability of Pushed Responses 81 | ### 10.4. 推送响应的缓存能力 82 | 83 | > Pushed responses do not have an explicit request from the client; the 84 | request is provided by the server in the PUSH_PROMISE frame. 85 | 86 | 推送响应并不会对应一个来自客户端的显式请求. 这个请求包含在服务器的PUSH_PROMISE帧中. 87 | 88 | > Caching responses that are pushed is possible based on the guidance 89 | provided by the origin server in the Cache-Control header field. 90 | However, this can cause issues if a single server hosts more than one 91 | tenant. For example, a server might offer multiple users each a 92 | small portion of its URI space. 93 | 94 | 可以依据原服务器在`Cache-Control`头部字段提供的指示来缓存推送的响应. 尽管如此, 在一个服务器上部署多个tenant时可能会出问题. 比如, 95 | 服务器可能把它的URI空间分配给多个用户各一小部分. 96 | 97 | > Where multiple tenants share space on the same server, that server 98 | MUST ensure that tenants are not able to push representations of 99 | resources that they do not have authority over. Failure to enforce 100 | this would allow a tenant to provide a representation that would be 101 | served out of cache, overriding the actual representation that the 102 | authoritative tenant provides. 103 | 104 | 多个tenant共享同一个服务器的空间的情况下, 服务器必须确保tenant不能推送他们无权管辖的资源. 如果不强制这么做, tenant将有可能提供缓存范围外的资源, 覆盖权威tenant提供的实际资源. 105 | 106 | > Pushed responses for which an origin server is not authoritative (see 107 | Section 10.1) MUST NOT be used or cached. 108 | 109 | 对于不具权威性(见10.1节描述)的原服务器, 推送响应是不准被使用或缓存的. 110 | 111 | ### 10.5. Denial-of-Service Considerations 112 | ### 10.5. 对于拒绝服务攻击的考虑 113 | 114 | > An HTTP/2 connection can demand a greater commitment of resources to 115 | operate than an HTTP/1.1 connection. The use of header compression 116 | and flow control depend on a commitment of resources for storing a 117 | greater amount of state. Settings for these features ensure that 118 | memory commitments for these features are strictly bounded. 119 | 120 | 相比HTTP/1.1连接, HTTP/2连接可以要求更大的资源操作能力. 121 | 头部压缩和流控在使用上都依赖于资源的承诺, 以存储更多的状态. 122 | 对于这些特性的设置严格限制了内存的使用. 123 | 124 | > The number of PUSH_PROMISE frames is not constrained in the same 125 | fashion. A client that accepts server push SHOULD limit the number 126 | of streams it allows to be in the "reserved (remote)" state. An 127 | excessive number of server push streams can be treated as a stream 128 | error (Section 5.4.2) of type ENHANCE_YOUR_CALM. 129 | 130 | PUSH_PROMISE帧的数量限制方式并不相同. 接受了服务器推送的客户端应该限制其"reserved (remote)"状态中允许使用的流的数量. 服务器推送流数量过多的话可能被视为一个类型为ENHANCE_YOUR_CALM的流错误(见5.4.2小节描述). 131 | 132 | > Processing capacity cannot be guarded as effectively as state 133 | capacity. 134 | 135 | `操作`不像`状态`那样可以有效进行管理. 136 | 137 | > The SETTINGS frame can be abused to cause a peer to expend additional 138 | processing time. This might be done by pointlessly changing SETTINGS 139 | parameters, setting multiple undefined parameters, or changing the 140 | same setting multiple times in the same frame. WINDOW_UPDATE or 141 | PRIORITY frames can be abused to cause an unnecessary waste of 142 | resources. 143 | 144 | SETTINGS帧的滥用可能会导致一个对等端增加额外的处理时间. 比如无意义的更改SETTINGS帧的参数, 设置多个未定义的参数, 或在同一个帧中多次修改同一个参数. 145 | WINDOW_UPDATE或PRIORITY帧的滥用可能会导致资源的不必要浪费. 146 | 147 | > Large numbers of small or empty frames can be abused to cause a peer 148 | to expend time processing frame headers. Note, however, that some 149 | uses are entirely legitimate, such as the sending of an empty DATA or 150 | CONTINUATION frame at the end of a stream. 151 | 152 | 巨大数量的小型帧或空帧的滥用可能会导致一个对等端增加处理帧头部的时间. 注意, 尽管如此一些情况下这种使用是完全合理的, 比如在流结束时发送一个空的DATA帧或者CONTINUATION帧. 153 | 154 | > Header compression also offers some opportunities to waste processing 155 | resources; see Section 7 of [COMPRESSION] for more details on 156 | potential abuses. 157 | 158 | 头部压缩过程也暴露了浪费处理资源的一些可乘之机. 详情参见[COMPRESSION]中的第七节描述的潜在滥用情况. 159 | 160 | > Limits in SETTINGS parameters cannot be reduced instantaneously, 161 | which leaves an endpoint exposed to behavior from a peer that could 162 | exceed the new limits. In particular, immediately after establishing 163 | a connection, limits set by a server are not known to clients and 164 | could be exceeded without being an obvious protocol violation. 165 | 166 | SETTINGS帧中对参数的限制不会立即生效, 这让一个从对等端暴露自己行为的端系统能够超过新设置的最大限度. 167 | 特别是, 建立连接之后即刻起, 服务器设置的限制, 客户端无从得知, 所以除非有明显违反协议不然可能会超过这个限制. 168 | 169 | > All these features -- i.e., SETTINGS changes, small frames, header 170 | compression -- have legitimate uses. These features become a burden 171 | only when they are used unnecessarily or to excess. 172 | 173 | 所有这些特性, 例如, SETTINGS改变, 小型帧, 头部压缩, 都有其合理的使用场景. 也只有在不必要的使用或者滥用情况下这些特性才会成为带来负面影响. 174 | 175 | > An endpoint that doesn't monitor this behavior exposes itself to a 176 | risk of denial-of-service attack. Implementations SHOULD track the 177 | use of these features and set limits on their use. An endpoint MAY 178 | treat activity that is suspicious as a connection error 179 | (Section 5.4.1) of type ENHANCE_YOUR_CALM. 180 | 181 | 一个端系统不会监视这一行为以免把自己置于DoS攻击的威胁之下. 182 | 协议的实现应该追踪这些特性的使用情况并在他们的使用上做限制. 一个端系统可以把可疑的活动视为一个类型为ENHANCE_YOUR_CALM的连接错误. 183 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RFC 7540 Translation (in progress) 2 | 3 | [HTTP/2 Standards](https://tools.ietf.org/html/rfc7540), 欢迎参与翻译! 4 | 5 | **新来的同学请先移步至issue**: https://github.com/abbshr/rfc7540-translation-zh_cn/issues/1 6 | 7 | + 请遵循"fork & pull request"协作模型, 不要直接commit到原始仓库. 8 | + 发起pull request之前请fetch/pull检查与upstream分支的差异获取最近更新. 9 | 10 | (更新时间2016-10-14) 11 | 12 | 翻译进度: 13 | 14 | + [x] 1. [介绍](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/1-zh-cn.md) 15 | + [x] 2. [概览](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/2-zh-cn.md) 16 | - [x] 2.1. [文档结构](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/2-zh-cn.md#21-文档结构) 17 | - [x] 2.2. [约定与术语](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/2-zh-cn.md#22-约定与术语) 18 | + [x] 3. [开始HTTP/2](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/3-zh-cn.md) 19 | - [x] 3.1. [HTTP/2版本标识](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/3-zh-cn.md#31-http2-version-identification--http2版本标识) 20 | - [x] 3.2. [为"http" URIs启用HTTP/2协议](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/3-zh-cn.md#32-starting-http2-for-http-uris--为http-uris启用http2协议) 21 | - [x] 3.2.1. [HTTP2-Settings头部字段](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/3-zh-cn.md#321-http2-settings-header-field--http2-settings首部字段) 22 | - [x] 3.3. [为"https" URIs启用HTTP/2协议](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/3-zh-cn.md#33-starting-http2-for-https-uris--为https-uris启用http2协议) 23 | - [x] 3.4. [先验下启用HTTP/2](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/3-zh-cn.md#34-starting-http2-with-prior-knowledge--先验下启用http2) 24 | - [x] 3.5. [HTTP/2连接序言](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/3-zh-cn.md#35-http2-connection-preface--http2连接前奏) 25 | + [x] 4. [HTTP帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/4-zh-cn.md) 26 | - [x] 4.1. [帧格式](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/4-zh-cn.md#41-帧格式) 27 | - [x] 4.2. [帧大小](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/4-zh-cn.md#42-帧大小) 28 | - [x] 4.3. [Header压缩和解压](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/4-zh-cn.md#43-header压缩和解压) 29 | + [x] 5. [流与多路复用](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md) 30 | - [x] 5.1. [流的状态](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#51-流的状态) 31 | - [x] 5.1.1. [流标识符](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#511-stream标识符) 32 | - [x] 5.1.2 [流的并发性](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#512-流的并发性) 33 | - [x] 5.2 [流控](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#52-流控) 34 | - [x] 5.2.1 [流控原则](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#521-流控原则) 35 | - [x] 5.2.2 [合理使用流控](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#522-合理使用流控) 36 | - [x] 5.3 [流的优先级](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#53-流的优先级) 37 | - [x] 5.3.1 [流的依赖关系](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#531-流的依赖关系) 38 | - [x] 5.3.2 [依赖权重](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#532-依赖权重) 39 | - [x] 5.3.3 [优先级重排](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#533-优先级依赖重排) 40 | - [x] 5.3.4 [优先级状态管理](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#534-优先级状态管理) 41 | - [x] 5.3.5 [默认优先级](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#535-默认优先级) 42 | - [x] 5.4 [错误处理](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#54-错误处理) 43 | - [x] 5.4.1 [连接错误](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#541-连接错误处理) 44 | - [x] 5.4.2 [流错误](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#542-流错误处理) 45 | - [x] 5.4.3 [连接终止](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#543-连接终止) 46 | - [x] 5.5 [HTTP/2扩展](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/5-zh-cn.md#55-http2扩展) 47 | + [x] 6. [帧的定义](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md) 48 | - [x] 6.1 [DATA 帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#61-data) 49 | - [x] 6.2 [HEADERS 帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#62-headers) 50 | - [x] 6. [PRIORITY 帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#63-priority) 51 | - [x] 6.4 [RST_STREAM 帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#64-rst_stream) 52 | - [x] 6.5 [SETTINGS 帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#65-settings) 53 | - [x] 6.5.1 [SETTINGS 帧格式](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#651-settings格式) 54 | - [x] 6.5.2 [已定义的 SETTINGS 参数](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#652-已定义的settings参数) 55 | - [x] 6.5.3 [设置同步](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#653-设置同步) 56 | - [x] 6.6 [PUSH_PROMISE 帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#66-push_promise) 57 | - [x] 6.7 [PING 帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#67-ping) 58 | - [x] 6.8 [GOAWAY 帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#68-goaway) 59 | - [x] 6.9 [WINDOW_UPDATE 帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#69-window_update) 60 | - [x] 6.9.1 [流控窗口](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#691-flow-control窗口) 61 | - [x] 6.9.2 [初始的Flow-Control窗口大小](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#692-初始的flow-control窗口大小) 62 | - [x] 6.9.3 [减小流窗口大小](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#693-减小流窗口大小) 63 | - [x] 6.10 [CONTINUATION 帧](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/6-zh-cn.md#610-continuation) 64 | + [x] 7. [错误码](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/7-zh-cn.md) 65 | + [x] 8. [HTTP消息交换](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md) 66 | - [x] 8.1 [HTTP 请求/响应交换](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#81-http-requestresponse-exchange--http-请求响应交换) 67 | - [x] 8.1.1 [从HTTP/2升级](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#811-upgrading-from-http2--从http2升级) 68 | - [x] 8.1.2 [HTTP头部字段](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#812-http-header-fields--http头部字段) 69 | - [x] 8.1.2.1 [伪头部字段](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#8121-pseudo-header-fields-伪头部字段) 70 | - [x] 8.1.2.2 [针对连接的头部字段](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#8122-connection-specific-header-fields--connection-specific头部字段) 71 | - [x] 8.1.2.3 [请求伪头部字段](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#8123-request-pseudo-header-fields--请求伪头部字段) 72 | - [x] 8.1.2.4 [响应伪头部字段](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#8124-response-pseudo-header-fields--响应伪头部字段) 73 | - [x] 8.1.2.5 [压缩Cookie头部字段](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#8125-compressing-the-cookie-header-field--压缩cookie头部字段) 74 | - [x] 8.1.2.6 [不规范的请求和响应](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#8126-malformed-requests-and-responses--不规范的请求和响应) 75 | - [x] 8.1.3 [例子](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#813-examples--例子) 76 | - [x] 8.1.4 [HTTP/2请求可靠机制](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#814-request-reliability-mechanisms-in-http2--http2请求可靠机制) 77 | - [x] 8.2 [服务端推送](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#82-server-push--服务端推送) 78 | - [x] 8.2.1 [推送请求](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#821-push-requests--推送请求) 79 | - [x] 8.2.2 [推送响应](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#822-push-responses--推送响应) 80 | - [x] 8.3 [CONNECT方法](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/8-zh-cn.md#83-the-connect-method--connect方法) 81 | + [x] 9. [其他HTTP要求/注意事项](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/9-zh-cn.md) 82 | - [x] 9.1 [连接管理](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/9-zh-cn.md#91-连接管理) 83 | - [x] 9.1.1 [连接复用](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/9-zh-cn.md#911-连接复用) 84 | - [x] 9.1.2 [421(误导请求)状态码](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/9-zh-cn.md#912-421误导请求状态码) 85 | - [x] 9.2 [使用TLS功能](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/9-zh-cn.md#92-使用tls功能) 86 | - [x] 9.2.1 [TLS1.2功能](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/9-zh-cn.md#921-tls-12功能) 87 | - [x] 9.2.2 [TLS1.2加密套件](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/9-zh-cn.md#922-tls-12加密套件) 88 | + [ ] 10. [安全性考虑](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/10-zh-cn.md#10-安全性考虑) 89 | - [x] 10.1. [服务器授权](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/10-zh-cn.md#101-服务器授权) 90 | - [x] 10.2. [跨协议攻击](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/10-zh-cn.md#102-跨协议攻击) 91 | - [x] 10.3. [伪装中介攻击](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/10-zh-cn.md#103-伪装中介攻击) 92 | + [ ] 11. IANA Considerations 93 | + [ ] 12. References 94 | + [ ] Appendix A. TLS 1.2 Cipher Suite Black List 95 | 96 | 校对审核进度: 97 | 98 | + [x] 1. Instroduction 99 | + [ ] 2. Overview 100 | + [ ] 3. Starting HTTP/2 101 | + [x] 4. HTTP帧 102 | + [ ] 5. 流与多路复用 103 | - [ ] 5.1. 流的状态 104 | - [ ] 5.1.1. 流标识符 105 | - [ ] 5.1.2 流的并发性 106 | - [ ] 5.2 流控 107 | - [ ] 5.2.1 流控原则 108 | - [ ] 5.2.2 合理使用流控 109 | - [ ] 5.3 流的优先级 110 | - [ ] 5.3.1 流的依赖关系 111 | - [ ] 5.3.2 依赖权重 112 | - [ ] 5.3.3 优先级重排 113 | - [ ] 5.3.4 优先级状态管理 114 | - [ ] 5.3.5 默认优先级 115 | - [ ] 5.4 错误处理 116 | - [ ] 5.4.1 连接错误 117 | - [ ] 5.4.2 流错误 118 | - [ ] 5.4.3 连接终止 119 | - [ ] 5.5 HTTP/2扩展 120 | + [ ] 6. Frame Definitions 121 | + [ ] 7. Error Codes 122 | + [ ] 8. HTTP Message Exchanges 123 | + [ ] 9. Additional HTTP Requirements/Considerations 124 | + [ ] 10. Security Considerations 125 | + [ ] 11. IANA Considerations 126 | + [ ] 12. References 127 | + [ ] Appendix A. TLS 1.2 Cipher Suite Black List 128 | -------------------------------------------------------------------------------- /9-zh-cn.md: -------------------------------------------------------------------------------- 1 | # 9. 其他HTTP要求/注意事项 2 | 3 | > This section outlines attributes of the HTTP protocol that improve interoperability, reduce exposure to known security vulnerabilities, or reduce the potential for implementation variation. 4 | 5 | 这部分概述了`HTTP`协议的属性,包括提高互通性、 减少暴露已知的安全漏洞或者减少执行变异的可能。 6 | 7 | ## 9.1 连接管理 8 | 9 | > HTTP/2 connections are persistent. For best performance, it is expected that clients will not close connections until it is determined that no further communication with a server is necessary (for example, when a user navigates away from a particular web page) or until the server closes the connection. 10 | 11 | `HTTP/2`的连接是持久性的。 为了获得最佳的性能,在确定与服务器没有进一步的连接必要之前客户端将不会关闭连接(例如:当用户导航到其他特定的网页时这个连接就会关闭),或者直到服务器端关闭连接之前。 12 | 13 | > Clients SHOULD NOT open more than one HTTP/2 connection to a given host and port pair, where the host is derived from a URI, a selected alternative service [ALT-SVC], or a configured proxy. 14 | 15 | 客户端不应该给一个给定的主机和端口号打开多个`HTTP/2`连接,其中这个主机来源于一个选定替代服务([参见:ALT-SVG](https://tools.ietf.org/html/rfc7540#ref-ALT-SVC))或者配置代理的统一资源标识符(URI)。 16 | 17 | > A client can create additional connections as replacements, either to replace connections that are near to exhausting the available stream identifier space (Section 5.1.1), to refresh the keying material for a TLS connection, or to replace connections that have encountered errors (Section 5.4.1). 18 | 19 | 客户端可以创建额外的连接作为替代,或者取代快要耗尽的可用流标识符空间([参见:Section 5.1.1](http://tools.ietf.org/html/rfc7540#section-5.1.1)),或者为`TLS`连接刷新密钥,或者替换遇到的错误连接([参见: Section 5.4.1](http://tools.ietf.org/html/rfc7540#section-5.4.1))。 20 | 21 | > A client MAY open multiple connections to the same IP address and TCP port using different Server Name Indication [TLS-EXT] values or to provide different TLS client certificates but SHOULD avoid creating multiple connections with the same configuration. 22 | 23 | 一个客户端可以针对相同的`IP`地址和`TCP`端口号用不同的服务器端名称标识符或者用不同的`TCL`客户端证书创建多个连接,但是应该避免用相同的配置创建多个连接。 24 | 25 | > Servers are encouraged to maintain open connections for as long as possible but are permitted to terminate idle connections if necessary. When either endpoint chooses to close the transport-layer TCP connection, the terminating endpoint SHOULD first send a GOAWAY (Section 6.8) frame so that both endpoints can reliably determine whether previously sent frames have been processed and gracefully complete or terminate any necessary remaining tasks. 26 | 27 | 服务器端被鼓励尽可能长时间的保持打开的连接,但是在必要的情况下要关闭空余的连接。当任意一个端口选择关闭传输层的`TCP`连接时,决定关闭的终端应该首先发送一个超时帧,这样两个终端都能可靠的确定之前发送的帧是否已经被处理、“优雅”的完成或者终止任何剩余的必要任务。 28 | 29 | ### 9.1.1 连接复用 30 | 31 | > Connections that are made to an origin server, either directly or through a tunnel created using the CONNECT method (Section 8.3), MAY be reused for requests with multiple different URI authority components. A connection can be reused as long as the origin server is authoritative (Section 10.1). For TCP connections without TLS, this depends on the host having resolved to the same IP address. 32 | 33 | 连接到源服务器的连接,无论是直接或者通过由`CONNECT`方法([参见: Section 8.3](http://tools.ietf.org/html/rfc7540#section-8.3))建立的隧道连接,都可能重复使用于多个不同`URL`权限请求组件。只要源服务器是权威的,连接就可以被复用([参见: Section 10.1](http://tools.ietf.org/html/rfc7540#section-10.1))。对于没有`TLS`的`TCP`连接,这取决于对同一个`IP`地址已经解析的主机端。 34 | 35 | > For "https" resources, connection reuse additionally depends on having a certificate that is valid for the host in the URI. The certificate presented by the server MUST satisfy any checks that the client would perform when forming a new TLS connection for the host in the URI. 36 | 37 | 对于`HTTP`资源,连接复用还额外取决于是否拥有一个对于`URL`中的主机已经验证过的证书。该证书由服务器提供并且必须满足这种形式的检查,即在`URL`主机中形成一个新的`TLS`连接时客户端将执行任何检查。 38 | 39 | > An origin server might offer a certificate with multiple "subjectAltName" attributes or names with wildcards, one of which is valid for the authority in the URI. For example, a certificate with a "subjectAltName" of "*.example.com" might permit the use of the same connection for requests to URIs starting with "https://a.example.com/" and "https://b.example.com/". 40 | 41 | 源服务器可能提供一个拥有多个`subjectAltName`属性或者通配符的证书,其中之一是有效授权的`URL`。例如:一个带有`*.example.com`的`subjectAltName`证书将允许`a.example.com`和`b.example.com`使用同一个连接。 42 | 43 | > In some deployments, reusing a connection for multiple origins can result in requests being directed to the wrong origin server. For example, TLS termination might be performed by a middlebox that uses the TLS Server Name Indication (SNI) [TLS-EXT] extension to select an origin server. This means that it is possible for clients to send confidential information to servers that might not be the intended target for the request, even though the server is otherwise authoritative. 44 | > 45 | > A server that does not wish clients to reuse connections can indicate that it is not authoritative for a request by sending a 421 (Misdirected Request) status code in response to the request (see Section 9.1.2). 46 | > 47 | > A client that is configured to use a proxy over HTTP/2 directs requests to that proxy through a single connection. That is, all requests sent via a proxy reuse the connection to the proxy. 48 | 49 | ### 9.1.2 421(误导请求)状态码 50 | 51 | > The 421 (Misdirected Request) status code indicates that the request was directed at a server that is not able to produce a response. This can be sent by a server that is not configured to produce responses for the combination of scheme and authority that are included in the request URI. 52 | 53 | 421(误导请求)状态码标识的是一个不能够产生响应的服务器请求。这个状态码可能会在服务器没有为产生经过计划和认证的响应进行相关的配置的时候产生。 54 | 55 | > Clients receiving a 421 (Misdirected Request) response from a server MAY retry the request -- whether the request method is idempotent or not -- over a different connection. This is possible if a connection is reused (Section 9.1.1) or if an alternative service is selected [ALT-SVC]. 56 | 57 | 客户端接收到服务器端发送的421(误导请求)响应可以通过不同的连接重试请求——不管这个请求方式是不是幂等的。这个连接可能是复用的(参见:[Section 9.1.1](https://tools.ietf.org/html/rfc7540#section-9.1.1)),或者可选的服务被选择([参见 ALT-SVC](https://tools.ietf.org/html/rfc7540#ref-ALT-SVC))。 58 | 59 | > This status code MUST NOT be generated by proxies. 60 | 61 | 这个状态码绝对不能由代理端产生。 62 | 63 | > A 421 response is cacheable by default, i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [RFC7234]). 64 | 65 | 421的响应缓存是默认的。除非被定义的方法或者显式缓存控制另有说明 66 | 67 | ## 9.2 使用TLS功能 68 | 69 | > Implementations of HTTP/2 MUST use TLS version 1.2 [TLS12] or higher for HTTP/2 over TLS. The general TLS usage guidance in [TLSBCP] SHOULD be followed, with some additional restrictions that are specific to HTTP/2. 70 | 71 | `HTTP/2`的实现必须使用`TLS 1.2`([参见: TLS12](https://tools.ietf.org/html/rfc7540#ref-TLS12))或者更高的版本。通用的`TLS`指导([参见: TLSBCP](https://tools.ietf.org/html/rfc7540#ref-TLSBCP))应该遵循,同时还需加上`HTTP/2`的一些额外限制条件。 72 | 73 | > The TLS implementation MUST support the Server Name Indication (SNI) [TLS-EXT] extension to TLS. HTTP/2 clients MUST indicate the target domain name when negotiating TLS. 74 | 75 | `TLS`的实现必须支持服务器名称指示(SNI)的`TLS`扩展([参见:TLS-EXT](https://tools.ietf.org/html/rfc7540#ref-TLS-EXT))。`HTTP/2`客户端在协商`TLS`的时候必须注明目标域名。 76 | 77 | > Deployments of HTTP/2 that negotiate TLS 1.3 or higher need only support and use the SNI extension; deployments of TLS 1.2 are subject to the requirements in the following sections. Implementations are encouraged to provide defaults that comply, but it is recognized that deployments are ultimately responsible for compliance. 78 | 79 | `HTTP/2`的部署中在协商`TLS1.3`或者更高的版本时只需要支持和使用服务器域名指示(SNI)扩展。`TLS1.2`的部署需要遵循下面章节的要求。在实现过程中鼓励提供符合要求的默认值,部署的最终负责合规性。 80 | 81 | ### 9.2.1 TLS 1.2功能 82 | 83 | > This section describes restrictions on the TLS 1.2 feature set that can be used with HTTP/2. Due to deployment limitations, it might not be possible to fail TLS negotiation when these restrictions are not met. An endpoint MAY immediately terminate an HTTP/2 connection that does not meet these TLS requirements with a connection error (Section 5.4.1) of type INADEQUATE_SECURITY. 84 | 85 | 本节描述了`HTTP/2`使用的`TLS 1.2`功能集限制。由于部署的限制,当一些限制没有遇到的时候`TLS`可能无法断开协商。终端必须立即终止一个不符合`TLS`要求的`HTTP/2`连接,并且把他们当做INADEQUATE_SECURITY处理([参见: Section5.4.1](https://tools.ietf.org/html/rfc7540#section-5.4.1))。 86 | 87 | > A deployment of HTTP/2 over TLS 1.2 MUST disable compression. TLS compression can lead to the exposure of information that would not otherwise be revealed [RFC3749]. Generic compression is unnecessary since HTTP/2 provides compression features that are more aware of context and therefore likely to be more appropriate for use for performance, security, or other reasons. 88 | 89 | 通过`TLS 1.2`进行的`HTTP/2`部署必须禁止压缩。`TLS`的压缩可能导致信息的暴露([参见:RFC3749](https://tools.ietf.org/html/rfc3749))。通用的压缩是不必要的,因为`HTTP/2`提供的压缩功能能够更好的联系上下文,因此可能更加的符合性能要求,安全或者其他方面。 90 | 91 | > A deployment of HTTP/2 over TLS 1.2 MUST disable renegotiation. An endpoint MUST treat a TLS renegotiation as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. Note that disabling renegotiation can result in long-lived connections becoming unusable due to limits on the number of messages the underlying cipher suite can encipher. 92 | 93 | 通过`TLS 1.2`进行的`HTTP/2`部署必须禁止重新协商。终端必须将`TLS`协商定义为连接错误,类型为`PROROCOL_ERROR`([参见 Section 5.4.1](https://tools.ietf.org/html/rfc7540#section-5.4.1))。务必注意由于密码套件可以加密消息的次数限制,禁止重新协商可能会导致长期连接编程不可用。 94 | 95 | > An endpoint MAY use renegotiation to provide confidentiality protection for client credentials offered in the handshake, but any renegotiation MUST occur prior to sending the connection preface. A server SHOULD request a client certificate if it sees a renegotiation request immediately after establishing a connection. 96 | 97 | 终端可以使用协商来对客户端握手提供机密性的保护,但是任何协商必须在发送连接前言之前。在建立连接后,服务器如果看到一个协商请求后会马上协商请求客户端证书。 98 | 99 | > This effectively prevents the use of renegotiation in response to a request for a specific protected resource. A future specification might provide a way to support this use case. Alternatively, a server might use an error (Section 5.4) of type HTTP_1_1_REQUIRED to request the client use a protocol that supports renegotiation. 100 | 101 | 这有效的防止了使用协商相应来请求一个特定的受保护资源。未来的规范可能会提供一种方式来支持这种需求。可替代地,服务器可以使用类型为`HTTP_1_1_REQUIRED`的错误([参见: Section 5.4](https://tools.ietf.org/html/rfc7540#section-5.4))来请求客户端使用支持重新协商的协议。 102 | 103 | > Implementations MUST support ephemeral key exchange sizes of at least 2048 bits for cipher suites that use ephemeral finite field Diffie- Hellman (DHE) [TLS12] and 224 bits for cipher suites that use ephemeral elliptic curve Diffie-Hellman (ECDHE) [RFC4492]. Clients MUST accept DHE sizes of up to 4096 bits. Endpoints MAY treat negotiation of key sizes smaller than the lower limits as a connection error (Section 5.4.1) of type INADEQUATE_SECURITY. 104 | 105 | 实现必须在最少支持2048位短暂密码套件(DHE)——使用短暂的迪菲-赫尔曼密钥交换([参见:TLS12](https://tools.ietf.org/html/rfc7540#ref-TLS12))和244位的密码套件(ecdhe)——使用短暂的椭圆曲线迪菲-赫尔曼密钥交换([参见:RFC4492](https://tools.ietf.org/html/rfc4492))中等支持密钥交换的加密套件中使用。客户端必须接受高达4096的`DHE`尺寸。终端可以把小于密钥最小尺寸的协商看作为类型为`INADEQUATE_SECURITY`连接错误([参见 Section 5.4.1](https://tools.ietf.org/html/rfc7540#section-5.4.1)) 106 | 107 | ### 9.2.2 TLS 1.2加密套件 108 | 109 | > A deployment of HTTP/2 over TLS 1.2 SHOULD NOT use any of the cipher suites that are listed in the cipher suite black list (Appendix A). 110 | 111 | 通过`TLS 1.2`进行的`HTTP/2`部署不应该使用任何流出在加密套件黑名单中的密码套件。 112 | 113 | > Endpoints MAY choose to generate a connection error (Section 5.4.1) of type INADEQUATE_SECURITY if one of the cipher suites from the black list is negotiated. A deployment that chooses to use a black- listed cipher suite risks triggering a connection error unless the set of potential peers is known to accept that cipher suite. 114 | 115 | 如果黑名单列表中的密码套件已经进行了协商,终端可以选择生成一个类型为`INADEQUATE_SECURITY`的连接错误。除非对等端接收这个密码套件,否则部署中选择使用黑名单中的密码套件会触发连接错误。 116 | 117 | > Implementations MUST NOT generate this error in reaction to the negotiation of a cipher suite that is not on the black list. Consequently, when clients offer a cipher suite that is not on the black list, they have to be prepared to use that cipher suite with HTTP/2. 118 | 119 | 黑名单包括密码套件,`TLS 1.2`是强制性的,这就意外着`TLS 1.2`的部署可能使用密码套件的非相交集。为了避免这个问题使得`TLS`的握手失败,通过`TLS 1.2`部署的`HTTP/2`必须支`TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`([参见:TLS-ECDHE](https://tools.ietf.org/html/rfc7540#ref-TLS-ECDHE))与P-256椭圆曲线(参见: [FIPS186](https://tools.ietf.org/html/rfc7540#ref-FIPS186))。 120 | 121 | > Note that clients might advertise support of cipher suites that are on the black list in order to allow for connection to servers that do not support HTTP/2. This allows servers to select HTTP/1.1 with a cipher suite that is on the HTTP/2 black list. However, this can result in HTTP/2 being negotiated with a black-listed cipher suite if the application protocol and cipher suite are independently selected. 122 | 123 | 需要注意的是为了允许连接不支持HTTP/2的服务器,客户端上可能宣传支持黑名单上的密码套件。这使得服务器用`HTTP/2`黑名单上的密码套件使用`HTTP/1.1`。然而,如果应用协议和加密套件是独立选择的,这可能会导致`HTTP/2`与黑名单上的密码套件进行协商。 -------------------------------------------------------------------------------- /3-zh-cn.md: -------------------------------------------------------------------------------- 1 | ## 3. Starting HTTP/2 / 开始 HTTP/2 2 | > An HTTP/2 connection is an application-layer protocol running on top of a TCP connection ([TCP]). The client is the TCP connection initiator. 3 | 4 | HTTP/2 是一个运行在 TCP 之上的应用层协议。客户端是 TCP 连接的发起者。 5 | 6 | > HTTP/2 uses the same "http" and "https" URI schemes used by HTTP/1.1. HTTP/2 shares the same default port numbers: 80 for "http" URIs and 443 for "https" URIs. As a result, implementations processing requests for target resource URIs like http://example.org/foo or https://example.com/bar are required to first discover whether the upstream server (the immediate peer to which the client wishes to establish a connection) supports HTTP/2. 7 | 8 | HTTP/2 使用和 HTTP/1.1 一样的 "http" 和 "https" 的 URL 模式。同时 HTTP/2 和 HTTP/1.1 也共享了相同的默认端口号:"http" 的 80 端口,"https" 的 443 端口。因此,实现者在处理类似 http://example.org/foo 或 https://example.com/bar 这样 URI 的目标资源请求之前,需要首先确定上游服务端(即当前客户端希望直接与之建立连接的对端)是否支持 HTTP/2。 9 | 10 | > The means by which support for HTTP/2 is determined is different for "http" and "https" URIs. Discovery for "http" URIs is described in Section 3.2. Discovery for "https" URIs is described in Section 3.3. 11 | 12 | 对于 "http" 和 "https" 两种 URI,检测是否支持 HTTP/2 的方法是不同的。检测 "http" 的 URI 在 3.2 节中描述。检测 "https" 的 URI 在 3.3 节中描述。 13 | 14 | ### 3.1 HTTP/2 Version Identification / HTTP/2 版本标识 15 | > The protocol defined in this document has two identifiers. 16 | > 17 | > * The string "h2" identifies the protocol where HTTP/2 uses Transport Layer Security (TLS) [TLS12]. This identifier is used in the TLS application-layer protocol negotiation (ALPN) extension [TLS-ALPN] field and in any place where HTTP/2 over TLS is identified. 18 | > 19 | > The "h2" string is serialized into an ALPN protocol identifier as the two-octet sequence: 0x68, 0x32. 20 | > * The string "h2c" identifies the protocol where HTTP/2 is run over cleartext TCP. This identifier is used in the HTTP/1.1 Upgrade header field and in any place where HTTP/2 over TCP is identified. 21 | > 22 | > The "h2c" string is reserved from the ALPN identifier space but describes a protocol that does not use TLS. 23 | 24 | 本文档定义的协议有两个标识符: 25 | 26 | * 字符串 "h2" 标示使用了 TLS(Transport Layer Security)*[TLS12]* 的 HTTP/2 协议。该标识符用在 TLS-ALPN(application-layer protocol negotiation)*[TLS-ALPN]* 的扩展字段,以及其他需要标示运行于 TLS 之上 HTTP/2 的地方。 27 | 28 | "h2" 字符串序列化成 ALPN 协议标识符时是两个字节的序列:0x68,0x32。 29 | 30 | * 字符串 "h2c" 标示运行在明文 TCP 之上的 HTTP/2 协议。该标识符用在 HTTP/1.1 的 Upgrade 首部字段,以及其他需要标示运行于 TCP 之上 HTTP/2 的地方。 31 | 32 | "h2c" 字符串保留在 ALPN 标识符空间,但是实际上标示了一个不使用 TLS 的协议。 33 | 34 | > Negotiating "h2" or "h2c" implies the use of the transport, security, framing, and message semantics described in this document. 35 | 36 | 协商 "h2" 或 "h2c" 需要用到本文档里描述的传输,安全,成帧和消息语义等概念。 37 | 38 | ### 3.2 Starting HTTP/2 for "http" URIs / 为 "http" URI 启用 HTTP/2 协议 39 | > A client that makes a request for an "http" URI without prior knowledge about support for HTTP/2 on the next hop uses the HTTP Upgrade mechanism (Section 6.7 of [RFC7230]). The client does so by making an HTTP/1.1 request that includes an Upgrade header field with the "h2c" token. Such an HTTP/1.1 request MUST include exactly one HTTP2-Settings (Section 3.2.1) header field. 40 | > 41 | > For example: 42 | > 43 | > ``` 44 | > GET / HTTP/1.1 45 | > Host: server.example.com 46 | > Connection: Upgrade, HTTP2-Settings 47 | > Upgrade: h2c 48 | > HTTP2-Settings: 49 | > ``` 50 | 51 | 客户端在发起一个 "http" URI 的请求时,如果事先不知道下一跳是否支持 HTTP/2 ,需要使用 HTTP Upgrade 机制(*[RFC7230]*的6.7节)。客户端首先发起一个 HTTP/1.1 请求,其中包含值为 "h2c" 的 Upgrade 首部字段。该请求还必须包含一个 HTTP2-Settings (3.2.1节)首部字段。 52 | 53 | 例如: 54 | 55 | ``` 56 | GET / HTTP/1.1 57 | Host: server.example.com 58 | Connection: Upgrade, HTTP2-Settings 59 | Upgrade: h2c 60 | HTTP2-Settings: 61 | ``` 62 | 63 | > Requests that contain a payload body MUST be sent in their entirety before the client can send HTTP/2 frames. This means that a large request can block the use of the connection until it is completely sent. 64 | 65 | 在客户端能发送 HTTP/2 帧之前,包含有效载荷的请求必须被全部发送。这意味着一个大尺寸的请求会独占连接, 直到它全部发送完毕。 66 | 67 | > If concurrency of an initial request with subsequent requests is important, an OPTIONS request can be used to perform the upgrade to HTTP/2, at the cost of an additional round trip. 68 | 69 | 对于一个具有后续请求的初始请求来说,如果它并发性十分重要,那么可以先发送一个 OPTIONS 类型的请求, 将协议升级到 HTTP/2, 但这样做会带来一个额外的往返开销。 70 | 71 | > A server that does not support HTTP/2 can respond to the request as though the Upgrade header field were absent: 72 | > 73 | > ``` 74 | > HTTP/1.1 200 OK 75 | > Content-Length: 243 76 | > Content-Type: text/html 77 | > ... 78 | > ``` 79 | 80 | 不支持 HTTP/2 的服务端响应请求时,可以认为 Upgrade 首部字段不存在: 81 | 82 | ``` 83 | HTTP/1.1 200 OK 84 | Content-Length: 243 85 | Content-Type: text/html 86 | ... 87 | ``` 88 | 89 | > A server MUST ignore an "h2" token in an Upgrade header field. Presence of a token with "h2" implies HTTP/2 over TLS, which is instead negotiated as described in Section 3.3. 90 | 91 | 服务端必须忽略值为 "h2" 的 Upgrade 首部字段。"h2" 标示使用 TLS 的 HTTP/2,其协商过程在 3.3 节中描述。 92 | 93 | > A server that supports HTTP/2 accepts the upgrade with a 101 (Switching Protocols) response. After the empty line that terminates the 101 response, the server can begin sending HTTP/2 frames. These frames MUST include a response to the request that initiated the upgrade. 94 | > 95 | > For example: 96 | > 97 | > ``` 98 | > HTTP/1.1 101 Switching Protocols 99 | > Connection: Upgrade 100 | > Upgrade: h2c 101 | > 102 | > [ HTTP/2 connection ... 103 | > ``` 104 | 105 | 支持 HTTP/2 的服务器响应状态码 101 (Switching Protocols) 表示接受升级协议的请求。在结束 101 响应的空行之后,服务端可以开始发送 HTTP/2 帧。这些帧必须包含一个对初始升级请求的响应。 106 | 107 | 例如: 108 | 109 | ``` 110 | HTTP/1.1 101 Switching Protocols 111 | Connection: Upgrade 112 | Upgrade: h2c 113 | 114 | [ HTTP/2 connection ... 115 | ``` 116 | 117 | > The first HTTP/2 frame sent by the server MUST be a server connection preface (Section 3.5) consisting of a SETTINGS frame (Section 6.5). Upon receiving the 101 response, the client MUST send a connection preface (Section 3.5), which includes a SETTINGS frame. 118 | 119 | 服务端发送的第一个 HTTP/2 帧必须是由一个 SETTINGS 帧(6.5节)组成的服务端连接前奏(3.5节)。客户端收到 101 响应之后,也必须发送一个包含 SETTINGS 帧的连接前奏。 120 | 121 | > The HTTP/1.1 request that is sent prior to upgrade is assigned a stream identifier of 1 (see Section 5.1.1) with default priority values (Section 5.3.5). Stream 1 is implicitly "half-closed" from the client toward the server (see Section 5.1), since the request is completed as an HTTP/1.1 request. After commencing the HTTP/2 connection, stream 1 is used for the response. 122 | 123 | 升级之前发送的 HTTP/1.1 请求被分配了一个有着默认优先级值(5.3.5节)的流标识符 1(5.1.1节)。流 1 暗示从客户端到服务端(5.1节)是半关闭的,因为该请求作为HTTP/1.1 请求已经完成了。HTTP/2 连接开始后,流 1 用于响应。 124 | 125 | #### 3.2.1 HTTP2-Settings Header Field / HTTP2-Settings 首部字段 126 | > A request that upgrades from HTTP/1.1 to HTTP/2 MUST include exactly one HTTP2-Settings header field. The HTTP2-Settings header field is a connection-specific header field that includes parameters that govern the HTTP/2 connection, provided in anticipation of the server accepting the request to upgrade. 127 | > 128 | > ``` 129 | > HTTP2-Settings = token68 130 | > ``` 131 | 132 | 从 HTTP/1.1 升级到 HTTP/2 的请求必须包含且只包含一个 HTTP2-Settings 首部字段。HTTP2-Settings 是一个连接相关的首部字段,它提供了用于管理 HTTP/2 连接的参数(前提是服务端接受了升级请求)。 133 | 134 | ``` 135 | HTTP2-Settings = token68 136 | ``` 137 | 138 | > A server MUST NOT upgrade the connection to HTTP/2 if this header field is not present or if more than one is present. A server MUST NOT send this header field. 139 | 140 | 如果该首部字段没有出现,或者出现了不止一个,那么服务端一定不要把连接升级到 HTTP/2。服务端一定不要发送该首部字段。 141 | 142 | > The content of the HTTP2-Settings header field is the payload of a SETTINGS frame (Section 6.5), encoded as a base64url string (that is, the URL- and filename-safe Base64 encoding described in Section 5 of [RFC4648], with any trailing '=' characters omitted). The ABNF [RFC5234] production for token68 is defined in Section 2.1 of [RFC7235]. 143 | 144 | HTTP2-Settings 首部字段的值是 SETTINGS 帧(6.5节)的有效载荷,被编码成了 base64url 串(即,*[RFC4648]*第 5 节描述的 URL 和文件名安全 Base64 编码,忽略任何结尾'='字符)。ABNF*[RFC5234]*产生 token68 在*[RFC7235]*2.1节有定义。 145 | 146 | > Since the upgrade is only intended to apply to the immediate connection, a client sending the HTTP2-Settings header field MUST also send HTTP2-Settings as a connection option in the Connection header field to prevent it from being forwarded (see Section 6.1 of [RFC7230]). 147 | 148 | 因为升级操作只适用于相邻端点的直连,发送 HTTP2-Settings 首部字段的客户端也必须在发送的 Connection 首部字段值里加上 HTTP2-Settings ,防止它被转发(参见*[RFC7230]*的 6.1 节)。 149 | 150 | > A server decodes and interprets these values as it would any other SETTINGS frame. Explicit acknowledgement of these settings (Section 6.5.3) is not necessary, since a 101 response serves as implicit acknowledgement. Providing these values in the upgrade request gives a client an opportunity to provide parameters prior to receiving any frames from the server. 151 | 152 | 就像对其他的 SETTINGS 帧那样,服务端对这些值进行解码和解释。对这些设置(6.5.3节)进行显式的确认是没有必要的,因为 101 响应本身就相当于隐式的确认。升级请求中提供这些值,让客户端有机会在收到服务端的帧之前就设置一些参数。 153 | 154 | ### 3.3 Starting HTTP/2 for "https" URIs / 为 "https" URI 启用 HTTP/2 协议 155 | > A client that makes a request to an "https" URI uses TLS [TLS12] with the application-layer protocol negotiation (ALPN) extension [TLS-ALPN]. 156 | 157 | 客户端对 "https" URI 发起请求时使用 TLS-ALPN(带有应用层协议协商扩展 (ALPN) 的 TLS [TLS12])。 158 | 159 | > HTTP/2 over TLS uses the "h2" protocol identifier. The "h2c" protocol identifier MUST NOT be sent by a client or selected by a server; the "h2c" protocol identifier describes a protocol that does not use TLS. 160 | 161 | 运行在 TLS 之上的 HTTP/2 使用"h2"协议标识符。此时,客户端不能发送 "h2c" 协议标识符,服务端也不能选择 "h2c" 协议标识符;"h2c" 协议标识符表示 HTTP/2 不使用 TLS。 162 | 163 | > Once TLS negotiation is complete, both the client and the server MUST send a connection preface (Section 3.5). 164 | 165 | 一旦 TLS 协商完成,客户端和服务端都必须发送一个连接序言(3.5节)。 166 | 167 | ### 3.4 Starting HTTP/2 with Prior Knowledge / 先验知识下启用 HTTP/2 168 | > A client can learn that a particular server supports HTTP/2 by other means. For example, [ALT-SVC] describes a mechanism for advertising this capability. 169 | 170 | 客户端可以通过其他方式了解服务端是否支持 HTTP/2。例如 *[ALT-SVC]* 就描述了一种广播服务端能力的机制。 171 | 172 | > A client MUST send the connection preface (Section 3.5) and then MAY immediately send HTTP/2 frames to such a server; servers can identify these connections by the presence of the connection preface. This only affects the establishment of HTTP/2 connections over cleartext TCP; implementations that support HTTP/2 over TLS MUST use protocol negotiation in TLS [TLS-ALPN]. 173 | 174 | 客户端必须先向这种服务端发送连接序言(3.5),然后可以立即发送 HTTP/2 帧。服务端能通过连接序言识别出这种连接。这只影响基于明文 TCP 的 HTTP/2 连接。基于 TLS 的 HTTP/2 实现必须使用 TLS 中的协议协商*[TLS-ALPN]*。 175 | 176 | > Likewise, the server MUST send a connection preface (Section 3.5). 177 | 178 | 同样,服务端也必须发送一个连接序言(3.5节)。 179 | 180 | > Without additional information, prior support for HTTP/2 is not a strong signal that a given server will support HTTP/2 for future connections. For example, it is possible for server configurations to change, for configurations to differ between instances in clustered servers, or for network conditions to change. 181 | 182 | 在没有额外的参考信息的情况下,某个服务端先前支持 HTTP/2 并不能表明它在以后的连接中仍会支持 HTTP/2。例如,服务端配置有可能改变了,或者集群中不同服务器配置有差异,或者网络状况改变了。 183 | 184 | ### 3.5 HTTP/2 Connection Preface / HTTP/2 连接序言 185 | > In HTTP/2, each endpoint is required to send a connection preface as a final confirmation of the protocol in use and to establish the initial settings for the HTTP/2 connection. The client and server each send a different connection preface. 186 | 187 | 在 HTTP/2 连接中,要求两端都要发送一个连接序言,作为对所使用协议的最终确认,并确定 HTTP/2 连接的初始设置。客户端和服务端各自发送不同的连接序言。 188 | 189 | > The client connection preface starts with a sequence of 24 octets, which in hex notation is: 190 | > 191 | > ``` 192 | > 0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a 193 | > ``` 194 | > That is, the connection preface starts with the string PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n). This sequence MUST be followed by a SETTINGS frame (Section 6.5), which MAY be empty. The client sends the client connection preface immediately upon receipt of a 101 (Switching Protocols) response (indicating a successful upgrade) or as the first application data octets of a TLS connection. If starting an HTTP/2 connection with prior knowledge of server support for the protocol, the client connection preface is sent upon connection establishment. 195 | 196 | 客户端连接序言以一个24字节的序列开始,用十六进制表示为: 197 | 198 | ``` 199 | 0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a 200 | ``` 201 | 202 | 连接序言以字符串 "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" 开始。这个序列后面必须跟一个可以为空的 SETTINGS 帧(6.5节)。客户端一收到 101(Switching Protocols) 响应(表示成功升级)后,就发送客户端连接序言,或者作为 TLS 连接的第一批应用数据字节。如果在预先知道服务端支持 HTTP/2 的情况下启用 HTTP/2 连接,客户端的连接序言在连接建立时发送。 203 | 204 | > Note: The client connection preface is selected so that a large proportion of HTTP/1.1 or HTTP/1.0 servers and intermediaries do not attempt to process further frames. Note that this does not address the concerns raised in [TALKING]. 205 | 206 | 注意:客户端连接前奏是专门挑选的,目的是为了让大部分 HTTP/1.1 或 HTTP/1.0 服务器和中介不会试图处理后面的帧,但这并没有解决在 *[TALKING]* 中提出的问题。 207 | 208 | > The server connection preface consists of a potentially empty SETTINGS frame (Section 6.5) that MUST be the first frame the server sends in the HTTP/2 connection. 209 | 210 | 服务端连接前奏包含一个可能为空的 SETTINGS 帧(6.5节),它必须是服务端在 HTTP/2 连接中发送的第一个帧。 211 | 212 | > The SETTINGS frames received from a peer as part of the connection preface MUST be acknowledged (see Section 6.5.3) after sending the connection preface. 213 | 214 | 在发送完本端的连接前奏之后,必须对来自对端的作为连接前奏一部分的 SETTINGS 帧进行确认。 215 | 216 | > To avoid unnecessary latency, clients are permitted to send additional frames to the server immediately after sending the client connection preface, without waiting to receive the server connection preface. It is important to note, however, that the server connection preface SETTINGS frame might include parameters that necessarily alter how a client is expected to communicate with the server. Upon receiving the SETTINGS frame, the client is expected to honor any parameters established. In some configurations, it is possible for the server to transmit SETTINGS before the client sends additional frames, providing an opportunity to avoid this issue. 217 | 218 | 为了避免不必要的时延,允许客户端发送完连接前奏后就立即向服务端发送其他的帧,而不必等待服务端的连接前奏。不过需要注意的是,服务端连接前奏的 SETTINGS 帧可能包含一些期望客户端如何与服务端进行通信所必须修改的参数。在收到这些 SETTINGS 帧以后,客户端应当遵守所有设置的参数。在某些配置中,服务端是可以在客户端发送额外的帧之前传送 SETTINGS 帧的,这样就避免了之前所说的问题。 219 | 220 | > Clients and servers MUST treat an invalid connection preface as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. A GOAWAY frame (Section 6.8) MAY be omitted in this case, since an invalid preface indicates that the peer is not using HTTP/2. 221 | 222 | 客户端和服务端都必须将无效的连接前奏处理为连接错误(5.4.1节),错误类型为 PROTOCOL_ERROR。在这种情况下,可以不发送 GOAWAY 帧(6.8节),因为无效的连接前奏表示对端并没有使用 HTTP/2。 223 | 224 | 225 | -------------------------------------------------------------------------------- /5-zh-cn.md: -------------------------------------------------------------------------------- 1 | # 5. 流和多路复用 2 | 3 | 在一个HTTP/2的连接中, 流是服务器与客户端之间用于帧交换的一个独立双向序列. 流有几个重要的特点: 4 | 5 | + 一个HTTP/2连接可以包含多个并发的流, 各个端点从多个流中交换frame 6 | + 流可以被客户端或服务器单方面建立, 使用或共享 7 | + 流也可以被任意一方关闭 8 | + frames在一个流上的发送顺序很重要. 接收方将按照他们的接收顺序处理这些frame. 特别是`HEADERS`和`DATA` frame的顺序, 在协议的语义上显得尤为重要. 9 | + 流用一个整数(流标识符)标记. 端点初始化流的时候就为其分配了标识符. 10 | 11 | ## 5.1 流的状态 12 | 13 | 下图展示了流的生存周期: 14 | 15 | ``` 16 | +--------+ 17 | send PP | | recv PP 18 | ,--------| idle |--------. 19 | / | | \ 20 | v +--------+ v 21 | +----------+ | +----------+ 22 | | | | send H / | | 23 | ,------| reserved | | recv H | reserved |------. 24 | | | (local) | | | (remote) | | 25 | | +----------+ v +----------+ | 26 | | | +--------+ | | 27 | | | recv ES | | send ES | | 28 | | send H | ,-------| open |-------. | recv H | 29 | | | / | | \ | | 30 | | v v +--------+ v v | 31 | | +----------+ | +----------+ | 32 | | | half | | | half | | 33 | | | closed | | send R / | closed | | 34 | | | (remote) | | recv R | (local) | | 35 | | +----------+ | +----------+ | 36 | | | | | | 37 | | | send ES / | recv ES / | | 38 | | | send R / v send R / | | 39 | | | recv R +--------+ recv R | | 40 | | send R / `----------->| |<-----------' send R / | 41 | | recv R | closed | recv R | 42 | `----------------------->| |<----------------------' 43 | +--------+ 44 | 45 | send: 发送这个frame的终端 46 | recv: 接受这个frame的终端 47 | 48 | H: HEADERS帧 (隐含CONTINUATION帧) 49 | PP: PUSH_PROMISE帧 (隐含CONTINUATION帧) 50 | ES: END_STREAM标记 51 | R: RST_STREAM帧 52 | ``` 53 | 54 | 该图只展示了流的状态转换以及frame和标记如何对转换产生影响. 这方面, `CONTINUATION`frames不会导致状态的转换, 他们只是跟在`HEADERS`或`PUSH_PROMISE` frame后面的有效组成部分. 55 | 56 | 状态转换的用途, 对于设置了`END_STREAM`标记的frame来说, `END_STREAM`被当做一个分开的事件处理. 设置了`END_STREAM`标记的`HEADERS` frame会导致两次状态转换. 57 | 58 | 在传输过程中, 每个端点对流状态的主观认识可能不同. 这些终端不会协商流的创建, 都是由终端独立创建的. 端点的流状态不同会带来负面影响: 在发送了`RST_STREAM`之后流处于关闭状态, 而frame可能在流关闭之后才到达. 59 | 60 | 流有如下状态: 61 | 62 | + `idle` 63 | 所有流最初状态都是`idle`. 64 | 下面描述了流从`idle`状态到其它状态的几种可能转换: 65 | 66 | - 发送或接收到一个`HEADERS`frame会使流状态变换`open`. 流标识符的选择参见5.1.1里的描述. 收到相同的`HEADERS`frame会导致流立即变为`half-close`状态. 67 | - (Sending a PUSH\_PROMISE frame on another stream reserves the idle stream that is identified for later use.)在另一个流上发送一个`PUSH_PROMISE`frame 被标识为以后使用. 预留流的状态对应转换到`reserved (local)`. 68 | - (Receiving a PUSH\_PROMISE frame on another stream reserves an idle stream that is identified for later use.)在另一个流上接收一个`PUSH_PROMISE`frame 被标识为以后使用. 预留流的状态对应转换到`reserved (remote)`. 69 | - 注意`PUSH_PROMISE`frame并不在idle流上发送, 只是promised流的ID字段引用了新的reserved流. 70 | 71 | 在`idle`状态接收到任何非`HEADERS`或`PUSH_PROMISE`frame必须视为连接错误, 错误类型为`PROTOCOL_ERROR` 72 | 73 | + `reserved (local)` 74 | 处于这种状态的流表示它已经发送了一个`PUSH_PROMISE`frame并成为promised流. `PUSH_PROMISE`frame通过关联一个由远程对等点初始化的流来转换idle流到reserved流. 75 | 处于这个状态的流, 只有下面的几种可能状态转换: 76 | 77 | - 端点发送一个`HEADERS`frame, 流进入`half-closed (remote)`状态. 78 | - 任何一个端点发送一个`RST_STREAM`frame, 流变成`closed`状态. 这将释放一个流保留的资源. 79 | 80 | 端点不准发送除`HEADERS`, `RST_STREAM`或`PRIORITY`之外任何类型的frame. 81 | 82 | 这一状态可能收到`PRIORITY`或`WINDOW_UPDATE`frame. 除了`RST_STREAM`, `PRIORITY`以及`WINDOW_UPDATE`frame之外, 收到其他类型的frame必须视为`PROTOCOL_EROR`类型的连接错误. 83 | 84 | + `reserved (remote)` 85 | 如果一个流已被远程对等点保留, 状态就会变成`reserved(remote)`. 86 | 可能的转换如下: 87 | 88 | - 收到一个HEADERS frame导致状态变为half-close(local) 89 | - 任何端点发送一个`RST_STREAM`frame会导致状态变成`closed`, 并释放流保留的资源. 90 | 91 | 端点可以发送一个PRIORITY frame以重新确定reserved流的优先级次序. 不允许发送除RST_STREAM, WINDOW_UPDATE或PRIORITY之外的frame. 92 | 93 | 在一个流上拿到非HEADERS, RST_STREAM或PRIORITY的frame必须视为`PROTOCOL_EROR`类型的连接错误. 94 | 95 | + `open` 96 | 任何一对等方可以使用open状态的流发送任意类型的frame. 这一状态下, 发送方会监视给出的流级别和流控范围. 97 | 98 | 在任意一方发送设置了END_STREAM标记的frame后, 流状态会变为half-closed的其中一个状态: 如果一方发送了该frame, 其流变为half-closed(local); 如果一方收到该frame, 流变为half-closed(remote). 99 | 100 | 在这个状态发送RST_STREAM frame可以使状态立即变成closed. 101 | 102 | + `half-closed (local)` 103 | 处于这个状态的流不能发送除WINDOW\_UPDATE, PRIORITY以及RST\_STREAM之外的frame. 104 | 105 | 收到一个标记了END_STREAM的frame或者发送一个RST_STREAM frame, 都会使状态变成closed. 106 | 107 | 端点允许接收任意类型的frame. 便于后续接收用于流控的frame, 使用WINDOW_UPDATE frame提供流控credit很有必要. 接收方可以选择忽略WINDWO_UPDATE frame, (which might arrive for a short period after a frame bearing the END_STREAM flag is sent.) 108 | 109 | 收到的PRIORITY frame用于重定流的优先级次序(依据流的标记而定) 110 | 111 | + `half-closed (remote)` 112 | 处于这个状态的流,对端不再用来发送frame了. 并且端点也无需继续维护接收方流控窗口. 113 | 114 | 如果端点收到额外的frame,并且不是WINDOW_UPDATE, PRIORITY或RST_STREAM,那么必须响应一个类型为STREAM_CLOSED的流错误. 115 | 116 | 这一状态下的流可以发送任意类型的frame. 端点仍会继续监视已知的流级别和流控范围. 117 | 118 | 发送一个END_STERAM标记的frame或任意一个对等方发送了RST_STREAM frame都会使流变为closed. 119 | 120 | + `closed` 121 | closed标识终止状态. 122 | 123 | 在一个closed的流上不允许发送PRIORITY之外的其他frame. 端点在收到RST_STREAM frame后又收到非PRIORITY的frame的话, 一定被视为流错误对待(类型STREAM_CLOSED). 124 | 125 | 同样, 收到END_STREAM标记后又收到**非如下描述**的frame, 会触发一个连接错误(类型STREAM_CLOSED): 126 | 127 | 发送了包含END_STREAM标记的DATA或HEADERS frame后的一小段时间内, 允许WINDOW_UPDATE或RST_STREAM frame被接收. 直到远程对等端收到并处理了RST_STERAM或包含END_STREAM标记的frame, 才可以发送这些类型的frame. 128 | 假如在发送了END_STREAM后已明显过了超时时间, 这时却再次收到frame, 尽管终端可以选择把这个frame当成PROTOCOL_ERROR类型的连接错误来处理, 但无论如何最终**必须**忽略这种情况下收到的WINDOW_UPDATE或RST_STREAM frame. 129 | 130 | PRIORITY帧可从closed流上发到优先级更高的流(取决于closed流). 终端应该处理PRIORITY帧, 尽管他们可能因为流已经从依赖树中移除而被忽略. 131 | 132 | 如果是发送RST_STREAM帧的原因让状态转换到了closed, 收到RST_STREAM的对等端这时可能已经发送了RST_STREAM或者入队等待发送中, 但是已经在流上传输的帧是不可以被撤销的. 这时, 终端必须忽略从closed的流上再取得的帧, 如果这个closed流已经发送了RST_STREAM帧. 终端也可以选择一个超时时间, 忽略在此之后到达的帧, 并一律视作错误. 133 | 134 | 在发送了RST_STREAM之后收到的流控帧(比如DATA帧)也会被用于计算当前连接的流控窗口.(are counted toward the connection flow-control window.) 尽管这些帧有可能被忽略掉, 但是因为他们在发送方收到RST_STREAM之前被发送了, 所以发送方仍有可能会根据这些帧计算流控窗口大小. 135 | 136 | 终端发送了RST_STREAM帧之后可以再接收一个PUSH_PROMISE帧. PUSH_PROMISE帧会将流状态变为reserved即使相关的流已经被重置. 因此需要一个RST_STREAM帧去关闭不再需要的promised流. 137 | 138 | 本文档中没有给出更具体说明的地方, 对于收到的那些未在上述状态描述中明确认可的帧, 协议实现上应该视这种情况为一个类型为PROTOCOL_ERROR的连接错误. 另外注意PRIORITY帧可以在流的任何一个状态被发送/接收. 忽略未知类型的帧. 139 | 140 | ### 5.1.1 Stream标识符 141 | 142 | 每个流都用31位无符号整型标识. 客户端初始化流时必须使用奇数做标识, 而那些被服务器初始化的流则要使用偶数做标识. 注: 流标识符0x0用于连接控制消息, 不能用于建立一个新的流. 143 | 144 | 用于升级到HTTP/2的HTTP/1.1请求会以一个0x1为标识的流响应. 升级完成后, 客户端流0x1处于half-closed(local)状态. 因此, 0x1不能被客户端(从HTTP/1.1升级过来的)选作新的流标示符. 145 | 146 | 新建立的流标识符必须在数字排序上大于所有由该端系统已打开或保留的流. 这个要求制约了HEADERS帧打开的流和PUSH_PROMISE帧保留的流. 当接收到不期望的标识符时, 端系统必须响应一个类型为PROTOCOL_ERROR的连接错误. 147 | 148 | 首次使用一个新的流标识符会隐式关闭所有该端系统初始化的处于idle状态且标识符更小的流. 就是说, 如果一个客户端通过7号流发送了一个HEADERS帧, 并且它尚未使用5号流发送过帧, 那么当7号流上的第一个帧已发送或接收时, 5号流就会变为closed状态. 149 | 150 | 流标识符不能被重用. 而长连接会占用端系统的流标识符可用空间. 如果一个客户端无法建立新的流了, 那么他可以选择建立新连接来创建新的流. 同样, 当服务器不能建立新的流时, 可以发送一个GOAWAY帧以便客户端强制打开一个到服务器的新连接来创建新的流. 151 | 152 | ### 5.1.2 流的并发性 153 | 154 | 一个对等端可以通过SETTINGS帧的`SETTINGS_MAX_CONCURRENT_STREAMS`字段限制活跃状态的流的并发数, 流的最大并发量设置是特定于每个端系统而言的, 并且只作用于收到设置的对等端. 也就是说, 客户端指定服务器可用来初始化流的最大并发数, 反之亦然. 155 | 156 | 处于open或half-closed状态的流, 其数量受最大可打开流数量所限. 任意这三种状态(译注: half-closed包括remote和local两种状态)的流数量都受到`SETTINGS_MAX_CONCURRENT_STREAMS`的限制. 而reserved状态的流则没这种限制. 157 | 158 | 端系统的配置不准超过由其对等端所设置的最大限度. 如果一个端系统收到了HEADERS帧, 并且帧的设置超过了该端系统的流最大并发限制, 那么这种情况必须视为一个类型为PROTOCOL_ERROR或REFUSED_STREAM的流错误来对待, 错误码的选择取决于端系统是否希望自动重试(详见8.1.4章节). 159 | 160 | 如果一个端系统希望减小`SETTINGS_MAX_CONCURRENT_STREAMS`到一个比当前打开流的总量还要低的一个值, 两种情况可供选择: 或者直接关闭那些超过限制的流, 或者等待这些流完成传输. 161 | 162 | ## 5.2 流控 163 | 164 | 流的多路复用会让TCP连接的使用产生竞争, 这会导致流的阻塞. 流控手段确保同一连接上的流互相之间不会产生严重的妨碍. 流控既可用于某个单独的流, 也可用于整个连接. 165 | 166 | HTTP/2通过使用WINDOW_UPDATE帧提供了流控功能. 167 | 168 | ### 5.2.1 流控原则 169 | 170 | HTTP/2流允许在不修改原有协议的基础上使用一系列流控算法. 流控具有以下特点: 171 | 172 | 1. 流控针对于连接. 所有类型的流控都作用于两个单跳的端系统之间, 而非整个端到端链路. 173 | 2. 流控基于WINDOW\_UPDATE帧实现. 接收者告知他们准备在一个流上以及整个连接上分别接收多少字节. 这属于基于信用的模型. 174 | 3. 流控具有方向性, 且完全由接收者控制. 接收方可以选择给每个流和整个连接设置期望的任意窗口大小. 发送方必须遵循接收者施加的流控限制. 所有客户端和服务器以及中间设施, 作为接收方均独立声明其流控窗口, 并在发送时同样遵循其对等端设置的流控限制. 175 | 4. 对于所有的流和连接, 流控窗口的初始大小是65535字节(2^16). 176 | 5. 帧的类型也决定了是否要在这个帧上应用流控. 对于这篇文档中提到的帧, 只有DATA帧是流控的作用对象. 其他所有类型的帧均不占用流控窗口空间, 这保证重要的控制帧不会因流控被阻塞. 177 | 6. 流控不能被禁用 178 | 7. HTTP/2只定义了WINDOW\_UPDATE帧的格式和语义. 这篇文当中并未规定接收者何时发送这个帧或是值如何设定, 同样没有规定发送者如何选择发送分组. 协议的实现允许选择任意一种符合其需求的算法. 179 | 180 | 协议的实现也需要负责: 管理基于优先级发送请求和响应, 选择避免请求的队首阻塞, 以及管理流的创建. 这些选择算法可以与任何流控算法协同工作. 181 | 182 | ### 5.2.2 合理使用流控 183 | 184 | 流控的目的是保护端系统使之在资源约束下执行操作. 例如, 一个代理服务器需要在许多连接之间共享内存, 这些连接里可能有一条速度比较慢的上游连接和一条比较快的下游连接. 流控关注的情况是: 接收者尚未处理完一个流上的数据, 然而想要处理同一连接上其他流的数据. 185 | 186 | 如果部署时不需要这个功能, 可以把流控窗口设为最大值(2^31-1), 并在收到任意数据时发送一个WINDOW_UPDATE帧. 这相当于禁用了接收方的流控限制. 相反地, 发送方总是遵循接收方告之的流控窗口. 187 | 188 | 有资源约束情况下的部署, 可以使用流控来限制对等方可以消费的资源(比如内存). 需要注意的是, 如果不了解**带宽时延积**就启用了流控, 对于可用的网络资源来说这可能并非是最优的使用方案.(见译注) 189 | 190 | 即便对当前网络的带宽时延积有了充分的了解, 流控的实现也是很难的. 启用流控时, 接收方必须要立刻读取TCP的接收缓冲区, 否则达到了临界点时, 对于WINDOW\_UPDATE来说, 这时既不能读取也不能采取其他行动, 就会导致死锁产生. 191 | 192 | > **译注** 193 | 194 | > 带宽时延积: 即链路上的最大比特数,也称以比特为单位的链路长度. 计算方法: 带宽 × ACK时延 195 | 196 | > 实际传输数据的时候不可能每个报文发送后就立即收到确认,如果每报文等待确认就会导致传输速率变慢,所以TCP允许在没收到上一个确认前发送下N个报文,但是发送报文不能超过窗口大小,如果窗口\<带宽时延积,就会导致有些响应报文还未到达发送端时,发送端就已经达到窗口大小,这时发送端就必须重新发送之前的报文(而实际上接收端已经有响应了,只是未到达发送端),这样就会导致报文有大量重传,叠加效应就会导致传输速度远低于带宽(被无用的重传给占用了) 197 | 198 | > 相反,窗口足够大,发送端连续发送的N个报文都能在窗口内收到响应,不会有数据重传,理论上的传输速度就会等于带宽值. 199 | 200 | ## 5.3 流的优先级 201 | 202 | 客户端可以给一个新的流分配一个优先级, 做法是在用来打开流的HEADERS帧中包含优先次序信息. 在其他任何时间, 可以用PRIORITY帧改变一个流的优先级. 203 | 204 | 优先次序的目的是在并发流管理的时候, 允许端系统选择它所期望的对等端分配资源方式. 最重要的是, 当发送受到限制的情况下, 可以通过优先级选择使用哪个流来传输帧. 205 | 206 | 流可以通过被标记为其他流完成的依赖的方法赋予优先级. 每个依赖被赋予一个相对权重, 它用一个数值表示. 对于依赖这个流的其他流拥有的可用资源, 这个数值决定了的他们的相对比重. 207 | 208 | 显式设置过优先级的流将被优先安排. 但这种优先并不保证一个优先级高的流能得到优先处理或者优先传输. 端系统不能用优先级强迫其对等方按照特定顺序处理并发流. 所以说, 优先级仅仅作为一种建议存在. 209 | 210 | 可以忽略消息中的优先级信息. 默认情况下使用显式提供的任何优先级值. 211 | 212 | ### 5.3.1 流的依赖关系 213 | 214 | 每个流可以显式指定依赖其他的流. 如果流被其他流所依赖, 这就表明这个流在资源的分配上优先于它的从属流. 215 | 216 | 不依赖其他任何流的流, 会被隐式指定依赖标识符为0x0的流. 换句话说, 并非实际存在的流0x0成为了依赖树的根节点. 217 | 218 | 依赖于其他流的流称作一个从属流. 上游被依赖的流称作上级流. 如果一个流的依赖项目前不在依赖树中(比如idle状态的流), 219 | 这个流就会被赋予默认优先级. 220 | 221 | 当给一个流添加依赖时, 这个流就成为上级流的一个新依赖项. 共享同一个上级流的多个从属流之间并没有严格的顺序要求. 222 | 比如, 流B和C依赖于流A, 并且流D在创建时也把A作为依赖添加进来, 那么A的依赖项顺序可以是任意的(BCD/DBC...): 223 | 224 | ``` 225 | A A 226 | / \ ==> /|\ 227 | B C B D C 228 | ``` 229 | 230 | 一个专属(exclusive)标记允许新依赖等级的插入. 拥有专属标记的流会成为其上级流的唯一依赖项, 231 | 而上级流的其余依赖项会变成这个专属流的依赖项. 在前一个例子中, 如果使用一个对A的专属依赖创建D, 232 | 那么D就会变成B和C的上级流: 233 | 234 | ``` 235 | A 236 | A | 237 | / \ ==> D 238 | B C / \ 239 | B C 240 | ``` 241 | 242 | 对于依赖树内部的一个从属流, 直到它依赖的所有流(包括上级流依赖链上的流, 直到0x0)都已处于closed状态, 243 | 或者它不可能再使用这些上级流时, 它才能被分配到到资源. 244 | 245 | 流不可以依赖自身. 否则端系统必须将此视作类型为PROTOCOL_ERROR的流错误. 246 | 247 | ### 5.3.2 依赖权重 248 | 249 | 所有的从属流会分配到一个介于[1, 256]之间的整数, 表示权重. 250 | 251 | 依赖于相同上级的流应该依据其权重比例分配资源. 因此, 如果权重为4的流B和权重为12的流C都依赖于流A, 252 | 并且A上不会有任何动作, 那么B会分得1/4的资源, C分得3/4的资源. 253 | 254 | ### 5.3.3 优先级(依赖)重排 255 | 256 | 流的优先级可以通过PRIORITY帧来改变. 添加依赖会让这个流对其上级流产生依赖关系. 257 | 258 | 如果上级流重置了优先级, 它的从属流也会跟随其变化. 259 | 给重值优先级的流添加带有专属标记的依赖会导致其上级流的所有依赖项成为这个重置优先级的流的依赖项. 260 | 261 | 如果流把它的一个依赖项做为一个新的依赖, 那么之前的从属流首先会成为重置优先级的流(译注: 当前描述的流)的前一个上级的依赖项. 262 | 而那些被移动的依赖项的权重不会改变. 263 | 264 | 考虑这样一棵依赖树: B和C依赖于A, D和E依赖于C, F依赖于D. 如果把A设成D的一个依赖项(即A依赖D), 265 | 那么最后D就会替换A在树中的位置. 所有其他的依赖关系保持不变, 除非用专属标记重置了A的优先级(这会导致F直接依赖于A). 266 | 267 | ``` 268 | x x x x 269 | | / \ | | 270 | A D A D D 271 | / \ / / \ / \ | 272 | B C ==> F B C ==> F A OR A 273 | / \ | / \ /|\ 274 | D E E B C B C F 275 | | | | 276 | F E E 277 | (中间过程) (未使用专属标记) (使用了专属标记) 278 | ``` 279 | 280 | ### 5.3.4 优先级状态管理 281 | 282 | 当一个流从依赖树中被移除时, 它的依赖项可能直接变成它直接上级流的依赖项, 之后会依据这些依赖项在直接上级流的原有依赖项所占权重比例来重新计算新的依赖项权重. 283 | 284 | 从依赖树中移除流会导致一些优先级信息的丢失. 资源是在具有相同上级流的从属流之间共享的, 这意味着如果这些从属流中有一个处于关闭状态或阻塞住了, 其上分配到任何闲置资源将重新分配到其临近的流上. 如果公共的依赖项被移除, 那么对依赖项有依赖的那些流会和上一层的流共享资源. 285 | 286 | 例如, 假如流A和流B共享同一个上级流, 并且流C和流D都依赖流A. 移除流A之前, 如果A和D不再使用, 那么流C接收流A专享的所有资源. 如果流A被移除, 它的权重会在C和D之间分配. 如果流D仍无法继续使用, 那么流C得到的资源比重会减小. 依据平等的初始权重, C能得到1/3而非1/2的可用资源. 287 | 288 | 一个流上的优先级信息正在变化时, 这个流可能变成closed了. 如果一个依赖项中有标识的流并没有对应的的优先级信息, 那么它的从属流会替代它分配一个默认的优先级. 这潜在的创建一个非最优的优先级, 因为瘤可能分配到一个并非预期的优先级. 289 | 290 | 为了避免这些问题, 在流closed之后, 端系统还应该保存一段时间流的优先级状态. 保存的时间越长, 流分得非预期或默认优先级的可能性就越小. 291 | 292 | 同样地, idle状态的流可能被分配优先级或成为其他流的上级. 这就相当于在依赖书中创建一个节点组, 同时也赋予了优先级更灵活的表达方式. idle流最初被分配了默认优先级. 293 | 294 | 流上优先级信息的保留不受SETTINGS_MAX_CONCURRENT_STREAMS值的影响, 因此为了维护这些信息可能会给一个端系统带来巨大的负担. 因此, 可能需要限制一下保存的优先级状态信息的数量. 295 | 296 | 端系统维护的额外状态信息数量可以依负载而定. 高负载情况下, 可以取消优先级状态以防止资源的不合理使用. 极端情况下, 端系统甚至可以取消活跃的或reserved流的优先级状态. 如果施加了限制, 端系统应该至少维护和每个流所设置的SETTINGS_MAX_CONCURRENT_STREAMS一样多的状态. 协议的实现也应该尽量为优先级树中正在使用的流保存状态. 297 | 298 | 如果已经保存了足够多的状态来改变优先级, 端系统通过接收一个PRIORITY帧来改变一个closed流优先级, 那么它应该修改这个流的依赖项. 299 | 300 | ### 5.3.5 默认优先级 301 | 302 | 所有的流初始化时都会成为0x0的非专属依赖. 推送流在初始化时则依赖于和它们相关联的流. 303 | 不管何时, 流的默认权重都是16. 304 | 305 | ## 5.4 错误处理 306 | 307 | HTTP/2成帧过程产生的错误会分为两类: 308 | 309 | + 当一个错误导致整个连接不可用时, 这种情况视为一个连接错误. 310 | + 独立于流的错误属于流错误. 311 | 312 | 错误码的列表包含在[第七节](https://github.com/abbshr/rfc7540-translation-zh_cn/blob/master/7-zh-cn.md). 313 | 314 | ### 5.4.1 连接错误处理 315 | 316 | 任何妨碍帧处理过程或破坏任何连接状态的错误都属于连接错误. 317 | 318 | 当一个端系统遭遇了连接错误时应该首先通过最后与其对等端成功交互的流发送一个GOAWAY帧. GOAWAY帧包含一个用于说明连接终止原因错误码. 发送了GOAWAY帧之后, 端系统必须要关闭TCP连接. 319 | 320 | 对等方很有可能收不到这个GOAWAY帧 ([RFC7230中6.6小节](https://tools.ietf.org/html/rfc7230#section-6.6)描述了立即关闭的连接如何导致的数据丢失). 在连接错误发生的情况下, GOAWAY帧只是"尽力而为"的尝试与其接收对等端交流, 告诉它为何终止了连接. 321 | 322 | 一个端系统可以在任何时间结束连接. 特别是, 端系统可以选择性的将流错误视为连接错误. 端系统在断开连接时应该发送一个GOAWAY帧, 所以提供的时候就发送它. 323 | 324 | ### 5.4.2 流错误处理 325 | 326 | 流错误是与一个特定的流有关的错误, 并且它不会影响其他流的处理. 327 | 328 | 端系统检测到流错误发生时发送一个RST_STREAM帧, 包含了发生错误的流的标识符. 除此之外还包含一个表明错误类型的错误码. 329 | 330 | RST_STREAM是端系统可以在一个流上发送的最后一个帧. 发送RST_STREAM帧的对等端必须准备接收其远程端点发送的任何正在传输链路上或入队等待发送的帧. 可以忽略那些不会改变连接状态的帧 (比如维护头部压缩的状态或流控). 331 | 332 | 通常情况下, 端系统不应该在任何一个流上发送多于一个的RST_STERAM帧. 然而, 如果在多于一个RTT的时间里, 端系统再次从一个已经closed的流上收到了帧, 那么它就可以发送额外的RST_STREAM帧. 后面描述这一行为用于对付那些未严格遵守标准的协议实现. 333 | 334 | 为了避免循环发送, 端系统不允许再以一个RST_STREAM作为对接收到的RST_STREAM的响应. 335 | 336 | ### 5.4.3 连接终止 337 | 338 | 如果TCP连接在流仍处于open或half-closed状态时关闭了或被重置, 然而受影响的流不会去自动重试.(详见8.1.4小节) 339 | 340 | ## 5.5 HTTP/2扩展 341 | 342 | 除了协议基本的约定外, 允许对其进行扩展. 在本章节描述中, 协议扩展可以用来提供额外的服务或修改协议的任一部分. 需要注意的是扩展功能仅在单个连接范围内有效. 343 | 344 | 扩展会应用到该文档中定义的协议元素上, 但不会影响扩展HTTP的现有设置, 比如定义新的方法,状态码,头部字段. 345 | 346 | 扩展允许使用新的帧类型(见4.1节), 新的settings参数(见6.5.2小节), 或者使用新的错误码(见第7章). 注册中心会管理这些扩展内容: 帧类型(见11.2节), settings参数(见11.3节), 错误码(见11.4节). 347 | 348 | 协议实现上必须忽略那些未知的或不支持的扩展值, 也必须丢弃那些未知/不支持类型的帧. 这意味着所有这些可扩展的地方都可以被安全使用而无需提前安排协商. 然而, 报头区块中是不允许出现扩展帧的; 如果出现就要将其视为一个类型为PROTOCOL_ERROR的连接错误来对待. 349 | 350 | 如果一个扩展可能改变既有协议某部分的语义, 必须在使用前商定好. 举个例子, 一个扩展改变了HEADERS帧的结构, 那么直到对等方给出一个表示接受变更的信号时, 这个扩展才能被应用. 这个例子中, 可能有必要商定一下修改后的HEADERS结构何时起效. 除此之外需要注意的是, 将任何非DATA帧用作流控属于语义上的变化, 并且只能通过协商来完成. 351 | 352 | 该文档并没有描述如何协商使用扩展的方法, 但是注意一个settings参数就可以用来实现这一目的. 如果双方都设置一个值表示愿意使用扩展, 扩展即可被启用. 如果一个settings参数用在了扩展协商上, 那么他的初始值在设置上必须表示扩展在最初是被禁用的. 353 | -------------------------------------------------------------------------------- /8-zh-cn.md: -------------------------------------------------------------------------------- 1 | ## HTTP Message Exchanges / HTTP消息交换 2 | *译者注:能力有限,在不能确定的译文中,使用* \*\* \*\* *语法着重标出,校对者请留意。* 3 | 4 | 5 | > HTTP/2 is intended to be as compatible as possible with current uses of HTTP. This means that, from the application perspective, the features of the protocol are largely unchanged. To achieve this, all request and response semantics are preserved, although the syntax of conveying those semantics has changed. 6 | 7 | HTTP/2致力于尽可能与当前使用的HTTP兼容。这意味着,从应用的视角,协议的特性主要部分是没有变化的。为了实现它,所有请求和响应的语义都被保留,尽管传输这些语义的语法改变了。 8 | 9 | > Thus, the specification and requirements of HTTP/1.1 Semantics and Content [RFC7231], Conditional Requests [RFC7232], Range Requests [RFC7233], Caching [RFC7234], and Authentication [RFC7235] are applicable to HTTP/2. Selected portions of HTTP/1.1 Message Syntax and Routing [RFC7230], such as the HTTP and HTTPS URI schemes, are also applicable in HTTP/2, but the expression of those semantics for this protocol are defined in the sections below. 10 | 11 | 因此,HTTP/1.1语义和内容[RFC7231], 条件请求[RFC7232], 范围请求[RFC7233],缓存[RFC7234],和认证[RFC7235]的规范和要求同样适用于HTTP/2。HTTP/1.1消息语法和路由 [RFC7230]的**选定部分**,像是HTTP和HTTPS URL模式也同样适用于HTTP/2,但是协议如何表达这些语义在下面章节定义。 12 | 13 | ### 8.1. HTTP Request/Response Exchange / HTTP 请求/响应交换 14 | > A client sends an HTTP request on a new stream, using a previously unused stream identifier (Section 5.1.1). A server sends an HTTP response on the same stream as the request. 15 | 16 | 客户端在一个新得流上发送HTTP请求,使用一个以前没有使用的流标识符(Section 5.1.1)。服务端在和请求相同的流上返回HTTP响应。 17 | 18 | > An HTTP message (request or response) consists of: 19 | 1. for a response only, zero or more HEADERS frames (each followed by zero or more CONTINUATION frames) containing the message headers of informational (1xx) HTTP responses (see [RFC7230], Section 3.2 and [RFC7231], Section 6.2), 20 | 2. one HEADERS frame (followed by zero or more CONTINUATION frames) containing the message headers (see [RFC7230], Section 3.2), 21 | 3. zero or more DATA frames containing the payload body (see [RFC7230], Section 3.3), and 22 | 4. optionally, one HEADERS frame, followed by zero or more CONTINUATION frames containing the trailer-part, if present (see [RFC7230], Section 4.1.2). 23 | 24 | 一个HTTP消息(请求和响应)包含: 25 | 1. 只对响应来说, 0或者以上的HEADERS帧(每一个跟着0或者以上的CONTINUATION帧),包含HTTP响应信息的消息头(see [RFC7230], Section 3.2 and [RFC7231], Section 6.2), 26 | 2. 一个HEADERS帧(跟着0或者以上的CONTINUATION帧),包含消息头(see [RFC7230], Section 3.2), 27 | 3. 0或者更多的数据帧,包含载荷体(see [RFC7230], Section 3.3),和 28 | 4. 可选的,一个HEADERS帧,如多存在的话,跟着0或者以上的包含尾部的CONTINUATION帧([RFC7230], Section 4.1.2) 29 | 30 | > The last frame in the sequence bears an END_STREAM flag, noting that a HEADERS frame bearing the END_STREAM flag can be followed by CONTINUATION frames that carry any remaining portions of the header block. 31 | 32 | 序列的最后一帧必须带有END_STREAM标志,**一个带有END_STREAM标志的HEADERS帧不可以被任何带有剩余部分头部块的CONTINUATION帧跟随**。 33 | 34 | > Other frames (from any stream) MUST NOT occur between the HEADERS frame and any CONTINUATION frames that might follow. 35 | 36 | 其余的帧(来自任何流)不能在HEADERS帧和可能跟随HEADERS帧的CONTINUATION帧之间出现。 37 | 38 | > HTTP/2 uses DATA frames to carry message payloads. The "chunked" transfer encoding defined in Section 4.1 of [RFC7230] MUST NOT be used in HTTP/2. 39 | 40 | HTTP/2使用DATA帧携带消息载荷。[RFC7230]中4.1节定义的"区块"转移编码不能在HTTP/2中使用。 41 | 42 | >Trailing header fields are carried in a header block that also terminates the stream. Such a header block is a sequence starting with a HEADERS frame, followed by zero or more CONTINUATION frames, where the HEADERS frame bears an END_STREAM flag. Header blocks after the first that do not terminate the stream are not part of an HTTP request or response. 43 | 44 | 头部块携带Trailing头部字段也能结束流。这样的头部块是一个以HEADERS帧开始的序列,HEADERS帧跟着0或者以上的CONTINUATION帧,其中HEADERS帧带有END_STREAM标志。在第一个没有结束流的帧之后的头部块不是HTTP请求和响应的部分。 45 | 46 | 47 | >A HEADERS frame (and associated CONTINUATION frames) can only appear at the start or end of a stream. An endpoint that receives a HEADERS frame without the END_STREAM flag set after receiving a final (non- informational) status code MUST treat the corresponding request or response as malformed (Section 8.1.2.6). 48 | 49 | 一个HEADERS帧(和相关联CONTINUATION帧)只能在流的开始或者结束出现。在收到最终(无信息)状态码之后,一个又收到没有END_STREAM标志的HEADERS帧端系统必须把响应的请求或者响应当作是不规范的。 50 | 51 | >An HTTP request/response exchange fully consumes a single stream. A request starts with the HEADERS frame that puts the stream into an "open" state. The request ends with a frame bearing END_STREAM, which causes the stream to become "half-closed (local)" for the client and "half-closed (remote)" for the server. A response starts with a HEADERS frame and ends with a frame bearing END_STREAM, which places the stream in the "closed" state. 52 | 53 | 一个HTTP请求/响应交换完全的消耗一个流。一个请求以HEADERS帧开始,将流变为"open"状态。请求以携带END_STREAM标志的帧结束,将客户端流的状态变为"half-closed (local)",将服务端流的状态变为"half-closed (remote)",一个响应以HEADERS帧开始,带有END_STREAM标志的帧结束,将流变为"closed"状态。 54 | 55 | >An HTTP response is complete after the server sends -- or the client receives -- a frame with the END_STREAM flag set (including any CONTINUATION frames needed to complete a header block). A server can send a complete response prior to the client sending an entire request if the response does not depend on any portion of the request that has not been sent and received. When this is true, a server MAY request that the client abort transmission of a request without error by sending a RST_STREAM with an error code of NO_ERROR after sending a complete response (i.e., a frame with the END_STREAM flag). Clients MUST NOT discard responses as a result of receiving such a RST_STREAM, though clients can always discard responses at their discretion for other reasons. 56 | 57 | 一个HTTP响应在服务器发送或者客户端收到一个有END_STREAM标识的帧(包括任何需要用来完成头部块的CONTINUATION帧)完成。如果响应不依赖于还没被发送或者接收的请求的任何部分,在客户端发送完整的请求之前服务端可以完整的发送响应。当这成立时,服务端可能请求客户端无错误的放弃请求传输,通过在发送完整响应(类如,一个有END_STREAM标志的帧)之后发送一个错误码为NO_ERROR的RST_STREAM。 58 | 59 | 60 | #### 8.1.1. Upgrading from HTTP/2 / 从HTTP/2升级 61 | > HTTP/2 removes support for the 101 (Switching Protocols) informational status code ([RFC7231], Section 6.2.2). 62 | The semantics of 101 (Switching Protocols) aren't applicable to a multiplexed protocol. Alternative protocols are able to use the same mechanisms that HTTP/2 uses to negotiate their use (see Section 3). 63 | 64 | HTTP/2 移除了对101(协议转换)信息状态码的支持([RFC7231], Section 6.2.2)。 65 | 101(协议转换)不适用多路协议。**替代的协议可能使用和HTTP/2相同的机制,协商它们的使用。** 66 | 67 | #### 8.1.2. HTTP Header Fields / HTTP头部字段 68 | >HTTP header fields carry information as a series of key-value pairs. For a listing of registered HTTP headers, see the "Message Header Field" registry maintained at . 69 | 70 | HTTP头部字段携带了一系列键值对信息。已注册的HTTP头列表,可以在"消息头部字段"注册处看到,维持在。 71 | 72 | > Just as in HTTP/1.x, header field names are strings of ASCII characters that are compared in a case-insensitive fashion. However, header field names MUST be converted to lowercase prior to their encoding in HTTP/2. A request or response containing uppercase header field names MUST be treated as malformed (Section 8.1.2.6). 73 | 74 | 就像HTTP/1.x,头部字段名称是大小写不敏感的ASCII字符串。然而,头部字段名称必须在HTTP/2编码前转换为小写字母。包含大写头部字段名称的请求或者响应必须被当作是不规范的。 75 | 76 | ##### 8.1.2.1. Pseudo-Header Fields 伪头部字段 77 | >While HTTP/1.x used the message start-line (see [RFC7230], Section 3.1) to convey the target URI, the method of the request, and the status code for the response, HTTP/2 uses special pseudo-header fields beginning with ':' character (ASCII 0x3a) for this purpose. 78 | 79 | HTTP/1.x 使用消息开始行(see [RFC7230], Section 3.1)传递目标URL,请求方法,响应状态码,HTTP/2使用特殊的以":"开始的伪头部字段来达到这个目的。 80 | 81 | >Pseudo-header fields are not HTTP header fields. Endpoints MUST NOT generate pseudo-header fields other than those defined in this document. 82 | 83 | 伪头部字段不是HTTP头部字段。端系统不能构造伪头部字段除非是在这篇文档里定义的。 84 | 85 | >Pseudo-header fields are only valid in the context in which they are defined. Pseudo-header fields defined for requests MUST NOT appear in responses; pseudo-header fields defined for responses MUST NOT appear in requests. Pseudo-header fields MUST NOT appear in trailers. Endpoints MUST treat a request or response that contains undefined or invalid pseudo-header fields as malformed (Section 8.1.2.6). 86 | 87 | 伪头部字段只有在他们定义的语境中才有效。为请求定义的伪头部字段不能在响应中出现;为响应定义的伪头部字段不能在请求中出现。伪头部字段不能在尾部出现。端系统必须把包含未定义或无效的伪头部字段的请求或者响应当作是不规范的(Section 8.1.2.6)。 88 | 89 | >All pseudo-header fields MUST appear in the header block before regular header fields. Any request or response that contains a pseudo-header field that appears in a header block after a regular header field MUST be treated as malformed (Section 8.1.2.6). 90 | 91 | 所有的在头部块中的伪头部字段必须出现在**常规**的头部字段之前。任何包含伪头部字段出现在常规头部字段之后的请求或者响应必须被当作是不规范的。 92 | 93 | ##### 8.1.2.2. Connection-Specific Header Fields / Connection-Specific头部字段 94 | >HTTP/2 does not use the Connection header field to indicate connection-specific header fields; in this protocol, connection-specific metadata is conveyed by other means. An endpoint MUST NOT generate an HTTP/2 message containing connection-specific header fields; any message containing connection-specific header fields MUST be treated as malformed (Section 8.1.2.6). 95 | 96 | HTTP/2不使用Connection说明头部字段说明connection-specific头部字段;在协议中,connection-specific元信息被使用其他方式传递。端系统不能产生包含连接-说明头部字段的HTTP/2消息;任何包含connection-specific头部字段的消息必须被当作成不规范的(Section 8.1.2.6)。 97 | 98 | >The only exception to this is the TE header field, which MAY be present in an HTTP/2 request; when it is, it MUST NOT contain any value other than "trailers". 99 | 100 | 唯一的例外就是TE头部字段,可能在HTTP/2请求中出现;当这时时,它必须包含非"trailers"值。 101 | 102 | >This means that an intermediary transforming an HTTP/1.x message to HTTP/2 will need to remove any header fields nominated by the Connection header field, along with the Connection header field itself. Such intermediaries SHOULD also remove other connection-specific header fields, such as Keep-Alive, Proxy-Connection, Transfer-Encoding, and Upgrade, even if they are not nominated by the Connection header field. 103 | 104 | 这意味着任何将HTTP/1.x消息转换为HTTP/2的中介必须移除任何被Connection头部字段**提名**的头部字段,和Connection头部字段自己。这些中介应该移除其他connection-specific头部字段,比如Keep-Alive, Proxy-Connection,Transfer-Encoding,和Upgrade,即使他们没有被连接头部字段提名。 105 | 106 | > Note: HTTP/2 purposefully does not support upgrade to another protocol. The handshake methods described in Section 3 are believed sufficient to negotiate the use of alternative protocols. 107 | 108 | 注意:HTTP/2无意支持升级到其他协议。第三节介绍的握手方法被认为是有效的来协商使用替代协议。 109 | 110 | ##### 8.1.2.3. Request Pseudo-Header Fields / 请求伪头部字段 111 | >The following pseudo-header fields are defined for HTTP/2 requests: 112 | - The ":method" pseudo-header field includes the HTTP method ([RFC7231], Section 4). 113 | - The ":scheme" pseudo-header field includes the scheme portion of the target URI ([RFC3986], Section 3.1). 114 | ":scheme" is not restricted to "http" and "https" schemed URIs. A proxy or gateway can translate requests for non-HTTP schemes, enabling the use of HTTP to interact with non-HTTP services. 115 | - The ":authority" pseudo-header field includes the authority portion of the target URI ([RFC3986], Section 3.2). The authority MUST NOT include the deprecated "userinfo" subcomponent for "http" or "https" schemed URIs.
116 | To ensure that the HTTP/1.1 request line can be reproduced accurately, this pseudo-header field MUST be omitted when translating from an HTTP/1.1 request that has a request target in origin or asterisk form (see [RFC7230], Section 5.3). Clients that generate HTTP/2 requests directly SHOULD use the ":authority" pseudo-header field instead of the Host header field. An intermediary that converts an HTTP/2 request to HTTP/1.1 MUST create a Host header field if one is not present in a request by copying the value of the ":authority" pseudo-header field. 117 | - The ":path" pseudo-header field includes the path and query parts of the target URI (the "path-absolute" production and optionally a '?' character followed by the "query" production (see Sections 3.3 and 3.4 of [RFC3986]). A request in asterisk form includes the value '\*' for the ":path" pseudo-header field.
118 | This pseudo-header field MUST NOT be empty for "http" or "https" URIs; "http" or "https" URIs that do not contain a path component MUST include a value of '/'. The exception to this rule is an OPTIONS request for an "http" or "https" URI that does not include a path component; these MUST include a ":path" pseudo-header field with a value of '*' (see [RFC7230], Section 5.3.4). 119 | 120 | 下列HTTP/2伪头部字段为HTTP/2请求定义: 121 | - ":method"伪头部字段包含HTTP方法([RFC7231], Section 4)。 122 | - ":scheme"伪头部字段包含目标URL模式部分([RFC3986], Section 3.1)。 123 | - ":authority"伪头部字段包含目标RUL认证部分([RFC3986], Section 3.2)。认证不能包含"http"或"https"URLs的废弃的"userinfo"子部分。
124 | 为了确保HTTP/1.1请求行可以被准确的重现,当从在**origin或asterisk**形式中有请求目标的HTTP/1.1请求翻译时,这个伪头部字段必须被忽略(see [RFC7230], Section 5.3)。发起HTTP/2请求的客户端应该直接使用":authority"伪头部字段来替代Host头部字段。将HTTP/2请求转换为HTTP/1.1的中介创建一个Host头部字段如果请求中不存在,通过复制":authority"伪头部字段的值来实现。 125 | - ":path"伪头部字段包含目标URL的路径和查询部分(绝对路径产生式和一个跟着"?"字符的查询产生式)。星号形式的请求包含值为"\*"的":path"伪头部字段。
126 | 这个伪头部字段对"http"或"https"URLs来说不能为空;不包含path部分‘http’或‘https’URLs必须包含一个‘/’值。这个规则的例外是不包含path部分的"http"或"https"URL的OPTIONS请求;这个必须包含值为"*"的":path"伪头部字段(see [RFC7230], Section 5.3.4)。 127 | 128 | >All HTTP/2 requests MUST include exactly one valid value for the ":method", ":scheme", and ":path" pseudo-header fields, unless it is a CONNECT request (Section 8.3). An HTTP request that omits mandatory pseudo-header fields is malformed (Section 8.1.2.6). 129 | 130 | 所有的HTTP/2请求必须准确的包含有效的":method", ":scheme", 和 ":path"伪头部字段,除非它是一个CONNECT请求(Section 8.3)。一个省略强制性伪头部字段的HTTP请求是不规范的(Section 8.1.2.6). 131 | 132 | > HTTP/2 does not define a way to carry the version identifier that is included in the HTTP/1.1 request line. 133 | 134 | HTTP/2没有定义一个携带包含在HTTP/1.1请求行中的版本标识符的方法。 135 | 136 | ##### 8.1.2.4. Response Pseudo-Header Fields / 响应伪头部字段 137 | > For HTTP/2 responses, a single ":status" pseudo-header field is defined that carries the HTTP status code field (see [RFC7231], Section 6). This pseudo-header field MUST be included in all responses; otherwise, the response is malformed (Section 8.1.2.6). 138 | 139 | 对于HTTP/2响应,一个":status"伪头部字段被定义来携带HTTP状态码字段(see [RFC7231], Section 6)。这个伪头部字段必须被所有的响应包含;否则,响应是不规范的(Section 8.1.2.6). 140 | 141 | > HTTP/2 does not define a way to carry the version or reason phrase that is included in an HTTP/1.1 status line. 142 | 143 | HTTP/2没有定义携带包含在HTTP/1.1状态行中的版本或原因解释的方法。 144 | 145 | ##### 8.1.2.5. Compressing the Cookie Header Field / 压缩Cookie头部字段 146 | > The Cookie header field [COOKIE] uses a semi-colon (";") to delimit cookie-pairs (or "crumbs"). This header field doesn't follow the list construction rules in HTTP (see [RFC7230], Section 3.2.2), which prevents cookie-pairs from being separated into different name-value pairs. This can significantly reduce compression efficiency as individual cookie-pairs are updated. 147 | 148 | Cookie头部字段[COOKIE]使用分号";"分割cookie对(或 "crumbs")。这个头部字段没有遵循防止cookie-pairs被分割到不同的键值对的HTTP列表构造法则(see [RFC7230], Section 3.2.2)。这可以显著地提升了压缩效率当单独的cookie-pairs被更新时。 149 | 150 | > To allow for better compression efficiency, the Cookie header field MAY be split into separate header fields, each with one or more cookie-pairs. If there are multiple Cookie header fields after decompression, these MUST be concatenated into a single octet string using the two-octet delimiter of 0x3B, 0x20 (the ASCII string "; ") before being passed into a non-HTTP/2 context, such as an HTTP/1.1 connection, or a generic HTTP server application. 151 | 152 | 为了得到更好的压缩效率,Cookie头部字段可能被分割成多个头部字段,每一个有一个或多个cookie-pairs。在他们被传递到非HTTP/2语境中,比如HTTP/1.1连接,或者一个通用的HTTP服务应用,如果解压缩之后有多个Cookie头部字段,他们必须被连接成一个使用0x3B, 0x20(ASCII字符串 "; ")这两个分隔符的序列。 153 | 154 | > Therefore, the following two lists of Cookie header fields are semantically equivalent.
155 | cookie: a=b; c=d; e=f
156 | cookie: a=b
157 | cookie: c=d
158 | cookie: e=f 159 | 160 | 因此,下列两个Cookie头部字段在语义上是相等的。
161 | cookie: a=b
162 | cookie: c=d
163 | cookie: e=f 164 | 165 | ##### 8.1.2.6. Malformed Requests and Responses / 不规范的请求和响应 166 | > A malformed request or response is one that is an otherwise valid sequence of HTTP/2 frames but is invalid due to the presence of extraneous frames, prohibited header fields, the absence of mandatory header fields, or the inclusion of uppercase header field names. 167 | 168 | 一个不规范的请求或者响应是一个有效的HTTP/2帧序列,但是因为额外的帧,禁止的头部字段,缺少强制性头部字段,或者包含大写头部字段名字而无效。 169 | 170 | > A request or response that includes a payload body can include a content-length header field. A request or response is also malformed if the value of a content-length header field does not equal the sum of the DATA frame payload lengths that form the body. A response that is defined to have no payload, as described in [RFC7230], Section 3.3.2, can have a non-zero content-length header field, even though no content is included in DATA frames. 171 | 172 | 一个包含载荷的请求或者响应可以包含content-length头部字段。如果content-length字段的值不等于组成body的DATA帧载荷,请求或者响应也是不规范的。一个被定义没有载荷的响应,在[RFC7230] 3.3.2节中描述,可以有一个非零的content-length值,即使在DATA中没有内容包含。 173 | 174 | > Intermediaries that process HTTP requests or responses (i.e., any intermediary not acting as a tunnel) MUST NOT forward a malformed request or response. Malformed requests or responses that are detected MUST be treated as a stream error (Section 5.4.2) of type PROTOCOL_ERROR. 175 | 176 | 处理HTTP请求和响应的中介(比如任何不是隧道角色的中介)不能前递一个不规范的请求或者响应。被侦测出来不规范的请求或者响应必须被当成PROTOCOL_ERROR类型的流错误(Section 5.4.2) 177 | 178 | > For malformed requests, a server MAY send an HTTP response prior to closing or resetting the stream. Clients MUST NOT accept a malformed response. Note that these requirements are intended to protect against several types of common attacks against HTTP; they are deliberately strict because being permissive can expose implementations to these vulnerabilities. 179 | 180 | 对一个不规范的请求,在关闭或者重置流之前服务端可能发送HTTP响应。客户端不能接收不规范的响应。注意这些要求是为了防止几种类型的常见HTTP攻击;他们是故意的如此严格,因为宽松可能使这些漏洞被揭发实现。 181 | 182 | #### 8.1.3. Examples / 例子 183 | > This section shows HTTP/1.1 requests and responses, with illustrations of equivalent HTTP/2 requests and responses. 184 | 185 | 这部分展示了一些有响应HTTP/2请求和响应的HTTP/1.1请求和响应。 186 | 187 | > An HTTP GET request includes request header fields and no payload body and is therefore transmitted as a single HEADERS frame, followed by zero or more CONTINUATION frames containing the serialized block of request header fields. The HEADERS frame in the following has both the END_HEADERS and END_STREAM flags set; no CONTINUATION frames are sent. 188 | 189 | 一个HTTP GET请求包含请求头部字段没有载荷体,因此被以一个单独的HEADERS帧传输,跟着零个或多个包含请求头部字段序列块的CONTINUATION帧。下面的这个HEADERS帧设置了END_HEADERS和END_STREAM标志位;没有发送CONTINUATION帧。 190 | 191 | ``` 192 | GET /resource HTTP/1.1 HEADERS 193 | Host: example.org ==> + END_STREAM 194 | Accept: image/jpeg + END_HEADERS 195 | :method = GET 196 | :scheme = https 197 | :path = /resource 198 | host = example.org 199 | accept = image/jpeg 200 | ``` 201 | 202 | > Similarly, a response that includes only response header fields is transmitted as a HEADERS frame (again, followed by zero or more CONTINUATION frames) containing the serialized block of response header fields. 203 | 204 | 同时,只包含响应头部字段的响应的也被以一个包含响应头部字段序列块的HEADERS帧传输(当然,跟着零或多个CONTINUATION帧) 205 | 206 | ``` 207 | HTTP/1.1 304 Not Modified HEADERS 208 | ETag: "xyzzy" ==> + END_STREAM 209 | Expires: Thu, 23 Jan ... + END_HEADERS 210 | :status = 304 211 | etag = "xyzzy" 212 | expires = Thu, 23 Jan ... 213 | ``` 214 | 215 | > An HTTP POST request that includes request header fields and payload data is transmitted as one HEADERS frame, followed by zero or more CONTINUATION frames containing the request header fields, followed by one or more DATA frames, with the last CONTINUATION (or HEADERS) frame having the END_HEADERS flag set and the final DATA frame having the END_STREAM flag set: 216 | 217 | 一个包含请求头部字段和载荷数据的HTTP POST被以一个单独的HEADERS帧传输,跟着零个或多个包含请求头部字段序列块的CONTINUATION帧 218 | ,再跟着一个或多个DATA帧,其中最后一个CONTINUATION帧(或HEADERS帧)设置了END_HEADERS标志位,最后一个DATA帧设置了END_STREAM标志位。 219 | 220 | ``` 221 | POST /resource HTTP/1.1 HEADERS 222 | Host: example.org ==> - END_STREAM 223 | Content-Type: image/jpeg - END_HEADERS 224 | Content-Length: 123 :method = POST 225 | :path = /resource 226 | {binary data} :scheme = https 227 | 228 | CONTINUATION 229 | + END_HEADERS 230 | content-type = image/jpeg 231 | host = example.org 232 | content-length = 123 233 | 234 | DATA 235 | + END_STREAM 236 | {binary data} 237 | ``` 238 | 239 | > Note that data contributing to any given header field could be spread between header block fragments. The allocation of header fields to frames in this example is illustrative only. 240 | 241 | **注意任何给定头部字段的相关数据可能会在头部块段之间散布。**这个例子中的帧的头部字段的分配仅作为说明。 242 | 243 | > A response that includes header fields and payload data is transmitted as a HEADERS frame, followed by zero or more CONTINUATION frames, followed by one or more DATA frames, with the last DATA frame in the sequence having the END_STREAM flag set: 244 | 245 | 一个包含请求头部字段和载荷数据的响应被以一个单独的HEADERS帧传输,跟着零个或多个的CONTINUATION帧,再跟着一个或多个DATA帧,其中序列中最后一个DATA帧设置了END_STREAM标志位。 246 | 247 | ``` 248 | HTTP/1.1 200 OK HEADERS 249 | Content-Type: image/jpeg ==> - END_STREAM 250 | Content-Length: 123 + END_HEADERS 251 | :status = 200 252 | {binary data} content-type = image/jpeg 253 | content-length = 123 254 | 255 | DATA 256 | + END_STREAM 257 | {binary data} 258 | ``` 259 | 260 | > An informational response using a 1xx status code other than 101 is transmitted as a HEADERS frame, followed by zero or more CONTINUATION frames. 261 | 262 | 使用除了101之外的1xx状态码的信息响应以一个HEADERS帧传输,跟着零个或多个的CONTINUATION帧。 263 | 264 | > Trailing header fields are sent as a header block after both the request or response header block and all the DATA frames have been sent. The HEADERS frame starting the trailers header block has the END_STREAM flag set. 265 | The following example includes both a 100 (Continue) status code, which is sent in response to a request containing a "100-continue" token in the Expect header field, and trailing header fields: 266 | 267 | Trailing头部字段在请求和响应头部块以及所有的DATA帧传输完成之后以头部块的形式传输。HEADERS帧设置END_STREAM标志开始尾部头部字段传输。下面的例子包含了一个100(Continue)状态码和尾部头部字段,被作为对在Except头部字段包含"100-continue"标识对的请求的响应中发送。 268 | 269 | ``` 270 | HTTP/1.1 100 Continue HEADERS 271 | Extension-Field: bar ==> - END_STREAM 272 | + END_HEADERS 273 | :status = 100 274 | extension-field = bar 275 | 276 | HTTP/1.1 200 OK HEADERS 277 | Content-Type: image/jpeg ==> - END_STREAM 278 | Transfer-Encoding: chunked + END_HEADERS 279 | Trailer: Foo :status = 200 280 | content-length = 123 281 | 123 content-type = image/jpeg 282 | {binary data} trailer = Foo 283 | 0 284 | Foo: bar DATA 285 | - END_STREAM 286 | {binary data} 287 | 288 | HEADERS 289 | + END_STREAM 290 | + END_HEADERS 291 | foo = bar 292 | ``` 293 | 294 | 295 | #### 8.1.4. Request Reliability Mechanisms in HTTP/2 / HTTP/2请求可靠机制 296 | > In HTTP/1.1, an HTTP client is unable to retry a non-idempotent request when an error occurs because there is no means to determine the nature of the error. It is possible that some server processing occurred prior to the error, which could result in undesirable effects if the request were reattempted. 297 | 298 | 在HTTP/1.1中,当错误发生时一个HTTP客户端不能重复一个非幂等的请求,因为没有方法确定错误的原因。可能一些服务器处理在错误发生之前已经处理了,当重新尝试请求时可能会造成不期望的后果。 299 | 300 | > HTTP/2 provides two mechanisms for providing a guarantee to a client that a request has not been processed: 301 | - The GOAWAY frame indicates the highest stream number that might have been processed. Requests on streams with higher numbers are therefore guaranteed to be safe to retry. 302 | - The REFUSED_STREAM error code can be included in a RST_STREAM frame to indicate that the stream is being closed prior to any processing having occurred. Any request that was sent on the reset stream can be safely retried. 303 | 304 | HTTP/2 提供了两套机制能向客户端保证一个请求没有被处理。 305 | - GOAWAY帧表示了可能被处理的最高流标识符。在有更高流标识符的流上的请求能保证安全的重试。 306 | - REFUSED_STREAM错误码可以被包含在RST_STREAM帧中来表示流在任何处理发生之前就被关闭了。 307 | 308 | > Requests that have not been processed have not failed; clients MAY automatically retry them, even those with non-idempotent methods. 309 | 310 | 还没有被处理的请求没失败;客户端可以自动的重试他们,即使他们有非幂等的方法。 311 | 312 | > A server MUST NOT indicate that a stream has not been processed unless it can guarantee that fact. If frames that are on a stream are passed to the application layer for any stream, then REFUSED_STREAM MUST NOT be used for that stream, and a GOAWAY frame MUST include a stream identifier that is greater than or equal to the given stream identifier. 313 | 314 | 服务端不能表明一个流还没有被处理除非能保证这个事实。如果任何一个流上的帧已经传递到应用层,REFUSED_STREAM不能被用在这个流上,并且一个GOAWAY帧必须包含一个大于等于给定流标识符的流标识符。 315 | 316 | > In addition to these mechanisms, the PING frame provides a way for a client to easily test a connection. Connections that remain idle can become broken as some middleboxes (for instance, network address translators or load balancers) silently discard connection bindings. The PING frame allows a client to safely test whether a connection is still active without sending a request. 317 | 318 | 在这些机制之外,PING帧给客户端提供了一种简单测试连接的方式。闲置状态的连接可能被中间设备(例如,网络地址转换器或载荷均衡)静默的放弃连接绑定破坏。PING帧允许客户端安全的测试连接是否是活动的而不必发送请求。 319 | 320 | ### 8.2. Server Push / 服务端推送 321 | > HTTP/2 allows a server to pre-emptively send (or "push") responses (along with corresponding "promised" requests) to a client in association with a previous client-initiated request. This can be useful when the server knows the client will need to have those responses available in order to fully process the response to the original request. 322 | 323 | HTTP/2允许服务器先行发送(或推送)与先前客户端初始请求相关的响应(对应"许诺"的请求)到客户端。这在服务端知道客户端将会须要这些响应来完全地处理原始请求的响应时会很有用。 324 | 325 | > A client can request that server push be disabled, though this is negotiated for each hop independently. The SETTINGS_ENABLE_PUSH setting can be set to 0 to indicate that server push is disabled. 326 | 327 | 客户端可以请求服务端推送禁用,尽管这在每一跳独立的协商。SETTINGS_ENABLE_PUSH被设置为0表示服务端推送关闭。 328 | 329 | > Promised requests MUST be cacheable (see [RFC7231], Section 4.2.3), MUST be safe (see [RFC7231], Section 4.2.1), and MUST NOT include a request body. Clients that receive a promised request that is not cacheable, that is not known to be safe, or that indicates the presence of a request body MUST reset the promised stream with a stream error (Section 5.4.2) of type PROTOCOL_ERROR. Note this could result in the promised stream being reset if the client does not recognize a newly defined method as being safe. 330 | 331 | 许诺的请求必须是可缓存的(see [RFC7231], Section 4.2.3),必须是安全的(see [RFC7231], Section 4.2.1),必须不能包含请求体。客户端收到不是可缓存的,不能被识别为安全的或者是表明存在请求体的许诺请求必须重置许诺流并设置PROTOCOL_ERROR类型的流错误(Section 5.4.2)。注意这可能导致在客户端不能识别一个新的方法是不是安全的时候重置流。 332 | 333 | > Pushed responses that are cacheable (see [RFC7234], Section 3) can be stored by the client, if it implements an HTTP cache. Pushed responses are considered successfully validated on the origin server (e.g., if the "no-cache" cache response directive is present ([RFC7234], Section 5.2.2)) while the stream identified by the promised stream ID is still open. 334 | 335 | 可缓存的的推送响应可以被客户端存储,如果客户端实现了HTTP缓存。推送响应在许诺流ID的流标识符依旧打开时,被认为是在原始服务端上成功有效的(例如,如果"no-cache"响应指令存在([RFC7234], Section 5.2.2))。 336 | 337 | > Pushed responses that are not cacheable MUST NOT be stored by any HTTP cache. They MAY be made available to the application separately. 338 | 339 | 不可缓存的推送响应肯定不能被任何HTTP缓存存储。这可能在应用分离的时候有效。 340 | 341 | > The server MUST include a value in the ":authority" pseudo-header field for which the server is authoritative (see Section 10.1). A client MUST treat a PUSH_PROMISE for which the server is not authoritative as a stream error (Section 5.4.2) of type PROTOCOL_ERROR. 342 | 343 | 服务端如果是认证的(see Section 10.1),必须包含":authority"伪头部字段的值。一个客户端对待一个服务端没有认证的PUSH_PROMISE为PROTOCOL_ERROR类型的流错误(Section 5.4.2)。 344 | 345 | > An intermediary can receive pushes from the server and choose not to forward them on to the client. In other words, how to make use of the pushed information is up to that intermediary. Equally, the intermediary might choose to make additional pushes to the client, without any action taken by the server. 346 | 347 | 中介可以从服务端接收推送并且选择是否将他们前递给客户端。换一句话说,如何利用推送信息取决于中介。同等的,中介也可以选择推送额外的响应给客户端,在没有接收到服务器任何动作的前提下。 348 | 349 | > A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. Clients MUST reject any attempt to change the SETTINGS_ENABLE_PUSH setting to a value other than 0 by treating the message as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 350 | 351 | 客户端是不能推送的。因此,服务端必须把PUSH_PROMISE帧当作是PROTOCOL_ERROR类型的连接错误(Section 5.4.1)。客户端必须决绝任何尝试把SETTINGS_ENABLE_PUSH设置为非零值的消息,并把消息当作是PROTOCOL_ERROR类型的连接错误。 352 | 353 | #### 8.2.1. Push Requests / 推送请求 354 | 355 | > Server push is semantically equivalent to a server responding to a request; however, in this case, that request is also sent by the server, as a PUSH_PROMISE frame. 356 | 357 | 服务端推送语义上相当于服务端响应一个请求;然而,这种情况下,请求仍然是服务端以PUSH_PROMISE帧方式发送。 358 | 359 | > The PUSH_PROMISE frame includes a header block that contains a complete set of request header fields that the server attributes to the request. It is not possible to push a response to a request that includes a request body. 360 | Pushed responses are always associated with an explicit request from the client. The PUSH_PROMISE frames sent by the server are sent on that explicit request's stream. The PUSH_PROMISE frame also includes a promised stream identifier, chosen from the stream identifiers available to the server (see Section 5.1.1). 361 | 362 | PUSH_PROMISE帧包含了包含所有服务端在请求里设置的请求头部字段的头部块。这是不可能向一个包含请求体的请求推送响应的。推送响应总是与来自客户端的明确的请求相关。被服务器发送的PUSH_PROMISE帧在这个对应的请求流上发送。PUSH_PROMISE帧当然包含了许诺流标识符,从服务端可用的流标识符空间里选择。 363 | 364 | > The header fields in PUSH_PROMISE and any subsequent CONTINUATION frames MUST be a valid and complete set of request header fields (Section 8.1.2.3). The server MUST include a method in the ":method" pseudo-header field that is safe and cacheable. If a client receives a PUSH_PROMISE that does not include a complete and valid set of header fields or the ":method" pseudo-header field identifies a method that is not safe, it MUST respond with a stream error (Section 5.4.2) of type PROTOCOL_ERROR. 365 | 366 | PUSH_PROMISE和任何后续CONTINUATION帧里的头部字段必须包含有效完整的请求头部字段(Section 8.1.2.3)。服务端必须必须包含安全可缓存的":method"伪头部字段。如果客户端收到了没有完整包含有效请求头部字段或者":method"伪头部字段的方法是不安全的PUSH_PROMISE帧,他必须被当作是PROTOCOL_ERROR类型的流错误(Section 5.4.2)。 367 | 368 | > The server SHOULD send PUSH_PROMISE (Section 6.6) frames prior to sending any frames that reference the promised responses. This avoids a race where clients issue requests prior to receiving any PUSH_PROMISE frames. 369 | 370 | 服务端应该在发送任何与许诺响应相关的帧之前发送PUSH_PROMISE(Section 6.6)。这避免了客户端在收到PUSH_PROMISE帧之前发送请求的竞争。 371 | 372 | > For example, if the server receives a request for a document containing embedded links to multiple image files and the server chooses to push those additional images to the client, sending PUSH_PROMISE frames before the DATA frames that contain the image links ensures that the client is able to see that a resource will be pushed before discovering embedded links. Similarly, if the server pushes responses referenced by the header block (for instance, in Link header fields), sending a PUSH_PROMISE before sending the header block ensures that clients do not request those resources. 373 | 374 | 例如,如果服务器收到了一个包含多个图像文件的内嵌连接的文档,服务器选择推送这些额外的图像到客户端,并在DATA帧之前发送包含图像连接的PUSH_PROMISE来确保客户端在发现这些内置连接之前能确保这些资源会被推送。同样的,如果服务端推送了被头部块(for instance, in Link header fields)引用的响应,在发送头部块之前发送PUSH_PROMISE帧来确保客户端不会请求这些资源。 375 | 376 | > PUSH_PROMISE frames MUST NOT be sent by the client. 377 | 378 | PUSH_PROMISE帧不能被客户端发送。 379 | 380 | > PUSH_PROMISE frames can be sent by the server in response to any client-initiated stream, but the stream MUST be in either the "open" or "half-closed (remote)" state with respect to the server. PUSH_PROMISE frames are interspersed with the frames that comprise a response, though they cannot be interspersed with HEADERS and CONTINUATION frames that comprise a single header block. 381 | 382 | PUSH_PROMISE帧可以被服务端发送来响应客户端初始流,但是流对应服务端的状态必须被设置为"open"或"half-closed (remote)"。PUSH_PROMISE帧点缀在组成响应的帧之间,但是不能点缀在组成一个完整头部块的HEADERS和CONTINUATION帧。 383 | 384 | > Sending a PUSH_PROMISE frame creates a new stream and puts the stream into the "reserved (local)" state for the server and the "reserved (remote)" state for the client. 385 | 386 | 发送一个PUSH_PROMISE帧创建了一个新的流,并将服务器端流的状态改为"reserved (local)",客户端的状态改为"reserved (remote)"。 387 | 388 | #### 8.2.2. Push Responses / 推送响应 389 | 390 | > After sending the PUSH_PROMISE frame, the server can begin delivering the pushed response as a response (Section 8.1.2.4) on a server-initiated stream that uses the promised stream identifier. The server uses this stream to transmit an HTTP response, using the same sequence of frames as defined in Section 8.1. This stream becomes "half-closed" to the client (Section 5.1) after the initial HEADERS frame is sent. 391 | 392 | 在发送PUSH_PROMISE帧之后,服务端可以开始传递被推送的响应作为响应在使用许诺流标识符服务端初始的流上。服务端使用这个流传递HTTP响应,使用和在8.1节中定义的相同的帧序列。在初始HEADERS被发送之后这个流对于客户端变成"half-closed"状态(Section 5.1)。 393 | 394 | > Once a client receives a PUSH_PROMISE frame and chooses to accept the pushed response, the client SHOULD NOT issue any requests for the promised response until after the promised stream has closed. 395 | 396 | 如果客户端收到了PUSH_PROMISE帧并选择接收推送响应,客户端不应该在许诺流关闭之前发起任何关于许诺响应的请求。 397 | 398 | > If the client determines, for any reason, that it does not wish to receive the pushed response from the server or if the server takes too long to begin sending the promised response, the client can send a RST_STREAM frame, using either the CANCEL or REFUSED_STREAM code and referencing the pushed stream's identifier. 399 | 400 | 如果客户端因为某些原因,决定不接收从服务端来的推送响应,或者服务端花费了太长的时间来发送许诺响应,客户端可以发送RST_STREAM帧,使用CANCEL或REFUSED_STREAM码并且引用推送流标识符。 401 | 402 | > A client can use the SETTINGS_MAX_CONCURRENT_STREAMS setting to limit the number of responses that can be concurrently pushed by a server. Advertising a SETTINGS_MAX_CONCURRENT_STREAMS value of zero disables server push by preventing the server from creating the necessary streams. This does not prohibit a server from sending PUSH_PROMISE frames; clients need to reset any promised streams that are not wanted. 403 | 404 | 客户端可以使用SETTINGS_MAX_CONCURRENT_STREAMS来限制服务器推送的最大并行响应数。设置SETTINGS_MAX_CONCURRENT_STREAMS为零可以禁用推送来阻止服务器创建不必要的流。这不禁止服务端发送PUSH_PROMISE帧;客户端需要重置任何不期望的许诺流。 405 | 406 | > Clients receiving a pushed response MUST validate that either the server is authoritative (see Section 10.1) or the proxy that provided the pushed response is configured for the corresponding request. For example, a server that offers a certificate for only the "example.com" DNS-ID or Common Name is not permitted to push a response for "https://www.example.org/doc". 407 | 408 | 客户端收到的任何推送响应必须验证服务器是认证的(see Section 10.1)或者代理被配置为为相应的请求提供推送响应。例如,只提供"example.com" DNS-ID 或者 Common Name 证书的服务器是不允许为"https://www.example.org/doc"推送响应的。 409 | 410 | > The response for a PUSH_PROMISE stream begins with a HEADERS frame, which immediately puts the stream into the "half-closed (remote)" state for the server and "half-closed (local)" state for the client, and ends with a frame bearing END_STREAM, which places the stream in the "closed" state. 411 | 412 | 以HEADERS帧开始的PUSH_PROMISE流响应,立即将服务端状态变为"half-closed (remote)",客户端状态变为"half-closed (local)",并以设置了END_STREAM的帧结束,这会将流置为"closed"状态。 413 | 414 | > Note: The client never sends a frame with the END_STREAM flag for a server push. 415 | 416 | 注意:客户端绝不对服务端推送发送设置END_STREAM标志的帧。 417 | 418 | ### 8.3. The CONNECT Method / CONNECT方法 419 | > In HTTP/1.x, the pseudo-method CONNECT ([RFC7231], Section 4.3.6) is used to convert an HTTP connection into a tunnel to a remote host. CONNECT is primarily used with HTTP proxies to establish a TLS session with an origin server for the purposes of interacting with "https" resources. 420 | 421 | 在HTTP/1.x,伪方法CONNECT([RFC7231], Section 4.3.6)被用来将HTTP连接转换成到一个远程主机的隧道。CONNECT主要被HTTP代理用来建立和远程服务端的TLS会话,为了和"https"资源交互。 422 | 423 | > In HTTP/2, the CONNECT method is used to establish a tunnel over a single HTTP/2 stream to a remote host for similar purposes. The HTTP header field mapping works as defined in Section 8.1.2.3 ("Request Pseudo-Header Fields"), with a few differences. Specifically: 424 | - The ":method" pseudo-header field is set to "CONNECT". 425 | - The ":scheme" and ":path" pseudo-header fields MUST be omitted. 426 | - The ":authority" pseudo-header field contains the host and port to connect to (equivalent to the authority-form of the request-target of CONNECT requests (see [RFC7230], Section 5.3)). 427 | 428 | 在HTTP/2,CONNECT方法被用来在一个HTTP/2流上建立一个隧道,为了同样的目的。HTTP头部字段映射按照在8.1.2.3节("Request Pseudo-Header Fields")定义工作,但是有点不同。说明如下: 429 | - ":method"伪头部字段被设置为"CONNECT"。 430 | - ":scheme" 和 ":path"伪头部字段必须被忽略 431 | - ":authority"伪头部字段包含了需要连接的主机和端口(和CONNECT请求目标的authority-form格式相同(see [RFC7230], Section 5.3))。 432 | 433 | > A CONNECT request that does not conform to these restrictions is malformed (Section 8.1.2.6). 434 | 435 | 没有遵守这些约束的CONNECT请求是不规范的(Section 8.1.2.6)。 436 | 437 | > A proxy that supports CONNECT establishes a TCP connection [TCP] to the server identified in the ":authority" pseudo-header field. Once this connection is successfully established, the proxy sends a HEADERS frame containing a 2xx series status code to the client, as defined in [RFC7231], Section 4.3.6. 438 | 439 | 支持用CONNECT的代理和":authority"伪头部字段表示的服务器建立TCP连接[TCP]。一旦连接成功建立了,代理发送包含2xx序列状态码的头部帧到客户端,在[RFC7231]中4.3.6节定义。 440 | 441 | > After the initial HEADERS frame sent by each peer, all subsequent DATA frames correspond to data sent on the TCP connection. The payload of any DATA frames sent by the client is transmitted by the proxy to the TCP server; data received from the TCP server is assembled into DATA frames by the proxy. Frame types other than DATA or stream management frames (RST_STREAM, WINDOW_UPDATE, and PRIORITY) MUST NOT be sent on a connected stream and MUST be treated as a stream error (Section 5.4.2) if received. 442 | 443 | 在初始头部帧被每一端发送后,所有的对应数据的后续DATA帧被TCP连接发送。被客户端发送的DATA帧载荷被代理传送到TCP服务端;从TCP服务端收到的数据被代理重新组合成DATA帧。DATA帧类型之外的帧或者流管理帧(RST_STREAM, WINDOW_UPDATE, 和 PRIORITY)不能在已经连接的流发送并且如果收到了被当作成流错误(Section 5.4.2)。 444 | 445 | > The TCP connection can be closed by either peer. The END_STREAM flag on a DATA frame is treated as being equivalent to the TCP FIN bit. A client is expected to send a DATA frame with the END_STREAM flag set after receiving a frame bearing the END_STREAM flag. A proxy that receives a DATA frame with the END_STREAM flag set sends the attached data with the FIN bit set on the last TCP segment. A proxy that receives a TCP segment with the FIN bit set sends a DATA frame with the END_STREAM flag set. Note that the final TCP segment or DATA frame could be empty. 446 | 447 | TCP连接可以被每一端关闭。设置END_STREAM的DATA帧被同等当作为TCP FIN位。在收到设置END_STREAM的帧后,客户端期望发送有END_STREAM标志的DATA帧。收到设置END_STREAM标志的DATA帧的代理在最后的一个TCP段上发送设置了FIN位的相关数据。收到设置了FIN位的TCP段的代理发送设置END_STREAM的数据帧。注意最后的TCP段或数据帧可以为空。 448 | 449 | > A TCP connection error is signaled with RST_STREAM. A proxy treats any error in the TCP connection, which includes receiving a TCP segment with the RST bit set, as a stream error (Section 5.4.2) of type CONNECT_ERROR. Correspondingly, a proxy MUST send a TCP segment with the RST bit set if it detects an error with the stream or the HTTP/2 connection. 450 | 451 | 一个TCP连接错误使用RST_STREAM表明。代理把TCP连接中的任何错误,包括收到了一个设置RST位的TCP段当作是CONNECT_ERROR类型的流错误(Section 5.4.2)。同样的,代理必须发送一个设置了FIN位的TCP段如果检测到了流或者HTTP/2连接的任何错误。 452 | -------------------------------------------------------------------------------- /6-zh-cn.md: -------------------------------------------------------------------------------- 1 | # 6. Frame Definitions 2 | # 6. 帧定义 3 | 4 | > This specification defines a number of frame types, each identified by a unique 8-bit type code. Each frame type serves a distinct purpose in the establishment and management either of the connection as a whole or of individual streams. 5 | 6 | 这份文档定义了多种帧类型,每种都由一个唯一的8位类型码标识。每种帧类型都服务于建立和管理整个连接或独立的流方面的一个不同的目的。 7 | 8 | > The transmission of specific frame types can alter the state of a connection. If endpoints fail to maintain a synchronized view of the connection state, successful communication within the connection will no longer be possible. Therefore, it is important that endpoints have a shared comprehension of how the state is affected by the use any given frame. 9 | 10 | 特定帧类型的传输可能改变连接的状态。如果终端不能维护连接状态视图的一致性,连接内成功的通信将是不可能的。因此,终端之间,关于特定帧的使用对状态所产生的影响具有相同的理解就变得非常重要。 11 | 12 | ## 6.1 DATA 13 | 14 | > DATA frames (type=0x0) convey arbitrary, variable-length sequences of octets associated with a stream. One or more DATA frames are used, for instance, to carry HTTP request or response payloads. 15 | 16 | DATA帧(type=0x0)传送与一个流关联的任意的,可变长度的字节序列。一个或多个DATA帧被用于,比如,携带HTTP请求或响应载荷。 17 | 18 | > DATA frames MAY also contain padding. Padding can be added to DATA frames to obscure the size of messages. Padding is a security feature; see Section 10.7. 19 | 20 | DATA帧也 **可以(MAY)** 包含填充字节。填充字节可以被加进DATA帧来掩盖消息的大小。填充字节是一个安全性的功能;参见 [Section 10.7](https://http2.github.io/http2-spec/#padding)。 21 | 22 | ``` 23 | +---------------+ 24 | |Pad Length? (8)| 25 | +---------------+-----------------------------------------------+ 26 | | Data (*) ... 27 | +---------------------------------------------------------------+ 28 | | Padding (*) ... 29 | +---------------------------------------------------------------+ 30 | ``` 31 | > Figure 6: DATA Frame Payload 32 | 33 | 图 6:DATA帧载荷 34 | 35 | 36 | > The DATA frame contains the following fields: 37 | 38 | DATA帧包含如下的字段: 39 | 40 | > Pad Length: 41 | > An 8-bit field containing the length of the frame padding in units of octets. This field is conditional (as signified by a "?" in the diagram) and is only present if the PADDED flag is set. 42 | 43 | **填充长度:** 44 | 45 | 一个8位的字段,包含了以字节为单位的帧的填充的长度。这个字段是有条件的(如图中的"?"所指的),只有在PADDED标记设置时才出现。 46 | 47 | > Data: 48 | > Application data. The amount of data is the remainder of the frame payload after subtracting the length of the other fields that are present. 49 | 50 | **数据:** 51 | 52 | 应用数据。数据的大小是帧载荷减去出现的其它字段的长度剩余的大小。 53 | 54 | > Padding: 55 | > Padding octets that contain no application semantic value. Padding octets MUST be set to zero when sending. A receiver is not obligated to verify padding but MAY treat non-zero padding as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 56 | 57 | **填充:** 58 | 59 | 填充字节包含了无应用语义的值。当填充时填充字节 **必须(MUST)** 被设置为0。接收者没有义务去验证填充,而 **可以(MAY)** 将非零的填充当做一个类型为[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 60 | 61 | > The DATA frame defines the following flags: 62 | 63 | DATA帧定义了如下的标记: 64 | 65 | > END_STREAM (0x1): 66 | > When set, bit 0 indicates that this frame is the last that the endpoint will send for the identified stream. Setting this flag causes the stream to enter one of the "half-closed" states or the "closed" state (Section 5.1). 67 | 68 | **END_STREAM (0x1):** 69 | 70 | 当设置了这个标记时,位0表示这个帧是终端将为标识的流发送的最后一帧。设置这个标记使得流进入某种"half-closed"状态或"closed"状态([Section 5.1](https://http2.github.io/http2-spec/#StreamStates))。 71 | 72 | > PADDED (0x8): 73 | > When set, bit 3 indicates that the Pad Length field and any padding that it describes are present. 74 | 75 | **PADDED (0x8):** 76 | 77 | 当设置了这个标记时,位3表示上面描述的 填充长度 字段及填充存在。 78 | 79 | > DATA frames MUST be associated with a stream. If a DATA frame is received whose stream identifier field is 0x0, the recipient MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 80 | 81 | DATA帧 **必须(MUST)** 与一个流关联。如果收到了一个流标识符为0x0的DATA帧,接收者 **必须(MUST)** 以一个类型为[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))来响应。 82 | 83 | > DATA frames are subject to flow control and can only be sent when a stream is in the "open" or "half-closed (remote)" state. The entire DATA frame payload is included in flow control, including the Pad Length and Padding fields if present. If a DATA frame is received whose stream is not in "open" or "half-closed (local)" state, the recipient MUST respond with a stream error (Section 5.4.2) of type STREAM_CLOSED. 84 | 85 | DATA帧受控于flow control,而且只能在流处于"open"或"half-closed (remote)"状态时发送。整个的DATA帧载荷被包含在flow control中,可能包括 填充长度 和填充字段。如果收到DATA帧的流不处于"open"或"half-closed (remote)"状态,则接收者 **必须(MUST)** 以一个类型为[STREAM_CLOSED](https://http2.github.io/http2-spec/#STREAM_CLOSED)的流错误([Section 5.4.2](https://http2.github.io/http2-spec/#StreamErrorHandler))来响应。 86 | 87 | > The total number of padding octets is determined by the value of the Pad Length field. If the length of the padding is the length of the frame payload or greater, the recipient MUST treat this as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 88 | 89 | 填充字节的总大小由填充长度字段决定。如果填充的长度是帧载荷的长度或更大,则接收者 **必须(MUST)** 将这作为一个类型为[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))来处理应。 90 | 91 | > Note: A frame can be increased in size by one octet by including a Pad Length field with a value of zero. 92 | 93 | 注意:一个帧可以通过包含一个值为零的填充长度字段来使帧长度只增加一个字节。 94 | 95 | ## 6.2 HEADERS 96 | 97 | > The HEADERS frame (type=0x1) is used to open a stream (Section 5.1), and additionally carries a header block fragment. HEADERS frames can be sent on a stream in the "idle", "reserved (local)", "open", or "half-closed (remote)" state. 98 | 99 | HEADERS帧(type=0x1)用于打开一个流([Section 5.1](https://http2.github.io/http2-spec/#StreamStates)),此外还携带一个首部块片段。HEADERS帧可以在一个"idle","reserved (local)","open",或"half-closed (remote)"状态的流上发送。 100 | 101 | ``` 102 | +---------------+ 103 | |Pad Length? (8)| 104 | +-+-------------+-----------------------------------------------+ 105 | |E| Stream Dependency? (31) | 106 | +-+-------------+-----------------------------------------------+ 107 | | Weight? (8) | 108 | +-+-------------+-----------------------------------------------+ 109 | | Header Block Fragment (*) ... 110 | +---------------------------------------------------------------+ 111 | | Padding (*) ... 112 | +---------------------------------------------------------------+ 113 | ``` 114 | > Figure 7: HEADERS Frame Payload 115 | 116 | 图 7: HEADERS帧载荷 117 | 118 | > The HEADERS frame payload has the following fields: 119 | 120 | HEADERS帧具有如下的字段: 121 | 122 | > Pad Length: 123 | > An 8-bit field containing the length of the frame padding in units of octets. This field is only present if the PADDED flag is set. 124 | 125 | **填充长度:** 126 | 127 | 一个8位的字段,包含了以字节为单位的帧的填充的长度。只有在PADDED标记设置时这个字段才出现。 128 | 129 | > E: 130 | > A single-bit flag indicating that the stream dependency is exclusive (see Section 5.3). This field is only present if the PRIORITY flag is set. 131 | 132 | **E:** 133 | 134 | 一个单独的位标记,指示了流依赖是独占的(参见[Section 5.3](https://http2.github.io/http2-spec/#StreamPriority))。这个字段只有在PRIORITY标记设置时才会出现。 135 | 136 | > Stream Dependency: 137 | > A 31-bit stream identifier for the stream that this stream depends on (see Section 5.3). This field is only present if the PRIORITY flag is set. 138 | 139 | 流依赖:一个31位的标识了这个流依赖的流的流标识符(参见[Section 5.3](https://http2.github.io/http2-spec/#StreamPriority))。这个字段只有在PRIORITY标记设置时才会出现。 140 | 141 | > Weight: 142 | > An unsigned 8-bit integer representing a priority weight for the stream (see Section 5.3). Add one to the value to obtain a weight between 1 and 256. This field is only present if the PRIORITY flag is set. 143 | 144 | **权值:** 145 | 146 | 一个无符号8位整型值,表示流的优先级权值(see [Section 5.3](https://http2.github.io/http2-spec/#StreamPriority))。这个值的范围为1到256。这个字段只有在PRIORITY标记设置时才会出现。 147 | 148 | > Header Block Fragment: 149 | > A header block fragment (Section 4.3). 150 | 151 | **首部块片段:** 152 | 153 | 一个首部块片段([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock))。 154 | 155 | > Padding: 156 | > Padding octets. 157 | 158 | **填充:** 159 | 160 | 填充字节。 161 | 162 | > The HEADERS frame defines the following flags: 163 | 164 | HEADERS帧定义了如下的标记: 165 | 166 | > END_STREAM (0x1): 167 | > When set, bit 0 indicates that the header block (Section 4.3) is the last that the endpoint will send for the identified stream. 168 | 169 | **END_STREAM (0x1):** 170 | 171 | 当设置时,位0表示这个首部块([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock))是终端将会为标识的流发送的最后一个块。 172 | 173 | > A HEADERS frame carries the END_STREAM flag that signals the end of a stream. However, a HEADERS frame with the END_STREAM flag set can be followed by CONTINUATION frames on the same stream. Logically, the CONTINUATION frames are part of the HEADERS frame. 174 | 175 | HEADERS帧携带了 END_STREAM标记,表明了流的结束。然而,在相同的流上,一个设置了END_STREAM标记的HEADERS帧后面可以跟着[CONTINUATION](https://http2.github.io/http2-spec/#CONTINUATION)帧。逻辑上来说,着[CONTINUATION](https://http2.github.io/http2-spec/#CONTINUATION)帧是HEADERS帧的一部分。 176 | 177 | > END_HEADERS (0x4): 178 | > When set, bit 2 indicates that this frame contains an entire header block (Section 4.3) and is not followed by any CONTINUATION frames. 179 | 180 | **END_HEADERS (0x4):** 181 | 182 | 当设置时,位2表示这个帧包含了这个首部块([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock)),而且后面没有任何的[CONTINUATION](https://http2.github.io/http2-spec/#CONTINUATION)帧。 183 | 184 | > A HEADERS frame without the END_HEADERS flag set MUST be followed by a CONTINUATION frame for the same stream. A receiver MUST treat the receipt of any other type of frame or a frame on a different stream as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 185 | 186 | 相同的流上,一个没有设置END_HEADERS标记的HEADERS帧后面 **必须(MUST)** 跟着一个[CONTINUATION](https://http2.github.io/http2-spec/#CONTINUATION)帧。接收者 **必须(MUST)** 将 接收到其它类型的帧,或在其它流上接收到了帧,当做是类型为[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误。 187 | 188 | > PADDED (0x8): 189 | > When set, bit 3 indicates that the Pad Length field and any padding that it describes are present. 190 | 191 | **PADDED (0x8):** 192 | 193 | 当设置时,位3表示将会有填充长度和它对应的填充出现。 194 | 195 | > PRIORITY (0x20): 196 | > When set, bit 5 indicates that the Exclusive Flag (E), Stream Dependency, and Weight fields are present; see Section 5.3. 197 | 198 | **PRIORITY (0x20):** 199 | 200 | 当设置时,位5指明独占标记(E),流依赖和权值字段将出现;参见[Section 5.3](https://http2.github.io/http2-spec/#StreamPriority)。 201 | 202 | > The payload of a HEADERS frame contains a header block fragment (Section 4.3). A header block that does not fit within a HEADERS frame is continued in a CONTINUATION frame (Section 6.10). 203 | 204 | HEADERS帧的载荷包含一个首部块片段([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock))。一个首部块无法装进一个HEADERS帧的话,将通过CONTINUATION帧来继续发送([Section 6.10](https://http2.github.io/http2-spec/#CONTINUATION))。 205 | 206 | > HEADERS frames MUST be associated with a stream. If a HEADERS frame is received whose stream identifier field is 0x0, the recipient MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 207 | 208 | HEADERS帧 **必须(MUST)** 与一个流关联。如果接收到了一个流标识符字段为0x0的HEADERS帧,则接收者 **必须(MUST)** 响应一个类型为[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 209 | 210 | > The HEADERS frame changes the connection state as described in Section 4.3. 211 | 212 | HEADERS帧如[Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock)中所述的那样改变连接的状态。 213 | 214 | > The HEADERS frame can include padding. Padding fields and flags are identical to those defined for DATA frames (Section 6.1). Padding that exceeds the size remaining for the header block fragment MUST be treated as a PROTOCOL_ERROR. 215 | 216 | HEADERS帧可以包含填充。填充字段和标记与DATA帧([Section 6.1](https://http2.github.io/http2-spec/#DATA))中定义的一致。填充超出了首部块片段的剩余大小 **必须(MUST)** 被当做一个 [PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)。 217 | 218 | > Prioritization information in a HEADERS frame is logically equivalent to a separate PRIORITY frame, but inclusion in HEADERS avoids the potential for churn in stream prioritization when new streams are created. Prioritization fields in HEADERS frames subsequent to the first on a stream reprioritize the stream (Section 5.3.3). 219 | 220 | HEADERS帧中包含的优先级信息在逻辑上等于另一个 [PRIORITY](https://http2.github.io/http2-spec/#PRIORITY)帧,但是包含在HEADERS中可以避免在创建新流时流优先级潜在的扰动。一个流中第一个之后的HEADERS帧中的优先级字段改变流的优先级([Section 5.3.3](https://http2.github.io/http2-spec/#reprioritize))。 221 | 222 | ## 6.3 PRIORITY 223 | 224 | > The PRIORITY frame (type=0x2) specifies the sender-advised priority of a stream (Section 5.3). It can be sent in any stream state, including idle or closed streams. 225 | 226 | PRIORITY帧 (type=0x2) 描述了给发送者建议的一个流的优先级([Section 5.3](https://http2.github.io/http2-spec/#StreamPriority))。它可以在任何流状态下发送,包括idle和closed流。 227 | 228 | ``` 229 | +-+-------------------------------------------------------------+ 230 | |E| Stream Dependency (31) | 231 | +-+-------------+-----------------------------------------------+ 232 | | Weight (8) | 233 | +-+-------------+ 234 | ``` 235 | > Figure 8: PRIORITY Frame Payload 236 | 237 | 图 8: PRIORITY帧载荷 238 | 239 | > The payload of a PRIORITY frame contains the following fields: 240 | 241 | PRIORITY帧包含如下的字段: 242 | 243 | > E: 244 | > A single-bit flag indicating that the stream dependency is exclusive (see Section 5.3). 245 | 246 | **E:** 一个单独的位标记指明流依赖是独占的(参见[Section 5.3](https://http2.github.io/http2-spec/#StreamPriority))。 247 | 248 | > Stream Dependency: 249 | > A 31-bit stream identifier for the stream that this stream depends on (see Section 5.3). 250 | 251 | **流依赖:** 252 | 一个31位的流标识符,指明了这个流依赖的流(参见 [Section 5.3](https://http2.github.io/http2-spec/#StreamPriority))。 253 | 254 | > Weight: 255 | > An unsigned 8-bit integer representing a priority weight for the stream (see Section 5.3). Add one to the value to obtain a weight between 1 and 256. 256 | 257 | **权值:** 258 | 一个无符号8位整型值,表示流的优先级权值(参见 [Section 5.3](https://http2.github.io/http2-spec/#StreamPriority))。该值的取值范围为1到256。 259 | 260 | > The PRIORITY frame does not define any flags. 261 | 262 | PRIORITY帧不定义任何标记。 263 | 264 | > The PRIORITY frame always identifies a stream. If a PRIORITY frame is received with a stream identifier of 0x0, the recipient MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 265 | 266 | PRIORITY帧总是标识一个流。如果接收到了一个流标识符为0x0的PRIORITY帧,则接收者 **必须(MUST)** 响应一个类型为[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 267 | 268 | > The PRIORITY frame can be sent on a stream in any state, though it cannot be sent between consecutive frames that comprise a single header block (Section 4.3). Note that this frame could arrive after processing or frame sending has completed, which would cause it to have no effect on the identified stream. For a stream that is in the "half-closed (remote)" or "closed" state, this frame can only affect processing of the identified stream and its dependent streams; it does not affect frame transmission on that stream. 269 | 270 | 可以在任何状态的流上发送RIORITY帧,尽管不能在包含了一个单独的首部块([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock))的连续两帧之间发送。注意,这个帧可能在处理或帧发送已经完成时到达,这将不对标识的流产生影响。对于处在"half-closed (remote)"或"closed"状态的流,这个帧只影响标识的流和依赖于它的流的处理;它不影响那些流的帧传输。 271 | 272 | > The PRIORITY frame can be sent for a stream in the "idle" or "closed" state. This allows for the reprioritization of a group of dependent streams by altering the priority of an unused or closed parent stream. 273 | 274 | 可以为处于"idle"或"closed"状态的流发送PRIORITY帧。这允许通过改变未使用或已关闭的父流的优先级来改变一组依赖流的优先级。 275 | 276 | > A PRIORITY frame with a length other than 5 octets MUST be treated as a stream error (Section 5.4.2) of type FRAME_SIZE_ERROR. 277 | 278 | PRIORITY帧的长度不是5个字节的话, **必须(MUST)** 被当做一个类型为[FRAME_SIZE_ERROR](https://http2.github.io/http2-spec/#FRAME_SIZE_ERROR)的流错误([Section 5.4.2](https://http2.github.io/http2-spec/#StreamErrorHandler))。 279 | 280 | ## 6.4 RST_STREAM 281 | 282 | > The RST_STREAM frame (type=0x3) allows for immediate termination of a stream. RST_STREAM is sent to request cancellation of a stream or to indicate that an error condition has occurred. 283 | 284 | RST_STREAM帧 (type=0x3)可以用于立即终止一个流。发送RST_STREAM来请求取消一个流,或者指明发生了一个错误状态。 285 | 286 | ``` 287 | +---------------------------------------------------------------+ 288 | | Error Code (32) | 289 | +---------------------------------------------------------------+ 290 | ``` 291 | > Figure 9: RST_STREAM Frame Payload 292 | 293 | Figure 9: RST_STREAM帧载荷 294 | 295 | > The RST_STREAM frame contains a single unsigned, 32-bit integer identifying the error code (Section 7). The error code indicates why the stream is being terminated. 296 | 297 | RST_STREAM帧包含了一个单独的无符号32位整型值的错误码([Section 7](https://http2.github.io/http2-spec/#ErrorCodes))。错误码指明了为什么要终止流。 298 | 299 | > The RST_STREAM frame does not define any flags. 300 | 301 | RST_STREAM帧不定义任何标记。 302 | 303 | > The RST_STREAM frame fully terminates the referenced stream and causes it to enter the "closed" state. After receiving a RST_STREAM on a stream, the receiver MUST NOT send additional frames for that stream, with the exception of PRIORITY. However, after sending the RST_STREAM, the sending endpoint MUST be prepared to receive and process additional frames sent on the stream that might have been sent by the peer prior to the arrival of the RST_STREAM. 304 | 305 | RST_STREAM帧完全终止引用的流,并使它进入"closed"状态。在一个流中收到一个RST_STREAM之后,接收者 **一定不能(MUST NOT)** 再为那个流发送额外的帧,[PRIORITY](https://http2.github.io/http2-spec/#PRIORITY)是例外。然而,在发送RST_STREAM之后,发送端 **必须(MUST)** 准备接收和处理额外的,可能由对端在RST_STREAM到达之前在那个流上发送的帧。 306 | 307 | > RST_STREAM frames MUST be associated with a stream. If a RST_STREAM frame is received with a stream identifier of 0x0, the recipient MUST treat this as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 308 | 309 | RST_STREAM帧 **必须(MUST)** 关联一个流。如果RST_STREAM帧的流标识符是0x0,则接收者 **必须(MUST)** 将其作为一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))处理。 310 | 311 | > RST_STREAM frames MUST NOT be sent for a stream in the "idle" state. If a RST_STREAM frame identifying an idle stream is received, the recipient MUST treat this as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 312 | 313 | RST_STREAM帧 **一定不能(MUST NOT)** 为"idle"状态的流而发送。如果接收了一个RST_STREAM帧,而它标识了一个idle流,则接收者 **必须(MUST)** 将其作为一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))处理。 314 | 315 | > A RST_STREAM frame with a length other than 4 octets MUST be treated as a connection error (Section 5.4.1) of type FRAME_SIZE_ERROR. 316 | 317 | RST_STREAM帧的长度不是4字节的话, **必须(MUST)** 被作为一个类型是[FRAME_SIZE_ERROR](https://http2.github.io/http2-spec/#FRAME_SIZE_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))处理。 318 | 319 | ## 6.5 SETTINGS 320 | 321 | > The SETTINGS frame (type=0x4) conveys configuration parameters that affect how endpoints communicate, such as preferences and constraints on peer behavior. The SETTINGS frame is also used to acknowledge the receipt of those parameters. Individually, a SETTINGS parameter can also be referred to as a "setting". 322 | 323 | SETTINGS帧 (type=0x4) 携带影响端点间如何通信的配置参数,比如关于对端行为的首选项和限制。SETTINGS帧也用于确认接收到了那些参数。个别地,一个SETTINGS参数也可以被称为一个"setting"。 324 | 325 | > SETTINGS parameters are not negotiated; they describe characteristics of the sending peer, which are used by the receiving peer. Different values for the same parameter can be advertised by each peer. For example, a client might set a high initial flow-control window, whereas a server might set a lower value to conserve resources. 326 | 327 | 不协商SETTINGS参数;它们描述了发送端的特性,而由接收端使用。端点之间对于相同参数可以广告不同的值。比如,一个客户端可以设置一个较大的初始flow-control窗口,然而服务器可以设置一个小的值来保留资源。 328 | 329 | > A SETTINGS frame MUST be sent by both endpoints at the start of a connection and MAY be sent at any other time by either endpoint over the lifetime of the connection. Implementations MUST support all of the parameters defined by this specification. 330 | 331 | SETTINGS帧 **必须(MUST)** 在连接开始时,两端都发送,而在连接整个生命期中其它的任何时间点,其中的一个端点 **可以(MAY)** 发送。实现 **必须(MUST)** 支持这份规范定义的所有参数。 332 | 333 | > Each parameter in a SETTINGS frame replaces any existing value for that parameter. Parameters are processed in the order in which they appear, and a receiver of a SETTINGS frame does not need to maintain any state other than the current value of its parameters. Therefore, the value of a SETTINGS parameter is the last value that is seen by a receiver. 334 | 335 | SETTINGS帧中的每个参数替换那个参数既有的值。参数以它们出现的顺序处理,SETTINGS帧的接收者不需要维护额外的状态,除了参数的当前值。因此,一个SETTINGS参数的值是接收者收到的最后的值。 336 | 337 | > SETTINGS parameters are acknowledged by the receiving peer. To enable this, the SETTINGS frame defines the following flag: 338 | 339 | SETTINGS参数由接收端作确认。为了启用这一点,SETTINGS帧定义了如下的标记: 340 | 341 | > ACK (0x1): 342 | > When set, bit 0 indicates that this frame acknowledges receipt and application of the peer's SETTINGS frame. When this bit is set, the payload of the SETTINGS frame MUST be empty. Receipt of a SETTINGS frame with the ACK flag set and a length field value other than 0 MUST be treated as a connection error (Section 5.4.1) of type FRAME_SIZE_ERROR. For more information, see Section 6.5.3 ("Settings Synchronization"). 343 | 344 | **ACK (0x1):** 设置时,位0指示了这个帧用于确认对端的SETTINGS帧的接收和应用。当设置了这个位时,SETTINGS帧的载荷必须是空的。接收到一个设置了ACK标记的SETTINGS帧,而长度字段的值不是0,这 **必须(MUST)** 被当做一个类型为[FRAME_SIZE_ERROR](https://http2.github.io/http2-spec/#FRAME_SIZE_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。要获得更多信息,请参考[Section 6.5.3](https://http2.github.io/http2-spec/#SettingsSync) ("[Settings Synchronization](https://http2.github.io/http2-spec/#SettingsSync)")。 345 | 346 | > SETTINGS frames always apply to a connection, never a single stream. The stream identifier for a SETTINGS frame MUST be zero (0x0). If an endpoint receives a SETTINGS frame whose stream identifier field is anything other than 0x0, the endpoint MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 347 | 348 | SETTINGS帧总是应用于一个连接,而不是一个单独的流。SETTINGS帧的流标识符 **必须(MUST)** 是零(0x0)。如果一个端点收到了一个流标识符字段不是0的SETTINGS帧,则 **必须(MUST)** 以一个类型为 [PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR) 的连接错误 ([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler)) 来响应。 349 | 350 | > The SETTINGS frame affects connection state. A badly formed or incomplete SETTINGS frame MUST be treated as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 351 | 352 | SETTINGS帧影响连接的状态。一个格式错误或不完整的SETTINGS帧 **必须(MUST)** 被当做一个类型为[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 353 | 354 | > A SETTINGS frame with a length other than a multiple of 6 octets MUST be treated as a connection error (Section 5.4.1) of type FRAME_SIZE_ERROR. 355 | 356 | SETTINGS帧的长度如果不是6字节的整数倍的话,必须被作为一个类型是FRAME_SIZE_ERROR](https://http2.github.io/http2-spec/#FRAME_SIZE_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 357 | 358 | 6.5.1 SETTINGS Format 359 | 360 | ### 6.5.1 SETTINGS格式 361 | 362 | > The payload of a SETTINGS frame consists of zero or more parameters, each consisting of an unsigned 16-bit setting identifier and an unsigned 32-bit value. 363 | 364 | SETTINGS帧的载荷由零个或多个参数组成,每个参数由一个无符号16位的设置标识符和一个无符号的32位值组成。 365 | 366 | ``` 367 | +-------------------------------+ 368 | | Identifier (16) | 369 | +-------------------------------+-------------------------------+ 370 | | Value (32) | 371 | +---------------------------------------------------------------+ 372 | ``` 373 | > Figure 10: Setting Format 374 | 375 | 图 10: 设置项的格式 376 | 377 | 6.5.2 Defined SETTINGS Parameters 378 | 379 | ### 6.5.2 已定义的SETTINGS参数 380 | 381 | > The following parameters are defined: 382 | 383 | 已定义了如下的参数: 384 | 385 | > SETTINGS_HEADER_TABLE_SIZE (0x1): 386 | > Allows the sender to inform the remote endpoint of the maximum size of the header compression table used to decode header blocks, in octets. The encoder can select any size equal to or less than this value by using signaling specific to the header compression format inside a header block (see [COMPRESSION]). The initial value is 4,096 octets. 387 | 388 | **SETTINGS_HEADER_TABLE_SIZE (0x1):** 389 | 允许发送者通知远端,用于解码首部块的首部压缩表的最大大小,以字节位单位。编码器可以可以选择任何等于或小于这个值的大小,通过使用首部块内信号特有的首部压缩格式(参考[[COMPRESSION] 390 | ](https://http2.github.io/http2-spec/#COMPRESSION))。初始值是4,096字节。 391 | 392 | > SETTINGS_ENABLE_PUSH (0x2): 393 | > This setting can be used to disable server push (Section 8.2). An endpoint MUST NOT send a PUSH_PROMISE frame if it receives this parameter set to a value of 0. An endpoint that has both set this parameter to 0 and had it acknowledged MUST treat the receipt of a PUSH_PROMISE frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 394 | 395 | **SETTINGS_ENABLE_PUSH (0x2):** 396 | 这个设置项可被用于禁用服务端推送([Section 8.2](https://http2.github.io/http2-spec/#PushResources))。一个终端如果收到了这个设置项,且值为0,则它 **一定不能(MUST NOT)** 发送[PUSH_PROMISE](https://http2.github.io/http2-spec/#PUSH_PROMISE)帧。一个已经将这个参数设置为了0,且已经收到了对这个设置项的确认的终端,则在收到一个[PUSH_PROMISE](https://http2.github.io/http2-spec/#PUSH_PROMISE)帧时, **必须(MUST)** 将其作为一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 397 | 398 | > The initial value is 1, which indicates that server push is permitted. Any value other than 0 or 1 MUST be treated as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 399 | 400 | 初始值是1,这表示服务端推送是允许的。任何0或1之外的值 **必须(MUST)** 被作为一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 401 | 402 | > SETTINGS_MAX_CONCURRENT_STREAMS (0x3): 403 | > Indicates the maximum number of concurrent streams that the sender will allow. This limit is directional: it applies to the number of streams that the sender permits the receiver to create. Initially, there is no limit to this value. It is recommended that this value be no smaller than 100, so as to not unnecessarily limit parallelism. 404 | 405 | **SETTINGS_MAX_CONCURRENT_STREAMS (0x3):** 406 | 指明了发送者允许的最大的并发流个数。这个限制是有方向的:它应用于发送者允许接收者创建的流的个数。初始时,这个值没有限制。建议这个值不要小于100,以便于不要不必要地限制了并发性。 407 | 408 | > A value of 0 for SETTINGS_MAX_CONCURRENT_STREAMS SHOULD NOT be treated as special by endpoints. A zero value does prevent the creation of new streams; however, this can also happen for any limit that is exhausted with active streams. Servers SHOULD only set a zero value for short durations; if a server does not wish to accept requests, closing the connection is more appropriate. 409 | 410 | SETTINGS_MAX_CONCURRENT_STREAMS被设置为0 **不应该(SHULD NOT)** 被终端特殊对待。值为0确实阻止创建新的流;然而,这也可能发生在活跃的流超出了限制的时候。服务器 **应该(SHOULD)** 只短暂地将这个值设为0;如果一个服务器不希望接受请求,关闭连接更合适。 411 | 412 | > SETTINGS_INITIAL_WINDOW_SIZE (0x4): 413 | > Indicates the sender's initial window size (in octets) for stream-level flow control. The initial value is 216-1 (65,535) octets. 414 | 415 | **SETTINGS_INITIAL_WINDOW_SIZE (0x4):** 416 | 指明了发送者stream-level flow control的初始窗口大小(以字节为单位)。初始值为2^16 - 1 (65,535)字节。 417 | 418 | > This setting affects the window size of all streams (see Section 6.9.2). 419 | 420 | 这个设置项影响所有流的窗口大小(参见[Section 6.9.2](https://http2.github.io/http2-spec/#InitialWindowSize))。 421 | 422 | > Values above the maximum flow-control window size of 231-1 MUST be treated as a connection error (Section 5.4.1) of type FLOW_CONTROL_ERROR. 423 | 424 | 值大于2^31-1的最大flow-control窗口大小 **必须(MUST)** 被作为一个类型是[FLOW_CONTROL_ERROR](https://http2.github.io/http2-spec/#FLOW_CONTROL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 425 | 426 | > SETTINGS_MAX_FRAME_SIZE (0x5): 427 | > Indicates the size of the largest frame payload that the sender is willing to receive, in octets. 428 | 429 | **SETTINGS_MAX_FRAME_SIZE (0x5):** 430 | 指明了发送者期望接收的最大的帧载荷大小,以字节为单位。 431 | 432 | > The initial value is 214 (16,384) octets. The value advertised by an endpoint MUST be between this initial value and the maximum allowed frame size (224-1 or 16,777,215 octets), inclusive. Values outside this range MUST be treated as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 433 | 434 | 初始值是2^14 (16,384)。终端广告的值 **必须(MUST)** 介于初始值和允许的最大帧大小(2^24-1 or 16,777,215 字节)之间,包含。这个范围之外的值 **必须(MUST)** 被作为一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 435 | 436 | > SETTINGS_MAX_HEADER_LIST_SIZE (0x6): 437 | > This advisory setting informs a peer of the maximum size of header list that the sender is prepared to accept, in octets. The value is based on the uncompressed size of header fields, including the length of the name and value in octets plus an overhead of 32 octets for each header field. 438 | 439 | **SETTINGS_MAX_HEADER_LIST_SIZE (0x6):** 440 | 这个建议性的设置通知对端发送者准备接受的首部列表的最大大小,以字节为单位。这个值是基于首部字段未压缩的大小来计算的,包括名字和值以字节为单位的长度,再为每个首部字段加上32字节。 441 | 442 | > For any given request, a lower limit than what is advertised MAY be enforced. The initial value of this setting is unlimited. 443 | 444 | 对于任何给定的请求,**可以(MAY)** 实施小于广告的限制的值。这个设置项的初始值没有限制。 445 | 446 | > An endpoint that receives a SETTINGS frame with any unknown or unsupported identifier MUST ignore that setting. 447 | 448 | 一个终端接收了一个SETTINGS帧,其中未知的或不支持的标识符的设置项 **必须(MUST)** 被忽略。 449 | 450 | 6.5.3 Settings Synchronization 451 | 452 | ### 6.5.3 设置同步 453 | 454 | > Most values in SETTINGS benefit from or require an understanding of when the peer has received and applied the changed parameter values. In order to provide such synchronization timepoints, the recipient of a SETTINGS frame in which the ACK flag is not set MUST apply the updated parameters as soon as possible upon receipt. 455 | 456 | SETTINGS中的大多数值受益于或需要知道对端在何时接收并应用改变的参数值。为了提供这种同步时间点,一个ACK标记没有设置的SETTINGS帧的接收者 **必须(MUST)** 一收到帧就尽可能快地应用更新后的参数。 457 | 458 | > The values in the SETTINGS frame MUST be processed in the order they appear, with no other frame processing between values. Unsupported parameters MUST be ignored. Once all values have been processed, the recipient MUST immediately emit a SETTINGS frame with the ACK flag set. Upon receiving a SETTINGS frame with the ACK flag set, the sender of the altered parameters can rely on the setting having been applied. 459 | 460 | SETTINGS帧中的参数 **必须(MUST)** 以它们出现的顺序处理,值之间没有对其它帧的处理。不支持的参数 **必须(MUST)** 被忽略。一旦处理了所有值,则接收者 **必须(MUST)** 立即发送一个设置了ACK标记的SETTINGS帧。一旦接收到设置了ACK标记的SETTINGS帧,改变了参数的发送者可以依赖于已经应用的设置了。 461 | 462 | > If the sender of a SETTINGS frame does not receive an acknowledgement within a reasonable amount of time, it MAY issue a connection error (Section 5.4.1) of type SETTINGS_TIMEOUT. 463 | 464 | 如果SETTINGS帧的发送者没有在合理的时间内收到确认,它 **可以(MAY)** 产生一个类型为[SETTINGS_TIMEOUT](https://http2.github.io/http2-spec/#SETTINGS_TIMEOUT)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 465 | 466 | ## 6.6 PUSH_PROMISE 467 | 468 | > The PUSH_PROMISE frame (type=0x5) is used to notify the peer endpoint in advance of streams the sender intends to initiate. The PUSH_PROMISE frame includes the unsigned 31-bit identifier of the stream the endpoint plans to create along with a set of headers that provide additional context for the stream. Section 8.2 contains a thorough description of the use of PUSH_PROMISE frames. 469 | 470 | PUSH_PROMISE帧 (type=0x5)用于通知对端发送方想要启动一个流。PUSH_PROMISE帧包含终端计划创建的流的无符号31位标识符,及为流提供额外上下为的一系列的首部。[Section 8.2](https://http2.github.io/http2-spec/#PushResources)包含对于PUSH_PROMISE帧的使用的一个详尽的描述。 471 | 472 | ``` 473 | +---------------+ 474 | |Pad Length? (8)| 475 | +-+-------------+-----------------------------------------------+ 476 | |R| Promised Stream ID (31) | 477 | +-+-----------------------------+-------------------------------+ 478 | | Header Block Fragment (*) ... 479 | +---------------------------------------------------------------+ 480 | | Padding (*) ... 481 | +---------------------------------------------------------------+ 482 | ``` 483 | > Figure 11: PUSH_PROMISE Payload Format 484 | 485 | 图 11: PUSH_PROMISE载荷格式 486 | 487 | > The PUSH_PROMISE frame payload has the following fields: 488 | 489 | PUSH_PROMISE帧载荷具有如下的字段: 490 | 491 | > Pad Length: 492 | > An 8-bit field containing the length of the frame padding in units of octets. This field is only present if the PADDED flag is set. 493 | 494 | **填充长度:** 495 | 一个8位的字段,包含了以字节为单位的帧填充的长度。只有在PADDED标记设置时这个字段才会出现。 496 | 497 | > R: 498 | > A single reserved bit. 499 | 500 | **R:** 501 | 一个保留位。 502 | 503 | > Promised Stream ID: 504 | > An unsigned 31-bit integer that identifies the stream that is reserved by the PUSH_PROMISE. The promised stream identifier MUST be a valid choice for the next stream sent by the sender (see "new stream identifier" in Section 5.1.1). 505 | 506 | **约定流ID:** 507 | 一个无符号31位整数,标识了PUSH_PROMISE保留的流。约定流标识符 **必须(MUST)** 是发送者后续要发送的流的一个有效的流标识符(参见 [Section 5.1.1](https://http2.github.io/http2-spec/#StreamIdentifiers)中的"新的流标识符")。 508 | 509 | > Header Block Fragment: 510 | > A header block fragment (Section 4.3) containing request header fields. 511 | 512 | **首部块片段:** 513 | 一个首部块片段([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock))包含了请求的首部字段。 514 | 515 | > Padding: 516 | > Padding octets. 517 | 518 | **填充:** 填充字节。 519 | 520 | > The PUSH_PROMISE frame defines the following flags: 521 | 522 | PUSH_PROMISE帧定义了如下的标记: 523 | 524 | > END_HEADERS (0x4): 525 | > When set, bit 2 indicates that this frame contains an entire header block (Section 4.3) and is not followed by any CONTINUATION frames. 526 | 527 | **END_HEADERS (0x4):** 528 | 设置时,位2表示这个帧包含一个完整的首部块([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock)),而且后面没有[CONTINUATION](https://http2.github.io/http2-spec/#CONTINUATION)帧。 529 | 530 | > A PUSH_PROMISE frame without the END_HEADERS flag set MUST be followed by a CONTINUATION frame for the same stream. A receiver MUST treat the receipt of any other type of frame or a frame on a different stream as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 531 | 532 | PUSH_PROMISE帧的END_HEADERS标记没有设置的话,它的后面 **必须(MUST)** 要有相同流的CONTINUATION帧。接收者 **必须(MUST)** 将收到其它类型的帧,或在一个不同的流上收到帧,作为一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 533 | 534 | > PADDED (0x8): 535 | > hen set, bit 3 indicates that the Pad Length field and any padding that it describes are present. 536 | 537 | **PADDED (0x8):** 538 | 设置时,位2表示 **填充长度** 字段和它所对应的填充将会出现。 539 | 540 | > PUSH_PROMISE frames MUST only be sent on a peer-initiated stream that is in either the "open" or "half-closed (remote)" state. The stream identifier of a PUSH_PROMISE frame indicates the stream it is associated with. If the stream identifier field specifies the value 0x0, a recipient MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 541 | 542 | PUSH_PROMISE帧 **必须(MUST)** 只在对端初始化的处于"open"或 "half-closed (remote)"状态的流上发送。PUSH_PROMISE帧的流标识符指明了它关联的流。如果流标识符字段是0x0,则接收者 **必须(MUST)** 响应一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 543 | 544 | > Promised streams are not required to be used in the order they are promised. The PUSH_PROMISE only reserves stream identifiers for later use. 545 | 546 | 约定的流不需要以它们约定的顺序使用。PUSH_PROMISE只为后面的使用保留了流标识符。 547 | 548 | > PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH setting of the peer endpoint is set to 0. An endpoint that has set this setting and has received acknowledgement MUST treat the receipt of a PUSH_PROMISE frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 549 | 550 | 如果对端将[SETTINGS_ENABLE_PUSH](https://http2.github.io/http2-spec/#SETTINGS_ENABLE_PUSH)设置为了0,则 **一定不能(MUST NOT)** 发送PUSH_PROMISE。已经设置了这个设定项且已经收到了确认的终端,收到了一个PUSH_PROMISE帧,则它 **必须(MUST)** 将这作为一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 551 | 552 | > Recipients of PUSH_PROMISE frames can choose to reject promised streams by returning a RST_STREAM referencing the promised stream identifier back to the sender of the PUSH_PROMISE. 553 | 554 | PUSH_PROMISE的接收者可以通过返回一个引用了约定的流标识符的[RST_STREAM](https://http2.github.io/http2-spec/#RST_STREAM)给PUSH_PROMISE的发送者来拒绝约定的流。 555 | 556 | > A PUSH_PROMISE frame modifies the connection state in two ways. First, the inclusion of a header block (Section 4.3) potentially modifies the state maintained for header compression. Second, PUSH_PROMISE also reserves a stream for later use, causing the promised stream to enter the "reserved" state. A sender MUST NOT send a PUSH_PROMISE on a stream unless that stream is either "open" or "half-closed (remote)"; the sender MUST ensure that the promised stream is a valid choice for a new stream identifier (Section 5.1.1) (that is, the promised stream MUST be in the "idle" state). 557 | 558 | PUSH_PROMISE帧以两种方式改变连接状态。首先,它包含的首部块([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock))潜在地改变为首部压缩维护的状态。其次,PUSH_PROMISE也为后续的使用保留一个流,这使得约定的流进入"reserved"状态。除非流处于"open"或"half-closed (remote)"状态,否则发送者 **一定不能(MUST NOT)** 在那个流上发送PUSH_PROMISE;发送者 **必须(MUST)** 确保约定的流是一个新的流标识符([Section 5.1.1](https://http2.github.io/http2-spec/#StreamIdentifiers))的有效的选择(即,约定的流 **必须(MUST)** 处于"idle"状态)。 559 | 560 | > Since PUSH_PROMISE reserves a stream, ignoring a PUSH_PROMISE frame causes the stream state to become indeterminate. A receiver MUST treat the receipt of a PUSH_PROMISE on a stream that is neither "open" nor "half-closed (local)" as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. However, an endpoint that has sent RST_STREAM on the associated stream MUST handle PUSH_PROMISE frames that might have been created before the RST_STREAM frame is received and processed. 561 | 562 | 由于PUSH_PROMISE保留一个流,则忽略一个PUSH_PROMISE帧导致流的状态变为不确定的。接收者必须将不处于"open"或"half-closed (local)"状态的流上接收到的PUSH_PROMISE作为一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。然而,已经在关联的流上发送了[RST_STREAM](https://http2.github.io/http2-spec/#RST_STREAM)的终端, **必须(MUST)** 处理可能在RST_STREAM](https://http2.github.io/http2-spec/#RST_STREAM)帧接收和处理之前创建的PUSH_PROMISE帧。 563 | 564 | > A receiver MUST treat the receipt of a PUSH_PROMISE that promises an illegal stream identifier (Section 5.1.1) as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. Note that an illegal stream identifier is an identifier for a stream that is not currently in the "idle" state. 565 | 566 | 接收者接收了一个PUSH_PROMISE,但其约定了一个非法的流标识符([Section 5.1.1](https://http2.github.io/http2-spec/#StreamIdentifiers)),则接收者必须将这作为一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。注意,非法的流标识符是当前不处于"idle"状态的流的标识符。 567 | 568 | > The PUSH_PROMISE frame can include padding. Padding fields and flags are identical to those defined for DATA frames (Section 6.1). 569 | 570 | PUSH_PROMISE帧可能包含填充。填充字段和标记与DATA帧一节([Section 6.1](https://http2.github.io/http2-spec/#DATA))中定义的一致。 571 | 572 | ## 6.7 PING 573 | 574 | > The PING frame (type=0x6) is a mechanism for measuring a minimal round-trip time from the sender, as well as determining whether an idle connection is still functional. PING frames can be sent from any endpoint. 575 | 576 | PING帧 (type=0x6) 是一种测量自发送者开始的最小往返时间的机制,也用于测定一个idle连接是否仍然有效。PING帧可以自连接的任何一端发送。 577 | 578 | ``` 579 | +---------------------------------------------------------------+ 580 | | | 581 | | Opaque Data (64) | 582 | | | 583 | +---------------------------------------------------------------+ 584 | ``` 585 | > Figure 12: PING Payload Format 586 | 587 | 图 12: PING 载荷格式 588 | 589 | > In addition to the frame header, PING frames MUST contain 8 octets of opaque data in the payload. A sender can include any value it chooses and use those octets in any fashion. 590 | 591 | 除了帧首部,PING帧 **必须(MUST)** 在载荷中包含8字节的不透明数据。发送者可以包含它选择的任何值,并且可以以任何方式使用它们。 592 | 593 | > Receivers of a PING frame that does not include an ACK flag MUST send a PING frame with the ACK flag set in response, with an identical payload. PING responses SHOULD be given higher priority than any other frame. 594 | 595 | 没有包含ACK标记的PING帧的接收者 **必须(MUST)** 必须在响应中发送一个设置了ACK标记的PING帧,且载荷要一致。**应该(SHOULD)** 给PING响应一个相对于其它帧更高的优先级 596 | 597 | > The PING frame defines the following flags: 598 | 599 | PING帧定义了如下的标记: 600 | 601 | > ACK (0x1): 602 | > When set, bit 0 indicates that this PING frame is a PING response. An endpoint MUST set this flag in PING responses. An endpoint MUST NOT respond to PING frames containing this flag. 603 | 604 | **ACK (0x1):** 605 | 当设置时,位0指明了这个PING帧是一个PING响应。终端在PING响应中 **必须(MUST)** 设置这个标记。终端 **一定不能(MUST NOT)** 响应包含了这个标记的PING帧。 606 | 607 | > PING frames are not associated with any individual stream. If a PING frame is received with a stream identifier field value other than 0x0, the recipient MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 608 | 609 | PING帧不与任何独立的流关联。如果接收到一个流标识符字段不是0的PING帧,接收者必须以一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))来响应。 610 | 611 | > Receipt of a PING frame with a length field value other than 8 MUST be treated as a connection error (Section 5.4.1) of type FRAME_SIZE_ERROR. 612 | 613 | 接收到一个PING帧,其长度字段的值不是8,则 **必须(MUST)** 被作为一个类型是[FRAME_SIZE_ERROR](https://http2.github.io/http2-spec/#FRAME_SIZE_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 614 | 615 | ## 6.8 GOAWAY 616 | 617 | > The GOAWAY frame (type=0x7) is used to initiate shutdown of a connection or to signal serious error conditions. GOAWAY allows an endpoint to gracefully stop accepting new streams while still finishing processing of previously established streams. This enables administrative actions, like server maintenance. 618 | 619 | GOAWAY帧(type=0x7)用于初始化一个连接的关闭,或通知严重的错误条件。GOAWAY允许一个终端在处理之前建立的流的同时优雅地停止接收新的流。这使管理操作称为可能,如服务器维护。 620 | 621 | > There is an inherent race condition between an endpoint starting new streams and the remote sending a GOAWAY frame. To deal with this case, the GOAWAY contains the stream identifier of the last peer-initiated stream that was or might be processed on the sending endpoint in this connection. For instance, if the server sends a GOAWAY frame, the identified stream is the highest-numbered stream initiated by the client. 622 | 623 | 在一个终端启动新流和远端发送一个GOAWAY帧之间有内在的竞态条件。要处理这种情况,GOAWAY包含这个连接中,发送端处理或可能会处理的由对端初始化的最后的流的流标识符。比如,如果服务器发送了一个GOAWAY帧,则标识的流是客户端初始化的流标识符最大的流。 624 | 625 | > Once sent, the sender will ignore frames sent on streams initiated by the receiver if the stream has an identifier higher than the included last stream identifier. Receivers of a GOAWAY frame MUST NOT open additional streams on the connection, although a new connection can be established for new streams. 626 | 627 | GOAWAY帧一旦发送,则发送者将忽略由接收者初始化的,流标识符大于帧中包含的流标识符的流上发送的帧。GOAWAY的接收者 **一定不能(MUST NOT)** 在连接上打开额外的流,尽管可以为新的流创建一个新的连接。 628 | 629 | > If the receiver of the GOAWAY has sent data on streams with a higher stream identifier than what is indicated in the GOAWAY frame, those streams are not or will not be processed. The receiver of the GOAWAY frame can treat the streams as though they had never been created at all, thereby allowing those streams to be retried later on a new connection. 630 | 631 | 如果GOAWAY的接收者已经在流标识符比GOAWAY帧中指明的更大的流上发送了数据,那些流将不会被处理。GOAWAY帧的接收者可以像它们从来没有创建一样处理,因此允许那些流稍后在一个新的连接上重试。 632 | 633 | > Endpoints SHOULD always send a GOAWAY frame before closing a connection so that the remote peer can know whether a stream has been partially processed or not. For example, if an HTTP client sends a POST at the same time that a server closes a connection, the client cannot know if the server started to process that POST request if the server does not send a GOAWAY frame to indicate what streams it might have acted on. 634 | 635 | 终端 **应该(SHOULD)** 总是在关闭连接之前发送一个GOAWAY帧,以使远处的对端可以知道一个流是否被部分处理了,还是么有。比如,如果一个HTTP客户端在服务器关闭一个连接的同时发送了一个POST,如果服务器不发送GOAWAY帧指明它已经处理的流的话,客户端无法知道服务器是否启动了对那个POST请求的处理。 636 | 637 | > An endpoint might choose to close a connection without sending a GOAWAY for misbehaving peers. 638 | 639 | 一个终端可能选择在不发送GOAWAY的情况下关闭连接来使对端行为不当。 640 | 641 | > A GOAWAY frame might not immediately precede closing of the connection; a receiver of a GOAWAY that has no more use for the connection SHOULD still send a GOAWAY frame before terminating the connection. 642 | 643 | 一个GOAWAY帧可以不紧贴着连接的关闭;不再使用连接的GOAWAY的接收者依然 **应该(SHOULD)** 在终止连接之前发送GOAWAY帧。 644 | 645 | ``` 646 | +-+-------------------------------------------------------------+ 647 | |R| Last-Stream-ID (31) | 648 | +-+-------------------------------------------------------------+ 649 | | Error Code (32) | 650 | +---------------------------------------------------------------+ 651 | | Additional Debug Data (*) | 652 | +---------------------------------------------------------------+ 653 | ``` 654 | > Figure 13: GOAWAY Payload Format 655 | 656 | 图 13: GOAWAY载荷格式 657 | 658 | > The GOAWAY frame does not define any flags. 659 | 660 | GOAWAY帧不定义任何标记。 661 | 662 | > The GOAWAY frame applies to the connection, not a specific stream. An endpoint MUST treat a GOAWAY frame with a stream identifier other than 0x0 as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 663 | 664 | GOAWAY帧应用于连接,而不是特定的流。一个终端 **必须(MUST)** 将一个流标识符不是0x0的GOAWAY帧作为一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 665 | 666 | > The last stream identifier in the GOAWAY frame contains the highest-numbered stream identifier for which the sender of the GOAWAY frame might have taken some action on or might yet take action on. All streams up to and including the identified stream might have been processed in some way. The last stream identifier can be set to 0 if no streams were processed. 667 | 668 | GOAWAY帧中的最后的流标识符包含了GOAWAY帧的发送者可能已经处理或可能会处理的最大的流标识符。所有流标识符小于等于标识的流的流可能已经以某种方式被处理了。如果没有流被处理的话,最后的流标识符可以被设置为0. 669 | 670 | > Note: In this context, "processed" means that some data from the stream was passed to some higher layer of software that might have taken some action as a result. 671 | 672 | **注意:** 在这个上下文中,"处理"意味着来自于流的一些数据被传给了一些更高层级的软件,那些软件可能已经做了一些处理。 673 | 674 | > If a connection terminates without a GOAWAY frame, the last stream identifier is effectively the highest possible stream identifier. 675 | 676 | 如果流终止了,而没有GOAWAY帧,则最后的流标识符实际上是最大的可能流标识符。 677 | 678 | > On streams with lower- or equal-numbered identifiers that were not closed completely prior to the connection being closed, reattempting requests, transactions, or any protocol activity is not possible, with the exception of idempotent actions like HTTP GET, PUT, or DELETE. Any protocol activity that uses higher-numbered streams can be safely retried using a new connection. 679 | 680 | 具有比标识的流的标识符更低或等于,在连接关闭前没有完全关掉的流,重试请求,事务,或任何的协议活动都是不合理的,除了幂等的行为,比如HTTP GET,PUT,或DELETE。任何使用了更大的流标识符的流的协议活动可以安全地使用一个新的连接来重试。 681 | 682 | > Activity on streams numbered lower or equal to the last stream identifier might still complete successfully. The sender of a GOAWAY frame might gracefully shut down a connection by sending a GOAWAY frame, maintaining the connection in an "open" state until all in-progress streams complete. 683 | 684 | 流标识符小于等于最后的流标识符的流上的活动可能依然可以成功完成。GOAWAY帧的发送者可以通过发送一个GOAWAY帧优雅地关闭一个连接,维护处于"open"状态地连接,直到所有进行中的流完成。 685 | 686 | > An endpoint MAY send multiple GOAWAY frames if circumstances change. For instance, an endpoint that sends GOAWAY with NO_ERROR during graceful shutdown could subsequently encounter a condition that requires immediate termination of the connection. The last stream identifier from the last GOAWAY frame received indicates which streams could have been acted upon. Endpoints MUST NOT increase the value they send in the last stream identifier, since the peers might already have retried unprocessed requests on another connection. 687 | 688 | 如果条件变了的话,一个终端 **可以(MAY)** 发送多个GOAWAY帧。比如,一个终端在优雅的关闭期间发送了一个带有[NO_ERROR](https://http2.github.io/http2-spec/#NO_ERROR)错误码的GOAWAY,后面遇到了一个需要立即关闭连接的条件。收到的最后的GOAWAY帧中的最后流标识符字段指明了可能已经处理的流。终端 **一定不能(MUST NOT)** 增加它们发送的最后流标识符字段的值,因为对端可能已经在另一个连接上重试了未处理的请求。 689 | 690 | > A client that is unable to retry requests loses all requests that are in flight when the server closes the connection. This is especially true for intermediaries that might not be serving clients using HTTP/2. A server that is attempting to gracefully shut down a connection SHOULD send an initial GOAWAY frame with the last stream identifier set to 231-1 and a NO_ERROR code. This signals to the client that a shutdown is imminent and that initiating further requests is prohibited. After allowing time for any in-flight stream creation (at least one round-trip time), the server can send another GOAWAY frame with an updated last stream identifier. This ensures that a connection can be cleanly shut down without losing requests. 691 | 692 | 一个不能重试请求的客户端丢失所有在服务器关闭连接时处于飞行中状态的请求。特别是对于不为使用HTTP/2的客户端服务的intermediaries。一个试图优雅地关闭一个连接的服务器 **应该(SHOULD)** 发送一个初始的GOAWAY帧,其中的最后流标识符被设为2^31-1,并包含[NO_ERROR](https://http2.github.io/http2-spec/#NO_ERROR)错误码。这通知客户端连接即将关闭,禁止初始化更多的请求。在一段为飞行中的流创建准备的时间之后(至少一个来回的时间),服务器可以发送另一个GOAWAY帧,其中携带了一个更新过的最后流标识符。这确保连接可以被干净地关闭而不会丢失氢气。 693 | 694 | > After sending a GOAWAY frame, the sender can discard frames for streams initiated by the receiver with identifiers higher than the identified last stream. However, any frames that alter connection state cannot be completely ignored. For instance, HEADERS, PUSH_PROMISE, and CONTINUATION frames MUST be minimally processed to ensure the state maintained for header compression is consistent (see Section 4.3); similarly, DATA frames MUST be counted toward the connection flow-control window. Failure to process these frames can cause flow control or header compression state to become unsynchronized. 695 | 696 | 发送一个GOAWAY帧之后,发送者可以丢弃由接收者初始化的,流标识符大于最后的流标识的流。然而,任何改变连接状态的帧不能被完全忽略。比如[HEADERS](https://http2.github.io/http2-spec/#HEADERS),[PUSH_PROMISE](https://http2.github.io/http2-spec/#PUSH_PROMISE),和[CONTINUATION](https://http2.github.io/http2-spec/#CONTINUATION)帧必须被最低限度地处理掉以确保为首部压缩维护的状态是一致的(参见[Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock));类似地,DATA帧 **必须(MUST)** 被计入连接的flow-control窗口。处理这些帧失败的话可能导致flow control或首部压缩状态变得不同步。 697 | 698 | > The GOAWAY frame also contains a 32-bit error code (Section 7) that contains the reason for closing the connection. 699 | 700 | GOAWAY帧也包含了一个32位的错误码([Section 7](https://http2.github.io/http2-spec/#ErrorCodes)),其中包含了关闭连接的原因。 701 | 702 | > Endpoints MAY append opaque data to the payload of any GOAWAY frame. Additional debug data is intended for diagnostic purposes only and carries no semantic value. Debug information could contain security- or privacy-sensitive data. Logged or otherwise persistently stored debug data MUST have adequate safeguards to prevent unauthorized access. 703 | 704 | 终端 **可以(MAY)** 给GOAWAY帧的载荷附加不透明的数据。附加的调试数据只用于诊断目的,而不携带语义值。调试信息可能包含安全或隐私数据。记录或持续存储调试信息 **必须(MUST)** 具有充足的保护措施来防止未授权的访问。 705 | 706 | ## 6.9 WINDOW_UPDATE 707 | 708 | > The WINDOW_UPDATE frame (type=0x8) is used to implement flow control; see Section 5.2 for an overview. 709 | 710 | WINDOW_UPDATE帧(type=0x8)用于实现flow control;参考[Section 5.2](https://http2.github.io/http2-spec/#FlowControl)来做整体的了解。 711 | 712 | > Flow control operates at two levels: on each individual stream and on the entire connection. 713 | 714 | Flow control操作于两个层次:在每个单独的流上,和整个连接上。 715 | 716 | > Both types of flow control are hop by hop, that is, only between the two endpoints. Intermediaries do not forward WINDOW_UPDATE frames between dependent connections. However, throttling of data transfer by any receiver can indirectly cause the propagation of flow-control information toward the original sender. 717 | 718 | flow control的两种类型都是逐段的,即,只在两个端点之间。Intermediaries不在依赖的连接之间转发WINDOW_UPDATE帧。然而,任何接收者数据传输的限制可以间接地使得flow-control信息被传播到最初的发送者。 719 | 720 | > Flow control only applies to frames that are identified as being subject to flow control. Of the frame types defined in this document, this includes only DATA frames. Frames that are exempt from flow control MUST be accepted and processed, unless the receiver is unable to assign resources to handling the frame. A receiver MAY respond with a stream error (Section 5.4.2) or connection error (Section 5.4.1) of type FLOW_CONTROL_ERROR if it is unable to accept a frame. 721 | 722 | Flow control只应用于被认为是受控于flow control的帧。就这份文档中定义的帧类型而言,这只包括[DATA](https://http2.github.io/http2-spec/#DATA)帧。那些免除flow control的帧 **必须(MUST)** 被接受并处理,除非接收者不能分配资源来处理帧。如果接收者不能接受一个帧,则它 **可以(MAY)** 响应一个类型是[FLOW_CONTROL_ERROR](https://http2.github.io/http2-spec/#FLOW_CONTROL_ERROR)的流错误([Section 5.4.2](https://http2.github.io/http2-spec/#StreamErrorHandler))或连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 723 | 724 | ``` 725 | +-+-------------------------------------------------------------+ 726 | |R| Window Size Increment (31) | 727 | +-+-------------------------------------------------------------+ 728 | ``` 729 | > Figure 14: WINDOW_UPDATE Payload Format 730 | 731 | 图 14: WINDOW_UPDATE载荷格式 732 | 733 | > The payload of a WINDOW_UPDATE frame is one reserved bit plus an unsigned 31-bit integer indicating the number of octets that the sender can transmit in addition to the existing flow-control window. The legal range for the increment to the flow-control window is 1 to 231-1 (2,147,483,647) octets. 734 | 735 | WINDOW_UPDATE帧的载荷由一个保留位外加一个无符号31位的整数组成,其中后者指明了发送者在已有的flow-control窗口之外可以传输的字节数。flow-control窗口合法的增量范围是1到2^31-1 (2,147,483,647)字节。 736 | 737 | > The WINDOW_UPDATE frame does not define any flags. 738 | 739 | WINDOW_UPDATE帧不定义任何标记。 740 | 741 | > The WINDOW_UPDATE frame can be specific to a stream or to the entire connection. In the former case, the frame's stream identifier indicates the affected stream; in the latter, the value "0" indicates that the entire connection is the subject of the frame. 742 | 743 | WINDOW_UPDATE帧可以应用于特定的流,也可以是整个连接。对于前者,帧的流标识符指明了受影响的流;而后者,"0"值指明了整个连接受控于该帧。 744 | 745 | > A receiver MUST treat the receipt of a WINDOW_UPDATE frame with an flow-control window increment of 0 as a stream error (Section 5.4.2) of type PROTOCOL_ERROR; errors on the connection flow-control window MUST be treated as a connection error (Section 5.4.1). 746 | 747 | 接收者 **必须(MUST)** 将收到flow-control窗口增量为0的WINDOW_UPDATE帧 作为一个类型为[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的流错误([Section 5.4.2](https://http2.github.io/http2-spec/#StreamErrorHandler));连接的flow-control窗口的错误flow-control **必须(MUST)** 被作为一个连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 748 | 749 | > WINDOW_UPDATE can be sent by a peer that has sent a frame bearing the END_STREAM flag. This means that a receiver could receive a WINDOW_UPDATE frame on a "half-closed (remote)" or "closed" stream. A receiver MUST NOT treat this as an error (see Section 5.1). 750 | 751 | WINDOW_UPDATE可以由已经发送了一个携带END_STREAM标记的帧的对端发送。这意味着接收者可能在一个"half-closed (remote)"或"closed"流上接收到WINDOW_UPDATE帧。接收者 **一定不能(MUST NOT)** 将这当做一个错误(参见 [Section 5.1](https://http2.github.io/http2-spec/#StreamStates)).。 752 | 753 | > A receiver that receives a flow-controlled frame MUST always account for its contribution against the connection flow-control window, unless the receiver treats this as a connection error (Section 5.4.1). This is necessary even if the frame is in error. The sender counts the frame toward the flow-control window, but if the receiver does not, the flow-control window at the sender and receiver can become different. 754 | 755 | 接收到一个flow-controlled帧的接收者 **必须(MUST)** 总是考虑到它对连接flow-control窗口的影响,除非接收者把这当做一个连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。即使帧是错误的这也是必须的。发送者将帧计入flow-control,但如果接收者没有这样做的话,发送者和接收者的flow-control窗口可能变得不同。 756 | 757 | > A WINDOW_UPDATE frame with a length other than 4 octets MUST be treated as a connection error (Section 5.4.1) of type FRAME_SIZE_ERROR. 758 | 759 | 长度不是4字节的WINDOW_UPDATE帧 **必须(MUST)** 被作为一个类型是[FRAME_SIZE_ERROR](https://http2.github.io/http2-spec/#FRAME_SIZE_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 760 | 761 | 6.9.1 The Flow-Control Window 762 | 763 | ### 6.9.1 Flow-Control窗口 764 | 765 | > Flow control in HTTP/2 is implemented using a window kept by each sender on every stream. The flow-control window is a simple integer value that indicates how many octets of data the sender is permitted to transmit; as such, its size is a measure of the buffering capacity of the receiver. 766 | 767 | HTTP/2中的Flow control使用一个由每个流上的每个发送者持有的窗口实现。flow-control窗口是一个简单的整型值,它指明了发送者允许传输的字节数;同样地,它的大小衡量了接收者的缓存能力。 768 | 769 | > Two flow-control windows are applicable: the stream flow-control window and the connection flow-control window. The sender MUST NOT send a flow-controlled frame with a length that exceeds the space available in either of the flow-control windows advertised by the receiver. Frames with zero length with the END_STREAM flag set (that is, an empty DATA frame) MAY be sent if there is no available space in either flow-control window. 770 | 771 | 两种flow-control窗口是适用的:流flow-control窗口和连接flow-control窗口。发送者 **一定不能(MUST NOT)** 发送一个长度超出了由接收者广告的任一种flow-control窗口的可用空间的flow-controlled帧。两种flow-control窗口中没有可用空间时,**可以(MAY)** 发送长度为0且END_STREAM标记被设置的帧(即,一个空的[DATA](https://http2.github.io/http2-spec/#DATA)帧)。 772 | 773 | > For flow-control calculations, the 9-octet frame header is not counted. 774 | 775 | 对于flow-control的计算,9字节的帧首部不计入内。 776 | 777 | > After sending a flow-controlled frame, the sender reduces the space available in both windows by the length of the transmitted frame. 778 | 779 | 发送一个flow-controlled帧之后,发送者给两个窗口中的可用空间都减小发送的帧的大小。 780 | 781 | > The receiver of a frame sends a WINDOW_UPDATE frame as it consumes data and frees up space in flow-control windows. Separate WINDOW_UPDATE frames are sent for the stream- and connection-level flow-control windows. 782 | 783 | 帧的接收者由于它消耗数据并释放flow-control窗口的空间而发送一个WINDOW_UPDATE帧。独立的WINDOW_UPDATE帧为流级及连接级的flow-control窗口而发送。 784 | 785 | > A sender that receives a WINDOW_UPDATE frame updates the corresponding window by the amount specified in the frame. 786 | 787 | 接收到一个WINDOW_UPDATE帧的发送者给对应窗口更新帧中描述的数量。 788 | 789 | > A sender MUST NOT allow a flow-control window to exceed 231-1 octets. If a sender receives a WINDOW_UPDATE that causes a flow-control window to exceed this maximum, it MUST terminate either the stream or the connection, as appropriate. For streams, the sender sends a RST_STREAM with an error code of FLOW_CONTROL_ERROR; for the connection, a GOAWAY frame with an error code of FLOW_CONTROL_ERROR is sent. 790 | 791 | 发送者 **一定不能(MUST NOT)** 允许一个flow-control窗口超出2^31-1字节。如果发送者接收了一个WINDOW_UPDATE,它导致flow-control窗口超出了最大值,则它 **必须(MUST)** 酌情终止流或连接。对于流,发送者发送一个[RST_STREAM](https://http2.github.io/http2-spec/#RST_STREAM),其中由一个错误码[FLOW_CONTROL_ERROR](https://http2.github.io/http2-spec/#FLOW_CONTROL_ERROR);对于连接,发送一个[GOAWAY](https://http2.github.io/http2-spec/#GOAWAY)帧,其中包含错误码[FLOW_CONTROL_ERROR](https://http2.github.io/http2-spec/#FLOW_CONTROL_ERROR)。 792 | 793 | > Flow-controlled frames from the sender and WINDOW_UPDATE frames from the receiver are completely asynchronous with respect to each other. This property allows a receiver to aggressively update the window size kept by the sender to prevent streams from stalling. 794 | 795 | 来自于发送者的Flow-controlled帧和来自于接收者的WINDOW_UPDATE帧相互之间是完全异步的。这个属性允许接收者侵略地更新由发送者保存的窗口大小来防止流的失速。 796 | 797 | 6.9.2 Initial Flow-Control Window Size 798 | 799 | ### 6.9.2 初始的Flow-Control窗口大小 800 | 801 | > When an HTTP/2 connection is first established, new streams are created with an initial flow-control window size of 65,535 octets. The connection flow-control window is also 65,535 octets. Both endpoints can adjust the initial window size for new streams by including a value for SETTINGS_INITIAL_WINDOW_SIZE in the SETTINGS frame that forms part of the connection preface. The connection flow-control window can only be changed using WINDOW_UPDATE frames. 802 | 803 | 当HTTP/2连接首次被建立时,新建立的流的初始flow-control窗口大小为65,535字节。连接的flow-control窗口也是65,535字节。两端可以通过在构成连接preface一部分的[SETTINGS](https://http2.github.io/http2-spec/#SETTINGS)帧中包含一个[SETTINGS_INITIAL_WINDOW_SIZE](https://http2.github.io/http2-spec/#SETTINGS_INITIAL_WINDOW_SIZE)值来为新流调整初始窗口大小。连接的flow-control窗口只能使用WINDOW_UPDATE帧来改变。 804 | 805 | > Prior to receiving a SETTINGS frame that sets a value for SETTINGS_INITIAL_WINDOW_SIZE, an endpoint can only use the default initial window size when sending flow-controlled frames. Similarly, the connection flow-control window is set to the default initial window size until a WINDOW_UPDATE frame is received. 806 | 807 | 在接收到设置了[SETTINGS_INITIAL_WINDOW_SIZE](https://http2.github.io/http2-spec/#SETTINGS_INITIAL_WINDOW_SIZE)值的[SETTINGS](https://http2.github.io/http2-spec/#SETTINGS)值之前,一个端点在发送flow-controlled帧时只能使用默认的初始窗口大小。类似地,连接的flow-control窗口在收到WINDOW_UPDATE帧之前,被设置为默认的初始窗口大小。 808 | 809 | > In addition to changing the flow-control window for streams that are not yet active, a SETTINGS frame can alter the initial flow-control window size for streams with active flow-control windows (that is, streams in the "open" or "half-closed (remote)" state). When the value of SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST adjust the size of all stream flow-control windows that it maintains by the difference between the new value and the old value. 810 | 811 | 除了给还不处于活跃状态的流修改flow-control,[SETTINGS](https://http2.github.io/http2-spec/#SETTINGS)帧可以改变具有活跃的flow-control窗口的流(即,处于"open"或"half-closed (remote)"状态的流)的初始flow-control窗口大小。当[SETTINGS_INITIAL_WINDOW_SIZE](https://http2.github.io/http2-spec/#SETTINGS_INITIAL_WINDOW_SIZE)的值改变时,接收者 **必须(MUST)** 根据新值和老值之间的差异调整它维护的所有的flow-control窗口的大小 812 | 813 | > A change to SETTINGS_INITIAL_WINDOW_SIZE can cause the available space in a flow-control window to become negative. A sender MUST track the negative flow-control window and MUST NOT send new flow-controlled frames until it receives WINDOW_UPDATE frames that cause the flow-control window to become positive. 814 | 815 | 对于[SETTINGS_INITIAL_WINDOW_SIZE](https://http2.github.io/http2-spec/#SETTINGS_INITIAL_WINDOW_SIZE)的改变,可能导致一个flow-control窗口中的可用空间变为负值。一个发送者 **必须(MUST)** 追踪负的flow-control窗口,且 **一定不能(MUST NOT)** 发送新的flow-controlled帧,直到它收到了使flow-control窗口变为正值的WINDOW_UPDATE帧。 816 | 817 | > For example, if the client sends 60 KB immediately on connection establishment and the server sets the initial window size to be 16 KB, the client will recalculate the available flow-control window to be -44 KB on receipt of the SETTINGS frame. The client retains a negative flow-control window until WINDOW_UPDATE frames restore the window to being positive, after which the client can resume sending. 818 | 819 | 比如,如果连接一建立客户端就立即发送了60 KB,而服务器将初始的窗口大小设置为16 KB,则客户端在收到[SETTINGS](https://http2.github.io/http2-spec/#SETTINGS)帧时将重新计算可用的flow-control窗口,其值为-44 KB。客户端保持负的flow-control窗口直到WINDOW_UPDATE帧将窗口恢复为正值,然后客户端可以恢复发送。 820 | 821 | > A SETTINGS frame cannot alter the connection flow-control window. 822 | 823 | 一个[SETTINGS](https://http2.github.io/http2-spec/#SETTINGS)帧不能改变连接的flow-control窗口。 824 | 825 | > An endpoint MUST treat a change to SETTINGS_INITIAL_WINDOW_SIZE that causes any flow-control window to exceed the maximum size as a connection error (Section 5.4.1) of type FLOW_CONTROL_ERROR. 826 | 827 | 终端必须将导致任何flow-control窗口超出最大大小的[SETTINGS_INITIAL_WINDOW_SIZE](https://http2.github.io/http2-spec/#SETTINGS_INITIAL_WINDOW_SIZE)的修改作为一个类型[FLOW_CONTROL_ERROR](https://http2.github.io/http2-spec/#FLOW_CONTROL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 828 | 829 | 6.9.3 Reducing the Stream Window Size 830 | 831 | ### 6.9.3 减小流窗口大小 832 | 833 | > A receiver that wishes to use a smaller flow-control window than the current size can send a new SETTINGS frame. However, the receiver MUST be prepared to receive data that exceeds this window size, since the sender might send data that exceeds the lower limit prior to processing the SETTINGS frame. 834 | 835 | 想要使用一个比当前大小更小的flow-control窗口的接收者可以发送一个新的[SETTINGS](https://http2.github.io/http2-spec/#SETTINGS)帧。然而,接收者 **必须(MUST)** 准备接收超出窗口大小的数据,因为发送者可能在处理[SETTINGS](https://http2.github.io/http2-spec/#SETTINGS)帧之前发送数据而超出了更低的限制。 836 | 837 | > After sending a SETTINGS frame that reduces the initial flow-control window size, a receiver MAY continue to process streams that exceed flow-control limits. Allowing streams to continue does not allow the receiver to immediately reduce the space it reserves for flow-control windows. Progress on these streams can also stall, since WINDOW_UPDATE frames are needed to allow the sender to resume sending. The receiver MAY instead send a RST_STREAM with an error code of FLOW_CONTROL_ERROR for the affected streams. 838 | 839 | 发送了一个减小初始flow-control窗口大小的SETTINGS帧之后,接收者 **可以(MAY)** 继续处理超出flow-control限制的流。允许流继续不允许接收者立即减小它为flow-control窗口保留的空间。这些流中的进程可能失速,由于需要[WINDOW_UPDATE](https://http2.github.io/http2-spec/#WINDOW_UPDATE)帧来允许发送者恢复发送。接收者 **可以(MAY)** 为受到影响的流发送错误码为[FLOW_CONTROL_ERROR](https://http2.github.io/http2-spec/#FLOW_CONTROL_ERROR)的[RST_STREAM](https://http2.github.io/http2-spec/#RST_STREAM)。 840 | 841 | ## 6.10 CONTINUATION 842 | 843 | > The CONTINUATION frame (type=0x9) is used to continue a sequence of header block fragments (Section 4.3). Any number of CONTINUATION frames can be sent, as long as the preceding frame is on the same stream and is a HEADERS, PUSH_PROMISE, or CONTINUATION frame without the END_HEADERS flag set. 844 | 845 | CONTINUATION帧 (type=0x9) 被用于继续发送首部块片段([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock))的序列。只要相同流上的前导帧是没有设置END_HEADERS标记的[HEADERS](https://http2.github.io/http2-spec/#HEADERS),[PUSH_PROMISE](https://http2.github.io/http2-spec/#PUSH_PROMISE),或CONTINUATION帧,就可以发送任意数量的CONTINUATION帧。 846 | 847 | ``` 848 | +---------------------------------------------------------------+ 849 | | Header Block Fragment (*) ... 850 | +---------------------------------------------------------------+ 851 | ``` 852 | > Figure 15: CONTINUATION Frame Payload 853 | 854 | 图 15: CONTINUATION帧载荷 855 | 856 | > The CONTINUATION frame payload contains a header block fragment (Section 4.3). 857 | 858 | CONTINUATION帧载荷包含一个首部块片段([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock))。 859 | 860 | > The CONTINUATION frame defines the following flag: 861 | 862 | CONTINUATION帧定义了如下的标记: 863 | 864 | > END_HEADERS (0x4): 865 | > When set, bit 2 indicates that this frame ends a header block (Section 4.3). 866 | 867 | **END_HEADERS (0x4):** 868 | 869 | 当设置时,位2指明这个帧结束了一个首部块([Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock))。 870 | 871 | > If the END_HEADERS bit is not set, this frame MUST be followed by another CONTINUATION frame. A receiver MUST treat the receipt of any other type of frame or a frame on a different stream as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 872 | 873 | 如果END_HEADERS位没有设置,则这个帧后面 **必须(MUST)** 跟着另一个CONTINUATION帧。如果一个接收者接收到了其它类型的帧,或在一个不同的流上接收到了帧,则必须将这作为类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 874 | 875 | > The CONTINUATION frame changes the connection state as defined in Section 4.3. 876 | 877 | CONTINUATION帧如[Section 4.3](https://http2.github.io/http2-spec/#HeaderBlock)中定义的那样改变连接状态。 878 | 879 | > CONTINUATION frames MUST be associated with a stream. If a CONTINUATION frame is received whose stream identifier field is 0x0, the recipient MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 880 | 881 | CONTINUATION帧 **必须(MUST)** 与一个流关联。如果接收到了一个流标识符字段为0x0的CONTINUATION帧,则接收者必须以一个类型为PROTOCOL_ERROR的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))来响应。 882 | 883 | > A CONTINUATION frame MUST be preceded by a HEADERS, PUSH_PROMISE or CONTINUATION frame without the END_HEADERS flag set. A recipient that observes violation of this rule MUST respond with a connection error (Section 5.4.1) of type PROTOCOL_ERROR. 884 | 885 | CONTINUATION帧的前面必须是END_HEADERS标记没有设置的[HEADERS](https://http2.github.io/http2-spec/#HEADERS),[PUSH_PROMISE](https://http2.github.io/http2-spec/#PUSH_PROMISE)或CONTINUATION帧。接收者如果发现违背了这个规则, **必须(MUST)** 响应一个类型是[PROTOCOL_ERROR](https://http2.github.io/http2-spec/#PROTOCOL_ERROR)的连接错误([Section 5.4.1](https://http2.github.io/http2-spec/#ConnectionErrorHandler))。 886 | --------------------------------------------------------------------------------