HTTP/1.0、それはWebの黎明期に、パケットがまだ「生」の姿で飛び交っていた時代の、ある種の「宣言」でした。RFC 1945という、今見れば古文書にも近いドキュメントに封じ込められたその仕様は、HTTP/0.9のシンプルなGETリクエストという単線的なやり取りから、現代のWebアプリケーションの礎となる、よりリッチでインタラクティブな通信への扉を開きました。今回は、このHTTP/1.0という、一見素朴ながらも極めて重要なマイルストーンに焦点を当て、パケットレベルの挙動、そしてそれを支えるトランスポート層やセキュリティ、パフォーマンス最適化の観点から、深淵を覗いていきましょう。
HTTP/1.0:ヘッダーという「情報」の誕生
HTTP/0.9は、クライアントがサーバーに「GET /path/to/resource HTTP/0.9\r\n」とだけ送り、サーバーがリソースの本体(HTMLなど)をそのまま返信する、非常にプリミティブなものでした。しかし、これではリソースの種類も分からないし、通信が成功したのかどうかもサーバーからの応答だけでは判断できません。
HTTP/1.0(RFC 1945)で導入された最も革新的な点は、「ヘッダーフィールド」の導入です。これにより、リクエストとレスポンスの両方に、メタデータとして様々な情報を含めることが可能になりました。
HTTP/1.0 リクエストのパケットレベルでの振る舞い
クライアントがHTTP/1.0のリクエストを送信する際、TCPコネクションが確立された後、以下のようなデータがパケットに載せられてサーバーへと送られます。
GET /index.html HTTP/1.0\r\n
Host: www.example.com\r\n
User-Agent: MyClient/1.0\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8\r\n
\r\n
パケットの中身を分解してみる
- `GET /index.html HTTP/1.0\r\n`: これがリクエストラインです。HTTPメソッド(GET)、リクエストURI(`/index.html`)、そしてプロトコルバージョン(`HTTP/1.0`)が明確に示されています。`\r\n`(CRLF: Carriage Return + Line Feed)は、各行の終端を示す改行コードであり、TCPパケットのペイロードとして送られます。
- `Host: www.example.com\r\n`: HTTP/1.0で必須となったヘッダーの一つです。これにより、一つのIPアドレスで複数のドメインをホストするバーチャルホスティングが可能になりました。サーバーはこの情報を見て、どのWebサイトのリソースを返すかを判断します。
- `User-Agent: MyClient/1.0\r\n`: クライアントのソフトウェア情報をサーバーに伝えます。サーバーはこれを見て、特定のブラウザに最適化されたコンテンツを提供したり、クローラーを識別したりします。
- `Accept: text/html,…`: クライアントが受け入れ可能なMIMEタイプ(Content-Type)を指定します。`q`値(quality value)で優先度を示すこともできます。これにより、サーバーはクライアントの能力に合わせて、より適切な形式のコンテンツ(HTML、XML、画像など)を選択できます。
- `\r\n`: 空行です。リクエストヘッダーの終わりと、リクエストボディ(この例ではなし)の開始を示します。
これらのヘッダーフィールドは、TCPセグメントのペイロードとして、まとめてあるいは分割されてサーバーに届けられます。パケットキャプチャツール(Wiresharkなど)で覗けば、これらのテキストデータがそのまま流れているのが確認できるでしょう。
HTTP/1.0 レスポンスのパケットレベルでの振る舞い
サーバーからのレスポンスも同様に、ヘッダーとボディで構成されます。
HTTP/1.0 200 OK\r\n
Server: Apache/2.4.41 (Ubuntu)\r\n
Date: Tue, 15 Nov 2023 10:00:00 GMT\r\n
Content-Type: text/html; charset=UTF-8\r\n
Content-Length: 1234\r\n
\r\n
Hello, HTTP/1.0!
パケットの中身を分解してみる
- `HTTP/1.0 200 OK\r\n`: ステータスラインです。プロトコルバージョン、ステータスコード(`200`)、そしてステータスメッセージ(`OK`)が含まれます。`200 OK`はリクエストが成功したことを意味し、`404 Not Found`や`500 Internal Server Error`など、様々な状態を通知します。
- `Server: Apache/2.4.41 (Ubuntu)\r\n`: サーバーソフトウェアの情報を伝えます。セキュリティの観点からは、詳細なバージョン情報を公開しない方が望ましい場合もあります。
- `Date: Tue, 15 Nov 2023 10:00:00 GMT\r\n`: サーバーの現在時刻です。キャッシュ制御やログ記録に利用されます。
- `Content-Type: text/html; charset=UTF-8\r\n`: レスポンスボディのMIMEタイプと文字エンコーディングを指定します。クライアントはこの情報に基づいて、コンテンツを正しく解釈します。
- `Content-Length: 1234\r\n`: レスポンスボディのサイズ(バイト数)を示します。HTTP/1.0では、このヘッダーがある場合、接続はボディの受信後に閉じられます。
- `\r\n`: 空行。ヘッダーの終わりです。
- `…