HTTPのバージョンについて、現在のまとめ

## はじめに
HTTPのバージョンと仕様について、個々最近の動きについて整理しておこうかと思います。

HTTPには幾つかのバージョンが有り、現在HTTP/1.1とHTTP/2が広く利用されており、HTTP/3も徐々に使われだしています。

バージョンが異なっていても、クライアントからHTTPリクエストを送り、サーバがHTTPレスポンスを返すのは変わりません。HTTPメッセージをどのようなフォーマットで送るかはバージョンによって異なりますが、HTTPメッセージが持つ意味は変わりません。

意味(セマンティクス)とは、GETリクエストやPOSTリクエスト、ステータスコード、ヘッダがどういった意味を持つかということです。

バージョンと、セマンティクスの歴史的遷移は下記のとおりです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32425/e64910a8-3857-1782-aeb7-5a1007ba8d08.png)


## HTTP/1.1とセマンティクス
HTTPは最初0.9から始まり、HTTP/1.0、HTTP/1.1と進んできました。

HTTP/1.1の最初の仕様は、1997年に公開された「[RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1](https://tools.ietf.org/html/rfc2068)」でした。HTTP/1.0と同じように、TCP上でただの文字列としてHTTPメッセージをやり取りするものです。

```
$ curl -v http://example.com
* Connected to example.com (93.184.216.34) port 80 (#0)
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/7.58.0
> Accept: */*
> 
< HTTP/1.1 200 OK
< Age: 505206
< Cache-Control: max-age=604800
< Content-Type: text/html; charset=UTF-8
...
```

その後、HTTP/1.1の改訂版として、曖昧だった部分などを修正したRFC7230~RFC7235が2014年に公開されています。

- [RFC7230 「Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing」](https://tools.ietf.org/html/rfc7230)
- [RFC7231 「Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content」](https://tools.ietf.org/html/rfc7231)
- [RFC7232 「Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests」](https://tools.ietf.org/html/rfc7232)
- [RFC7233 「Hypertext Transfer Protocol (HTTP/1.1): Range Requests」](https://tools.ietf.org/html/rfc7233)
- [RFC7234 「Hypertext Transfer Protocol (HTTP/1.1): Caching」](https://tools.ietf.org/html/rfc7234)
- [RFC7235 「Hypertext Transfer Protocol (HTTP/1.1): Authentication」](https://tools.ietf.org/html/rfc7235)

この段階ではまだ、`HTTPセマンティクス`と`メッセージフォーマット`は合わせて標準化されていました。

### 現在
その後、メッセージのフォーマットが異なるHTTP/2, HTTP/3の登場も踏まえて、仕様の整理作業が行われています。各ドキュメントは下記のとおりです。

- RFC9110 [HTTP Semantics](https://www.ietf.org/archive/id/draft-ietf-httpbis-semantics-14.html)
- RFC9111 [HTTP Caching](https://www.ietf.org/archive/id/draft-ietf-httpbis-cache-14.html)
- RFC9112 [HTTP/1.1](https://www.ietf.org/archive/id/draft-ietf-httpbis-messaging-14.html)

こうすることで、HTTP/2やHTTP/3の仕様からはセマンティクスの仕様を参照することができます。

RFC 9110 HTTP Semanticsの変更点については、「[HTTPセマンティクス仕様の改訂版(RFC9110) まとめ](https://asnokaze.hatenablog.com/entry/2021/06/07/010727)」を参照ください。

## HTTP/2
HTTPメッセージをより効率よくやり取りするために、HTTP/2という仕様が2015年頃に標準化されています。仕様は [RFC 7540「Hypertext Transfer Protocol Version 2 (HTTP/2)」](https://tools.ietf.org/html/rfc7540) から見ることができます。

HTTP/2は、Googleが開発していたSPDYというプロトコル元にしており、一つのTCPコネクション上で並列的にHTTPリクエストとHTTPレスポンスをやりとり出来るようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32425/3b7a5d2a-98a6-0210-149b-ae523483f0d6.png)


並列的にHTTPメッセージをやりとりするために、`フレーム`と呼ばれるメッセージと、仮想的な通信単位である`ストリーム`と呼ばれる概念を導入しています。HTTP/2の仕様では、このフレームとストリームを使ってどうHTTPメッセージをやり取りするかが定義されています。

細かくは解説しませんが、下記のような機能も含まれています
- ヘッダ圧縮
- 優先度制御
- サーバプッシュ
- ウィンドウ制御
- エラーハンドリング

合わせて、HTTPヘッダを圧縮する[RFC 7541 「HPACK: Header Compression for HTTP/2」](https://tools.ietf.org/html/rfc7540)を使用しています。HPACKでは辞書データであるテーブルと、ハフマン符号化を用いてヘッダのデータ量を削減しています。

### 現在
現在、このHTTP/2も改定作業が開始されています。大きな機能改善が入る想定ではなく、主に仕様上のバグ修正や、優先度制御まわりの文書の修正などです。

『[HTTP/2の改定版仕様(RFC9113)の変更点について](https://asnokaze.hatenablog.com/entry/2021/10/04/003623)』に変更点など詳しく書いてあります。

## HTTP/3
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32425/0998ee3a-67f8-6749-ebd4-1760f217c2f5.png)

HTTP/2よりさらにパフォーマンスを改善するために、HTTP/3と呼ばれる仕様が現在標準化中です。まだ、RFCは出ていませんが、大詰めと言われています。

現在の仕様は下記からアクセスできます
- [Hypertext Transfer Protocol Version 3 (HTTP/3)](https://tools.ietf.org/html/draft-ietf-quic-http-33)
- [QPACK: Header Compression for HTTP/3](https://tools.ietf.org/html/draft-ietf-quic-qpack-20)

HTTP/3は、下位層に[QUIC](https://tools.ietf.org/html/draft-ietf-quic-transport-34)と呼ばれるトランスポートプロトコルを利用するのが大きな特徴です。

QUICもHTTP/3と合わせてIETFで標準化されています。QUICの詳細については割愛しますが、UDP上で通信の暗号化と通信の信頼性を提供するトランスポートプロトコルです。パケットロスが起こったとしても受信できたパケットから処理可能であれば処理を進められるように設計されています。また、`ストリーム`とよばれる通信単位を持っています。

HTTP/3では、このQUICを効率良く利用できるように設計されています。QUICレイヤではパケットが入れ替わっても処理が進められますが、HTTPレイヤでそれを処理できないのであれば仕方ありません。

例えばHPACKをそのまま利用しようとすると、HPACKは送った順番でしか処理できなかったため、パケットロスが発生するとリカバリするため処理を進めることができませんでした。QPACKではパケットロスがあったとしても、届いた後続のパケットが処理できれば処理を進めます。

このような工夫が入ってるほか、HTP/2のときは自前でやってたストリーム管理周りの仕組みが、QUICが提供するストリームを利用する形に変わっています。

その他、優先度制御がオプションとなったりとHTTP/2のデプロイから得られた知見が活用されています。


## その他
今回は、HTTPのバージョンとセマンティクス仕様について説明しました。

しかし今回紹介できなかったHTTP関連の仕様は多くあります。例えばステータスコードを新しく定義するものや、HTTP/2機能改善に関するもの、WebSocketなどの仕様などなどです。

## 宣伝
HTTP/3の解説を書いた (2020/06/01)
https://asnokaze.hatenablog.com/entry/2020/06/01/005625

よろしくおねがいします。頑張って、アップデートします。。。