5.3. 立即关闭应用程序
HTTP/3实现可以在任何时候立即关闭QUIC连接。这将导致向对等方发送一个QUIC CONNECTION_CLOSE帧,这表明应用层已经终止了连接。此帧中的应用程序错误代码向对等方表明连接被关闭的原因。有关在 HTTP/3 中关闭连接时可以使用的错误代码,请参阅第 8 节。
在关闭连接之前,可能会发送一个 GOAWAY 帧以允许客户端重试某些请求。将GOAWAY帧包含在与QUIC CONNECTION_CLOSE帧相同的包中可以提高客户端接收帧的机会。
如果存在未明确关闭的打开流,则在关闭连接时将其悄悄关闭。
5.4. 运输关闭
由于各种原因,QUIC传输可以向应用层表明连接已经终止。这可能是由于对等方明确地关闭、传输层错误或中断连接的网络拓扑变化造成的。
如果连接在没有GOAWAY帧的情况下终止,客户端必须假定发送的任何请求,无论是全部的还是部分的,都可能已经被处理。
QUIC流提供可靠的字节按顺序传递,但不保证与其他流上的字节的传递顺序。在QUIC的版本1中,包含HTTP帧的流数据由QUIC stream帧承载,但是这个帧对HTTP帧层是不可见的。传输层对接收到的流数据进行缓冲和排序,向应用程序公开可靠的字节流。虽然QUIC允许在流中无序传递,但 HTTP/3 并未使用此功能。
QUIC 流可以是单向的,仅从发起者到接收者传输数据,也可以是双向的,双向传输数据。流可以由客户端或服务器发起。
当通过 QUIC 发送 HTTP 字段和数据时,QUIC 层处理大部分流管理。使用 QUIC 时,HTTP 不需要进行任何单独的多路复用,通过 QUIC 流发送的数据总是映射到特定的 HTTP 事务或整个 HTTP/3 连接上下文。
6.1 双向流
所有客户端发起的双向流都用于HTTP请求和响应。双向流确保响应可以很容易地与请求相关联。这些流称为请求流。
这意味着客户端的第一个请求发生在QUIC流0上,随后的请求发生在流4、流8等流中。为了允许这些流打开,HTTP/3服务器应该为允许的流数量和初始流控制窗口配置非零的最小值。为了避免不必要地限制并行性,一次至少应该允许100个请求流。
HTTP/3不使用服务器发起的双向流,尽管扩展可以定义这些流的用途。客户端必须将接收到服务器发起的双向流作为H3_STREAM_CREATION_ERROR类型的连接错误,除非已经协商了这样的扩展。
6.2 单向流
任意一个方向的单向流都可用于不同的用途。其目的由流类型表示,该流类型在流的开头作为可变长度整数发送。这个整数后面的数据的格式和结构由流类型决定。
单向流标头
HTTP/3连接在其生命周期的早期阶段的性能对单向流上的数据创建和交换非常敏感。过度限制流的数量或这些流的流控制窗口的终端将增加远程对等方提前达到限制并被阻止的机会。特别是,实现应该考虑远程对等方可能希望使用他们被允许使用的一些单向流来执行保留的流行为。
每个终端都需要为HTTP控制流创建至少一个单向流。QPACK需要两个额外的单向流,而其他扩展可能需要更多的流。因此,客户端和服务器端发送的传输参数必须允许对等方创建至少三个单向流。这些传输参数还应该为每个单向流提供至少1024字节的流量控制信用。
请注意,如果终端在创建关项单向流之前消耗了所有初始信用,则不需要授予额外信用来创建更多单向流。终端应该首先创建 HTTP 控制流以及强制扩展所需的单向流(例如 QPACK 编码器和解码器流),然后在其对等方允许的情况下创建其他流。
如果流标头是接收方不支持的流类型,则无法使用流的其余部分,因为语义未知。未知流类型的接收者必须中止读取流或删除传入数据而不进行进一步处理。如果读取被中止,接收者应该使用 H3_STREAM_CREATION_ERROR 错误代码或保留的错误代码。接收者不得将未知流类型视为任何类型的连接错误。
由于某些流类型会影响连接状态,因此接收者不应在读取流类型之前删除来自传入单向流的数据。
实现可以在知道对等方是否支持它们之前发送流类型。但是,可以修改现有协议组件(包括 QPACK 或其他扩展)的状态或语义的流类型,在知道对等方支持它们之前,绝对不能发送。
除非另有说明,否则发送者可以关闭或重置单向流。接收者必须容忍单向流在接收到单向流标头之前被关闭或重置。
6.2.1 控制流
控制流由0x00流类型表示。该流上的数据由HTTP/3帧组成。
每一方必须在连接开始时初始化一个控制流,并将其SETTINGS帧作为该流的第一帧发送。如果控制流的第一帧是任何其他帧类型,则必须作为H3_MISSING_SETTINGS类型的连接错误处理。每个对等方只允许一个控制流;接收到第二个声称是控制流的流必须作为H3_STREAM_CREATION_ERROR类型的连接错误处理。发送方绝对不能关闭控制流,接收方也绝对不能请求发送方关闭控制流。如果任何一个控制流在任何时候被关闭,这必须作为h3_close_critical_stream类型的连接错误处理。
由于控制流的内容用于管理其他流的行为,终端应该提供足够的流控制信用来防止对等方控制流被阻止。
使用一对单向流而不是一个双向流。这允许任何一方能够尽快发送数据。根据QUIC连接上是否有0-RTT,客户端或服务器都可以首先发送流数据。
6.2.2 push stream
服务器推送是HTTP/2中引入的一个可选特性,它允许服务器在请求发出之前发起响应。push stream由流类型0x01指示,后面是它所实现的承诺的Push ID,编码为可变长度整数。该流上的剩余数据由HTTP/3帧组成,并通过零个或多个临时HTTP响应,以及随后的单个最终 HTTP 响应来实现承诺的服务器推送。只有服务器可以推送,如果服务器接收到客户端发起的push stream,则必须将其视为 H3_STREAM_CREATION_ERROR 类型的连接错误。
push stream标头
客户端不应在读取push stream标头之前中止对push stream的读取,因为这可能导致客户端和服务器之间在已使用推送 ID 的情况下出现分歧。
每个Push ID只能在push stream标头中使用一次。如果客户端检测到一个push stream标头包含在另一个push stream标头中使用的Push ID,客户端必须将其作为H3_ID_ERROR类型的连接错误处理。
6.2.3 保留流类型
对于 N 的非负整数值,格式为 0x1f * N + 0x21 的流类型被保留以执行忽略未知类型的要求。这些流没有语义,可以在需要应用层填充时发送。它们也可以在当前没有数据传输的连接上发送。终端在接收时绝对不能认为这些流有任何意义。
以发送实现选择的任何方式选择流的有效负载和长度。当发送保留流类型时,实现可以干净地终止流或重置流。当重置流时,应该使用H3_NO_ERROR错误码或保留错误码。
如上所述,HTTP帧在QUIC流上传输。HTTP/3定义了三种流类型:控制流、请求流和push stream。本节介绍 HTTP/3 帧格式及其允许的流类型。
HTTP/3帧和流类型概述
SETTINGS帧只能作为控制流的第一帧出现,从表1(1)中可以看出。请注意,与QUIC帧不同,HTTP/3帧可以跨越多个数据包。
7.1 帧布局
所有帧都具有以下格式:
HTTP/3帧格式
每个帧包括以下字段:
类型:标识帧类型的可变长度整数。
长度:一个可变长度整数,用于描述帧有效负载的长度(以字节为单位)。
帧载荷:有效负载,其语义由 Type 字段确定。
每个帧的有效负载必须准确包含在其描述中标识的字段。在已识别字段之后包含附加字节的帧有效载荷或在已识别字段结束之前终止的帧有效载荷必须被视为 H3_FRAME_ERROR 类型的连接错误。特别是,冗余长度编码必须经过验证是自洽的。
当流完全终止时,如果流上的最后一帧被截断,则必须将其视为 H3_FRAME_ERROR 类型的连接错误。突然终止的流可以在帧中的任何点重置。
7.2 帧的定义
7.2.1 数据
DATA 帧 (type=0x00) 传送与 HTTP 请求或响应内容相关的任意可变长度字节序列。
DATA 帧必须与 HTTP 请求或响应相关联。如果在控制流上接收到 DATA 帧,接收者必须以 H3_FRAME_UNEXPECTED 类型的连接错误进行响应。
数据帧
7.2.2 标头
HEADERS 帧 (type=0x01) 用于携带使用 QPACK 编码的 HTTP 字段部分。
标头帧
HEADERS 帧只能在请求流或push stream上发送。如果在控制流上接收到 HEADERS 帧,则接收者必须以 H3_FRAME_UNEXPECTED 类型的连接错误进行响应。
7.2.3 CANCEL_PUSH
CANCEL_PUSH 帧(类型=0x03)用于在接收push stream之前请求取消服务器推送。CANCEL_PUSH 帧通过推送 ID(参见第 4.6 节)标识服务器推送,编码为可变长度整数。
当客户端发送一个CANCEL_PUSH帧时,它表示不希望接收承诺的资源。服务器应该中止发送资源,但是这样做的机制取决于相应的push stream的状态。如果服务器还没有创建push stream,它就不会创建push stream。如果push stream是打开的,服务器应该突然终止该流。如果push stream已经结束,服务器仍然可以突然终止流或不采取任何行动。
服务器发送一个CANCEL_PUSH帧来表明它不会履行先前发送的承诺。客户端不能期望相应的承诺得到实现,除非它已经接收并处理了承诺的响应。无论是否打开了push stream,当服务器确定承诺不会被履行时,它应该发送一个 CANCEL_PUSH 帧。如果流已经打开,服务器可以中止在流上发送,错误代码为 H3_REQUEST_CANCELLED。
发送 CANCEL_PUSH 帧对现有push stream的状态没有直接影响。当客户端已经接收到相应的push stream时,它不应该发送 CANCEL_PUSH 帧。在客户端发送 CANCEL_PUSH 帧后,push stream可能会到达,因为服务器可能尚未处理 CANCEL_PUSH。客户端应该中止读取流,错误代码为 H3_REQUEST_CANCELLED。
在控制流上发送 CANCEL_PUSH 帧。在控制流以外的流上接收 CANCEL_PUSH 帧必须被视为 H3_FRAME_UNEXPECTED 类型的连接错误。
CANCEL_PUSH帧
CANCEL_PUSH 帧携带一个编码为可变长度整数的Push ID。Push ID字段标识正在被取消的服务器推送。如果接收到的CANCEL_PUSH帧引用了一个大于当前连接允许的push ID,这必须作为H3_ID_ERROR类型的连接错误处理。
如果客户端收到 CANCEL_PUSH 帧,则该帧可能会标识由于重新排序而尚未被 PUSH_PROMISE 帧提及的推送 ID。如果服务器接收到一个尚未被 PUSH_PROMISE 帧提及的推送 ID 的 CANCEL_PUSH 帧,则必须将其视为 H3_ID_ERROR 类型的连接错误。
7.2.4 设置
SETTINGS 帧 (type=0x04) 传递影响终端通信方式的配置参数,例如对对等行为的偏好和约束。单独地,一个 SETTINGS 参数也可以称为"setting";每个SETTINGS参数的标识和值可以称为“设置标识”和“设置值”。
SETTINGS 帧始终适用于整个 HTTP/3 连接,而不是单个流。SETTINGS 帧必须作为每个控制流的第一帧被每个对等方发送,并且不得随后发送。如果终端在控制流上接收到第二个 SETTINGS 帧,终端必须以 H3_FRAME_UNEXPECTED 类型的连接错误响应。
SETTINGS 帧不得在控制流以外的任何流上发送。如果终端在不同的流上接收到 SETTINGS 帧,终端必须以 H3_FRAME_UNEXPECTED 类型的连接错误响应。
SETTINGS 参数未协商;它们描述了接收对等方可以使用的发送对等方的特征。但是,使用 SETTINGS 可以暗示协商:每个对等方都使用 SETTINGS 来发布一组支持的值。设置的定义将描述每个对等方如何组合这两个集合以得出将使用哪个选项的结论。SETTINGS 不提供识别选择何时生效的机制。
每个对等方可以通告相同参数的不同值。例如,客户端可能愿意使用非常大的响应字段段,而服务器则对请求大小更加谨慎。
相同的设置标识符不能在 SETTINGS 帧中出现多次。接收端可以将重复设置标识符的存在视为H3_SETTINGS_ERROR类型的连接错误。
SETTINGS帧的有效载荷由零个或多个参数组成。每个参数由一个设置标识符和一个值组成,它们都编码为QUIC可变长度整数。
设置帧
一个实现必须忽略任何带有它不理解的标识符的参数。
7.2.4.1 定义SETTINGS参数
HTTP/3 中定义了以下设置:
SETTINGS_MAX_FIELD_SECTION_SIZE (0x06):
默认值为无限制。
为 N 的非负整数值设置格式为 0x1f * N + 0x21 的标识符被保留以执行忽略未知标识符的要求。此类设置没有明确的含义。终端应该在其SETTINGS帧中包含至少一个这样的设置。终端绝对不能认为这些设置在接收时有任何意义。
由于该设置没有定义的含义,因此该设置的值可以是实现选择的任何值。
在[HTTP/2]中定义的设置标识符没有对应的HTTP/3设置也被保留。这些保留的设置绝对不能发送,并且它们的接收必须作为H3_SETTINGS_ERROR类型的连接错误处理。
其他设置可以通过 HTTP/3 的扩展来定义。
7.2.4.2 初始化
HTTP实现绝对不能发送基于当前对对等方设置的理解而无效的帧或请求。
所有设置都从初始值开始。每个终端应该使用这些初始值在对等方的SETTINGS帧到达之前发送消息,因为携带设置的数据包可能会丢失或延迟。当SETTINGS帧到达时,任何设置都将被更改为新的值。
这样就不需要在发送消息之前等待SETTINGS帧。在发送SETTINGS帧之前,终端绝对不能要求从对等方接收任何数据,必须在传输准备好发送数据后立即发送设置。
对于服务器,每个客户端设置的初始值都是默认值。
对于使用1-RTT QUIC连接的客户端,每个服务器设置的初始值都是缺省值。1-RTT项在包含设置的包被QUIC处理之前总是可用的,即使服务器立即发送 SETTINGS 也是如此。客户端不应该在发送请求之前无限期地等待 SETTINGS 到达,但他们应该处理接收到的数据报以增加在发送第一个请求之前处理 SETTINGS 的可能性。
当使用0-RTT QUIC连接时,每个服务器设置的初始值都是上一个会话中使用的值。客户端应该存储服务器在HTTP/3连接中提供的恢复信息的设置,但在某些情况下,他们可以选择不存储设置(例如,如果会话票据在SETTINGS帧之前收到)。当尝试0-RTT时,客户端必须遵守存储的设置,如果没有存储值,则使用默认值。一旦服务器提供了新的设置,客户端必须遵守这些值。
服务器可以记住它发布的设置,或存储票据中值的完整性保护副本,并在接受0-RTT数据时恢复信息。服务器使用HTTP/3设置值来决定是否接受0-RTT数据。如果服务器不能确定客户端记住的设置与它的当前设置是兼容的,它绝对不能接受0-RTT数据。如果符合这些设置的客户端不会违反服务器的当前设置,则记住的设置是兼容的。
服务器可以接受0-RTT并随后在其SETTINGS帧中提供不同的设置。如果0-RTT数据被服务器接受,它的SETTINGS帧绝对不能减少任何限制或改变任何可能被客户端与它的0-RTT数据违反的值。服务器必须包括与其默认值不同的所有设置。如果服务器接受0-RTT,但随后发送的设置与之前指定的设置不兼容,则必须将其视为 H3_SETTINGS_ERROR 类型的连接错误。如果服务器接受 0-RTT 但随后发送的 SETTINGS 帧忽略了客户端理解的设置值(除了保留的设置标识符),该设置值之前指定为具有非默认值,则必须将其视为连接错误输入 H3_SETTINGS_ERROR。
7.2.5 PUSH_PROMISE
PUSH_PROMISE 帧(类型=0x05)用于在请求流中从服务器到客户端携带承诺的请求标头部分。
PUSH_PROMISE 帧
有效载荷包括:
PUSH ID:一个可变长度的整数,用于标识服务器推送操作。Push ID用于push stream标头和CANCEL_PUSH帧。
服务器绝对不能使用比客户端提供的MAX_PUSH_ID帧大的Push ID。客户端收到推送承诺帧时,如果推送承诺帧的ID大于客户端发布的Push ID,则必须将其视为连接错误H3_ID_ERROR。
一个服务器可以在多个推送承诺帧中使用相同的Push ID。如果是这样,解压后的请求标头集必须包含相同顺序相同的字段,并且每个字段的名称和值必须完全匹配。客户端应该多次比较请求标头部分以获得承诺的资源。如果客户端收到一个已经承诺的Push ID,并且检测到不匹配,它必须响应一个H3_GENERAL_PROTOCOL_ERROR类型的连接错误。如果解压后的字段部分完全匹配,客户端应该将推送内容与每一个接收到推送承诺帧的流关联起来。
允许重复引用相同的Push ID主要是为了减少并发请求造成的重复。服务器应该避免长时间重复使用Push ID。客户端很可能使用服务器推送响应,而不保留它们以供重用。当客户端看到一个推送承诺帧使用了一个他们已经使用并删除的Push ID时,会被迫忽略这个承诺。
如果在控制流上接收到推送承诺帧,客户端必须响应一个H3_FRAME_UNEXPECTED类型的连接错误。
客户端不能发送PUSH_PROMISE帧。服务器必须将接收到的PUSH_PROMISE帧作为H3_FRAME_UNEXPECTED类型的连接错误处理。
关于整个服务器推送机制的描述,请参见4.6节。
7.2.6 关闭
GOAWAY帧(type=0x07)用于启动HTTP/3连接的任意终端的安全关闭。GOAWAY 允许终端停止接受新请求或推送,同时仍完成对先前接收到的请求和推送的处理。这将启用管理操作,例如服务器维护。GOAWAY 本身不会关闭连接。
GOAWAY帧
GOAWAY帧总是在控制流上发送。在服务器到客户端的方向上,它携带客户端发起的双向流的 QUIC 流 ID,编码为可变长度整数。客户端必须将接收到包含任何其他类型的流 ID 的 GOAWAY 帧视为 H3_ID_ERROR 类型的连接错误。
在客户端到服务器的方向上,GOAWAY帧携带一个被编码为变长整数的Push ID。
GOAWAY帧适用于整个连接,而不是特定的流。客户端必须将控制流以外的流上的GOAWAY帧作为H3_FRAME_UNEXPECTED类型的连接错误处理。
关于GOAWAY帧的更多信息请参见5.2节。
7.2.7 MAX_PUSH_ID
MAX_PUSH_ID帧(type=0x0d)被客户端用来控制服务器可以发起的服务器推送的数量。这设置了服务器可以在PUSH_PROMISE和CANCEL_PUSH帧中使用的Push ID的最大值。因此,除了由QUIC传输维持的限制外,这也限制了服务器可以发起的push stream的数量。
MAX_PUSH_ID帧总是在控制流上发送。在任何其他流上接收到MAX_PUSH_ID帧必须作为H3_FRAME_UNEXPECTED类型的连接错误处理。
服务器不能发送MAX_PUSH_ID帧。客户端必须将接收到的MAX_PUSH_ID帧作为H3_FRAME_UNEXPECTED类型的连接错误处理。
当创建HTTP/3连接时,最大Push ID是不设置的,这意味着服务器在收到MAX_PUSH_ID帧之前不能推送。客户端如果希望管理承诺的推送数量,可以在服务器完成或取消推送时通过发送MAX_PUSH_ID帧来增加最大Push ID。
MAX_PUSH_ID帧
MAX_PUSH_ID 帧携带一个可变长度整数,用于标识服务器可以使用的Push ID的最大值。MAX_PUSH_ID帧不能减少最大Push ID,接收到的MAX_PUSH_ID帧的值小于之前接收到的值必须作为H3_ID_ERROR类型的连接错误处理。
7.2.8 保留帧类型
对于N的非负整数值,格式为0x1f * N + 0x21的帧类型被保留来执行忽略未知类型的要求。这些帧没有语义,它们可以在任何允许发送帧的流上发送。这使得它们可以用于应用层填充。终端绝对不能认为这些帧在接收时有任何意义。
帧的有效负载和长度以实现选择的任何方式选择。
在没有相应 HTTP/3 帧的 HTTP/2 中使用的帧类型也被保留,这些帧类型绝对不能被发送,并且它们的接收必须作为H3_FRAME_UNEXPECTED类型的连接错误处理。
当流无法成功完成时,QUIC 允许应用程序突然终止重置该流并返回原因,这被称为“流错误”。HTTP/3 实现可以决定关闭 QUIC 流并传达错误类型。流错误不同于指示错误条件的 HTTP 状态代码。流错误表明发送方没有传输或使用完整的请求或响应,而 HTTP 状态码表明成功接收到的请求的结果。
如果需要终止整个连接,QUIC同样提供了通信原因的机制,这被称为“连接错误”。与流错误类似,HTTP/3实现可以终止一个QUIC连接,并使用8.1节中的错误代码说明原因。
尽管关闭流和连接的原因被称为“错误”,但这些操作并不一定表明连接或实现有问题。例如,如果不再需要请求的资源,则可以重置流。
在某些情况下,终端可以选择将流错误视为连接错误,关闭整个连接以响应单个流上的条件。在做出此选择之前,实现需要考虑对未处理请求的影响。
由于无需协商就可以定义新的错误码,在意外上下文中使用错误码或接收到未知错误码必须被视为等同于H3_NO_ERROR。然而,不管错误代码是什么,关闭流都可能有其他影响。
8.1 HTTP / 3错误代码
以下错误代码定义为在突然终止流、中止读取流或立即关闭 HTTP/3 连接时使用。
H3_NO_ERROR (0x0100):
H3_NO_ERROR (0x0100):
没有错误。当连接或流需要关闭但没有错误信号时,使用此方法。
H3_GENERAL_PROTOCOL_ERROR (0 x0101):
对等方违反协议要求的方式与更具体的错误代码不匹配,或者终端拒绝使用更具体的错误代码。
H3_INTERNAL_ERROR (0 x0102):
HTTP堆栈中发生了内部错误。
H3_STREAM_CREATION_ERROR (0 x0103):
终端检测到它的对等方创建了一个它会不接受的流。
H3_CLOSED_CRITICAL_STREAM (0 x0104):
HTTP/3 连接所需的流已关闭或重置。
H3_FRAME_UNEXPECTED (0 x0105):
接收到的帧在当前状态或当前流中是不允许的。
H3_FRAME_ERROR (0x0106):
接收到无法满足布局要求或大小无效的帧。
H3_EXCESSIVE_LOAD (0 x0107):
终端检测到它的对等方表现出可能产生过多负载的行为。
H3_ID_ERROR (0 x0108):
流ID或Push ID使用错误,例如超过限制、减少限制或被重用。
H3_SETTINGS_ERROR (0 x0109):
终端在SETTINGS帧的负载中检测到错误。
H3_MISSING_SETTINGS (0 x010a):
在控制流开始时没有收到SETTINGS帧。
H3_REQUEST_REJECTED (0 x010b):
服务器没有执行任何应用程序处理就拒绝了请求。
H3_REQUEST_CANCELLED (0 x010c):
请求或其响应(包括推送响应)被取消。
H3_REQUEST_INCOMPLETE (0 x010d):
客户端流在没有包含完整格式请求的情况下终止。
H3_MESSAGE_ERROR (0 x010e):
HTTP消息格式不正确,无法处理。
H3_CONNECT_ERROR (0 x010f):
为响应 CONNECT 请求而建立的 TCP 连接被重置或异常关闭。
H3_VERSION_FALLBACK (0 x0110):
请求的操作无法通过 HTTP/3 提供。对等方应通过 HTTP/1.1 重试。
为 N 的非负整数值保留格式 0x1f * N + 0x21 的错误代码,以执行将未知错误代码视为等效于 H3_NO_ERROR 的要求。实现应该从这个空间中选择一个错误代码,当他们发送 H3_NO_ERROR 时有一定的概率。
HTTP/3允许协议扩展。在本节中描述的限制范围内,协议扩展可用于提供附加服务或更改协议的任何方面。扩展仅在单个HTTP/3连接范围内有效。
这适用于本文档中定义的协议元素,这不会影响扩展HTTP的现有选项,例如定义新方法、状态代码或字段。
扩展允许使用新的帧类型(第 7.2 节)、新的设置(第 7.2.4.1 节)、新的错误代码(第 8 节)或新的单向流类型(第 6.2 节)。建立注册表是为了管理这些扩展点:帧类型(第 11.2.1 节)、设置(第 11.2.2 节)、错误代码(第 11.2.3 节)和流类型(第 11.2.4 节)。
实现必须忽略所有可扩展协议元素中未知或不支持的值。实现必须删除数据或中止对具有未知或不受支持类型的单向流的读取。这意味着这些扩展点中的任何一个都可以被扩展安全地使用,而无需事先安排或协商。然而,如果已知帧类型需要位于特定位置,例如作为控制流的第一帧的 SETTINGS 帧(参见第 6.2.1 节),未知帧类型不满足该要求,应该被视为错误。
可能改变现有协议组件语义的扩展必须在使用之前进行协商。例如,更改标头帧布局的扩展在对等方给出可接受的积极信号之前不能使用。当修改后的布局生效时,协调工作可能会很复杂。因此,为现有协议元素的新定义分配新标识符可能会更有效。
本文并不会要求使用一个特定的方法来协商扩展的使用,但它指出可以为此目的使用设置(第 7.2.4.1 节)。如果两个对等方都设置了表示愿意使用扩展的值,则可以使用扩展。如果设置用于扩展协商,则必须以这样一种方式定义默认值,即如果省略该设置,则禁用扩展。
参考及来源:https://www.rfc-editor.org/rfc/rfc9114.html
相关阅读: