5. Connection Closure (连接关闭)
一旦建立,HTTP/3连接可以在连接关闭之前用于处理许多请求和响应。连接关闭可以通过几种不同的方式发生。
5.1. Idle Connections (空闲连接)
每个QUIC端点在握手期间声明一个空闲超时 (Idle Timeout)。如果QUIC连接保持空闲(未接收到数据包)的时间超过此持续时间,对等方将假定连接已关闭。如果现有连接的空闲时间超过了QUIC握手期间协商的空闲超时,HTTP/3实现将需要为新请求打开新的HTTP/3连接,并且如果接近空闲超时,它们应该 (SHOULD) 这样做;参见 [QUIC-TRANSPORT] 的第10.1节。
HTTP客户端应该请求传输层在存在未完成的请求响应或服务器推送时保持连接打开,如 [QUIC-TRANSPORT] 的第10.1.2节所述。如果客户端不期望来自服务器的响应,允许空闲连接超时比花费精力维护可能不需要的连接更可取。网关可以 (MAY) 在预期需要时维护连接,而不是承担与服务器建立连接的延迟成本。服务器不应该 (SHOULD NOT) 主动保持连接打开。
5.2. Connection Shutdown (连接关闭)
即使连接不空闲,任一端点也可以决定停止使用连接并启动优雅的连接关闭 (Graceful Connection Close)。端点通过发送GOAWAY帧来启动HTTP/3连接的优雅关闭。GOAWAY帧包含一个标识符,该标识符向接收方指示在此连接中已处理或可能处理的请求或推送的范围。服务器发送客户端发起的双向流ID;客户端发送推送ID。具有指示标识符或更大标识符的请求或推送将被GOAWAY的发送方拒绝(第4.1.1节)。如果没有处理请求或推送,则此标识符可以 (MAY) 为零。
GOAWAY帧中的信息使客户端和服务器能够就在HTTP/3连接关闭之前接受了哪些请求或推送达成一致。在发送GOAWAY帧时,端点应该 (SHOULD) 显式取消(参见第4.1.1节和第7.2.3节)任何标识符大于或等于指示标识符的请求或推送,以便清理受影响流的传输状态。随着更多请求或推送到达,端点应该 (SHOULD) 继续这样做。
端点在收到来自对等方的GOAWAY帧后,禁止 (MUST NOT) 在连接上发起新请求或承诺新推送。客户端可以 (MAY) 建立新连接以发送其他请求。
某些请求或推送可能已经在传输中:
-
在收到GOAWAY帧后,如果客户端已经发送了流ID大于或等于GOAWAY帧中包含的标识符的请求,则这些请求将不会被处理。客户端可以在不同的HTTP连接上安全地重试未处理的请求。无法重试请求的客户端将丢失服务器关闭连接时正在传输的所有请求。
流ID小于服务器GOAWAY帧中的流ID的请求可能已被处理;在收到响应、流被单独重置、收到另一个流ID低于相关请求的GOAWAY或连接终止之前,无法知道它们的状态。
如果这些请求未被处理,服务器可以 (MAY) 拒绝指示ID以下流上的单个请求。
-
如果服务器在承诺了推送ID大于或等于GOAWAY帧中包含的标识符的推送后收到GOAWAY帧,则这些推送将不会被接受。
当提前知道连接关闭时,服务器应该 (SHOULD) 发送GOAWAY帧,即使提前通知很少,以便远程对等方可以知道请求是否已被部分处理。例如,如果HTTP客户端在服务器关闭QUIC连接的同时发送POST,则如果服务器不发送GOAWAY帧来指示它可能对哪些流采取了操作,客户端就无法知道服务器是否开始处理该POST请求。
端点可以 (MAY) 发送多个指示不同标识符的GOAWAY帧,但每个帧中的标识符禁止 (MUST NOT) 大于任何先前帧中的标识符,因为客户端可能已经在另一个HTTP连接上重试了未处理的请求。接收到包含大于先前接收的标识符的GOAWAY必须 (MUST) 被视为类型为H3_ID_ERROR的连接错误 (Connection Error)。
尝试优雅关闭连接的端点可以发送一个值设置为最大可能值的GOAWAY帧(对于服务器为2^62-4,对于客户端为2^62-1)。这确保对等方停止创建新请求或推送。在允许任何传输中的请求或推送到达的时间后,端点可以发送另一个GOAWAY帧,指示在连接结束之前它可能接受哪些请求或推送。这确保可以干净地关闭连接而不会丢失请求。
客户端在其发送的GOAWAY中为推送ID字段选择的值具有更大的灵活性。值2^62-1表示服务器可以继续履行已经承诺的推送。较小的值表示客户端将拒绝推送ID大于或等于此值的推送。与服务器一样,客户端可以 (MAY) 发送后续的GOAWAY帧,只要指定的推送ID不大于任何先前发送的值。
即使GOAWAY指示给定的请求或推送在收到时不会被处理或接受,底层传输资源仍然存在。发起这些请求的端点可以取消它们以清理传输状态。
一旦所有接受的请求和推送都已处理,端点可以允许连接变为空闲,或者它可以 (MAY) 立即关闭连接。完成优雅关闭的端点在关闭连接时应该 (SHOULD) 使用H3_NO_ERROR错误码。
如果客户端已使用请求消耗了所有可用的双向流ID,则服务器无需发送GOAWAY帧,因为客户端无法发出进一步的请求。
5.3. Immediate Application Closure (立即应用程序关闭)
HTTP/3实现可以随时立即关闭QUIC连接。这会导致向对等方发送QUIC CONNECTION_CLOSE帧,指示应用层已终止连接。此帧中的应用错误码向对等方指示关闭连接的原因。有关在HTTP/3中关闭连接时可以使用的错误码,请参见第8节。
在关闭连接之前,可以 (MAY) 发送GOAWAY帧以允许客户端重试某些请求。将GOAWAY帧包含在与QUIC CONNECTION_CLOSE帧相同的数据包中可以提高客户端接收该帧的机会。
如果有未明确关闭的打开流,则当连接关闭时它们会隐式关闭;参见 [QUIC-TRANSPORT] 的第10.2节。
5.4. Transport Closure (传输关闭)
由于各种原因,QUIC传输可能向应用层指示连接已终止。这可能是由于对等方的显式关闭、传输级错误或中断连接的网络拓扑变化。
如果连接在没有GOAWAY帧的情况下终止,客户端必须假定任何已发送的请求(无论是完整请求还是部分请求)可能已被处理。