We define a per-version set of behaviors for graceful vs. abrupt TCP closure handling (previously discussed in #3000):
When a TCP connection reaches the TIME-WAIT or CLOSED state, the associated endpoint MUST close its send stream.
If the connection closed gracefully, the endpoint MUST close the send stream gracefully.
Otherwise, the endpoint SHOULD close the send stream abruptly, using a mechanism appropriate to the HTTP version:
HTTP/3: reset the stream with H3_CONNECT_ERROR; see [RFC9000], Section 19.4 and [RFC9114], Section 8.1
HTTP/2: reset the stream with CONNECT_ERROR; see [RFC9113], Sections 6.4 and 7
HTTP/1.1 over TLS: TCP shutdown without a TLS closure alert; see [RFC8446], Section 6.1.
HTTP/1.1 without TLS: TCP RST
But then we also say:
The graceful and abrupt closure signals (Section 3.4) are more likely to be missing or corrupted:
Some implementations may be unable to emit the recommended abrupt closure signals, due to limitations in their TCP and TLS subsystems.
Faulty implementations may fail to send a TLS closure alert during graceful shutdown, or fail to report an error when the expected closure alert is not received. These misbehaviors are not compliant with [RFC8446], but they are common nonetheless among HTTP/1.1 implementations today.
If I get one of these signals via HTTP/1.1, how do I know what the endpoint on the other end is actually doing?
Should we:
- Leave as-is.
- Just say that HTTP/1.1 can't reliably propagate this distinction, instead of saying "here's how it works, but also it might not work".
- Maybe make FINAL_DATA the primary signal for HTTP/1.1? If you get FINAL_DATA then it's a graceful closure, regardless of if you got a TLS alert. If you don't get FINAL_DATA, then treat it as an abrupt closure, regardless of other layers.
We define a per-version set of behaviors for graceful vs. abrupt TCP closure handling (previously discussed in #3000):
But then we also say:
If I get one of these signals via HTTP/1.1, how do I know what the endpoint on the other end is actually doing?
Should we: