TL;DR
1 つの TCP 接続で、複数の HTTP リクエストとレスポンスをやり取りする仕組み。HTTP/1.1 では、持続的接続が既定の動作になっている。
なぜ必要か
HTTP/1.0 では、1 つの TCP 接続で 1 つのリクエストと 1 つのレスポンスしか処理しなかった。TCP はデータを送る前にハンドシェイクで接続を確立するので、ページの画像や CSS を取りに行くたびに接続を張ると、性能が落ちる。持続的接続では接続を再利用するので、リソースごとに接続を確立しなくてよい。
仕組み
RFC 9112 では、受け手は直近に受け取ったメッセージを見て、接続を続けるかを次の順で決める。
- Connection ヘッダに
closeがあれば、そのレスポンスの後で接続を閉じる - HTTP/1.1 以降なら、接続を続ける
- HTTP/1.0 で
keep-aliveがあれば(条件を満たす場合)、接続を続ける - どれでもなければ、そのレスポンスの後で接続を閉じる
接続を使い回すには、メッセージの終わりが分かる必要がある。そのため、すべてのメッセージが自分の長さを示していなければならない。クライアントは、レスポンスの本文を最後まで読んでから次のリクエストに接続を使う。
持続的接続の上では、レスポンスを待たずに複数のリクエストを送るパイプライン化もできる。ただし、サーバはリクエストを受けた順にレスポンスを返す必要がある。
注意点
close を送った、または受け取った側は、その接続で新しいリクエストを送ってはいけない。また、接続を急に閉じると TCP のリセットで未読のレスポンスが失われることがあるので、サーバは片方向ずつ段階的に接続を閉じる。