1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/// Reasons for closing an HTTP connection.
///
/// This enum represents the various reasons why an HTTP connection might need
/// to be closed after a request/response cycle is complete.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum CloseReason {
/// Client sent `connection: close`.
ClientConnectionClose,
/// Server sent `connection: close`.
ServerConnectionClose,
/// HTTP/1.0 response did not opt in to persistent connections.
/// See [RFC 9112 §9.3](https://www.rfc-editor.org/rfc/rfc9112#section-9.3).
Http10DefaultClose,
/// When doing expect-100 the server sent _some other response_.
///
/// For expect-100, the only options for a server response are:
///
/// * 100 continue, in which case we continue to send the body.
/// * do nothing, in which case we continue to send the body after a timeout.
/// * a 4xx or 5xx response indicating the server cannot receive the body.
Not100Continue,
/// Protocol upgrade via 101 Switching Protocols.
///
/// The connection is still open but should NOT be returned to the pool
/// because it's now using a different protocol (e.g., WebSocket, HTTP/2).
ProtocolSwitch,
/// A successful CONNECT changed the connection into a tunnel.
/// See [RFC 9112 §6.3](https://www.rfc-editor.org/rfc/rfc9112#section-6.3).
ConnectTunnel,
/// Response body is close delimited.
///
/// We do not know how much body data to receive. The socket will be closed
/// when it's done. This is HTTP/1.0 semantics.
/// See [RFC 9112 §6.3](https://www.rfc-editor.org/rfc/rfc9112#section-6.3).
CloseDelimitedBody,
}
impl CloseReason {
pub(crate) fn explain(&self) -> &'static str {
match self {
CloseReason::ClientConnectionClose => "client sent Connection: close",
CloseReason::ServerConnectionClose => "server sent Connection: close",
CloseReason::Http10DefaultClose => "server sent HTTP/1.0 without keep-alive",
CloseReason::Not100Continue => "non-100 response before body",
CloseReason::ProtocolSwitch => "protocol switched via 101",
CloseReason::ConnectTunnel => "protocol switched via CONNECT",
CloseReason::CloseDelimitedBody => "response body is close delimited",
}
}
}