学習目標
本講を終えると、以下を達成できるようになります。
- HTTP リクエスト/レスポンスメッセージの構造(リクエスト行・ステータス行・ヘッダ行・空行・本文)を図示できる
- GET / POST / PUT / DELETE / HEAD / OPTIONS の意味的な違いを説明できる
- ステータスコードを 1xx〜5xx に分類でき、200 / 301 / 302 / 304 / 400 / 401 / 403 / 404 / 500 / 502 / 503 などの代表例の意味を述べられる
- Host・User-Agent・Content-Type・Content-Length・Cookie・Cache-Control・Authorization といった主要ヘッダの役割を説明できる
- HTTP がステートレスであることの意味と、Cookie / セッションがそれを補う仕組みを説明できる
- HTTP/1.0 と HTTP/1.1 のパーシステント接続の違い、およびパイプライン処理の限界を述べられる
- HTTP/2 のバイナリフレーミング・ストリーム多重化・ヘッダ圧縮(HPACK)・サーバプッシュの概念を説明できる
- HOL(Head-of-Line) ブロッキング問題と、それが HTTP/3 (QUIC) を生む動機につながったことを説明できる
このレッスンの目次
HTTP の役割を再確認する
HTTP(HyperText Transfer Protocol) は、Web ブラウザ(クライアント) と Web サーバの間で リソース(HTML / 画像 / JSON など) をやり取りするためのアプリケーション層プロトコルです。トランスポート層には基本的に TCP(ポート 80) を使い、HTTPS の場合は TLS の上で動きます(TLS は通常 TCP ポート 443)。クライアントが要求(リクエスト)を出し、サーバが応答(レスポンス)を返す という 要求応答(request-response) 型のやり取りで進みます。
POINT
HTTP の本質は 「テキストベースの命令(リクエスト)に、テキストベースの回答(レスポンス)を返す」 という単純な約束。HTTP/1.x まではメッセージはほぼ人間が読める ASCII 文字列で、HTTP/2 以降はバイナリフレームになります。
クライアント-サーバ型の相互作用
図の見方:HTTP は常にクライアントが先に話しかける(プル型)。サーバから能動的に「ねえねえ」とは話しかけません(HTTP/2 のサーバプッシュは例外的機能で、後述)。
RFC で定義された世界中の標準
HTTP の仕様は IETF の RFC(Request for Comments) として公開されています。主要な版だけを挙げると、HTTP/1.1 は RFC 9110(Semantics)・RFC 9112(HTTP/1.1)、HTTP/2 は RFC 9113、HTTP/3 は RFC 9114 で標準化されています。誰もが同じ仕様を読める からこそ、世界中のブラウザとサーバが相互運用できます。
つながる知識: 「ポート 80 / 443 で Listen するサーバ」「Socket API で TCP に書き込む」という見方は、基礎 第3回 のトランスポート層の話と直結しています。HTTP は単独で動くのではなく、必ず下層プロトコル(TCP) の上に成り立つ点を意識してください。
HTTP メッセージの構造
HTTP/1.x のメッセージは テキスト行 で構成されます。リクエストもレスポンスも、おおよそ 「先頭の1行 + 複数のヘッダ行 + 空行 + 本文」 という4ブロックの構造を持ちます。先頭1行だけが種類(リクエスト行 or ステータス行) で異なり、それ以外は共通の作りです。
POINT
HTTP/1.x メッセージのフォーマット:
[先頭行(リクエスト行 / ステータス行)] CRLF
[ヘッダ行 1] CRLF
[ヘッダ行 2] CRLF
…
[空行(CRLF だけ)]
[本文(あれば)]
※ CRLF = \r\n。空行が「ヘッダ終わり・本文開始」の区切りとなります。
リクエストとレスポンスを並べて見る
HTTP リクエスト(クライアント→サーバ)
リクエストは先頭が リクエスト行:メソッド SP URI SP HTTP-バージョン CRLF。
GET /docs/index.html HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 14.4) Firefox/124.0
Accept: text/html,application/xhtml+xml
Accept-Language: ja,en;q=0.8
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: session=abc123; theme=dark
(本文なし。GET なので空)
- リクエスト行:GET がメソッド、/docs/index.html が要求するリソースのパス、HTTP/1.1 がバージョン
- ヘッダ行:フィールド名: 値 の形。HTTP/1.1 では Host ヘッダが必須(同一 IP に複数のサイトが同居する仮想ホストで宛先サイトを識別するため)
- 空行:ヘッダの終わりを示す
- 本文:GET / HEAD では通常空。POST / PUT で送信データを格納
HTTP レスポンス(サーバ→クライアント)
レスポンスは先頭が ステータス行:HTTP-バージョン SP ステータスコード SP 理由句 CRLF。
HTTP/1.1 200 OK
Date: Sun, 26 Apr 2026 03:21:08 GMT
Server: nginx/1.24.0
Content-Type: text/html; charset=UTF-8
Content-Length: 1532
Cache-Control: max-age=600
Set-Cookie: session=abc123; Path=/; HttpOnly
Connection: keep-alive
<!DOCTYPE html>
<html>
<head><title>Example</title></head>
<body> … </body>
</html>
- ステータス行:200 は数値のステータスコード、OK は人間向けの理由句(reason phrase)
- ヘッダ行:本文の種類(Content-Type) や長さ(Content-Length) など
- 本文:HTML やバイナリデータ。長さは Content-Length で指定するか、Transfer-Encoding: chunked で分割
並べて比較
図の見方:リクエストとレスポンスは 先頭行が違うだけ で、ヘッダ・空行・本文という構造は共通。空行が必ずヘッダの終わりを示す境界線になっている。
もっと詳しく:CRLF と HTTP の歴史的経緯
HTTP/1.x のメッセージ区切りに CRLF(\r\n) を使うのは、ARPANET 時代から続くインターネットテキストプロトコルの慣習です(SMTP・FTP も同様)。LF(\n) のみではなく CR+LF にしている理由は、Unix・Windows・Mac で改行コードが違っていた時代の互換性確保のため。HTTP/2 以降はテキストではなくバイナリフレームになったため、CRLF の概念は消えています。
主要メソッド:GET / POST / PUT / DELETE / HEAD / OPTIONS
HTTP リクエストの先頭にある メソッド(method) は、サーバに対して 「何をしてほしいのか」 を示す動詞です。HTTP/1.1 で定義された主要メソッドは以下の通り。意味的な性質(冪等性・安全性) も合わせて理解することが重要です。
POINT
用語の整理:
安全(safe) = サーバの状態を変えない(GET / HEAD / OPTIONS)
冪等(idempotent) = 何度実行しても結果が同じ(GET / HEAD / OPTIONS / PUT / DELETE)
非冪等 = 何度実行すると結果が変わりうる(POST)
| メソッド | 意味 | 安全 | 冪等 | 本文 |
| GET | リソースを取得する。最も基本 | ○ | ○ | 原則なし |
| POST | サーバにデータを送って処理させる(フォーム投稿・新規作成) | × | × | あり |
| PUT | 指定 URI のリソースを送ったデータで 置き換える(なければ作る) | × | ○ | あり |
| DELETE | 指定 URI のリソースを削除する | × | ○ | 原則なし |
| HEAD | GET と同じだが ヘッダだけ を返す(本文なし)。サイズ確認や生存確認用 | ○ | ○ | なし |
| OPTIONS | そのリソースで利用可能なメソッドを問い合わせる(CORS プリフライトでも使用) | ○ | ○ | 原則なし |
PUT と POST の違い:同じ「データを送る」でも、PUT は 「この URI をこの内容で置き換えて」 という指示なので何度送っても結果は同じ(冪等)。POST は 「処理してほしい」 なので、たとえばコメント投稿なら何度送ると重複コメントが増える(非冪等)。
Q. ブラウザの「リロード」で同じ POST を再送信すると確認ダイアログが出ます。なぜ GET ではダイアログが出ないのに POST だけ出るのでしょう?
GET は 安全かつ冪等 なので、何度送ってもサーバの状態に影響しません(同じページを取り直すだけ)。一方 POST は 非冪等 なので、リロードで再送すると「商品を二重購入」「コメント二重投稿」のような事故が起きます。だからブラウザはユーザに「本当に再送する?」と確認を求めるわけです。HTTP メソッドの設計思想がブラウザの UI にまで反映されている、わかりやすい例です。
考えてみよう: RESTful API の設計では、「GET /users/123 = 取得」「PUT /users/123 = 更新」「DELETE /users/123 = 削除」「POST /users = 新規作成」のようにメソッドと URI を組み合わせて操作を表現します。冪等性を意識して設計することで、ネットワーク障害時の 自動再送 が安全に実装できるという実利があります。
ステータスコードの分類と代表例
レスポンスの 3桁の数値 がステータスコードです。先頭の桁で大分類が決まり、5つのカテゴリに分かれます。HTTP/1.1 (RFC 9110) で標準化されています。
図の見方:ステータスコードは「100の位」だけでもおおよその意味がわかる。2xx なら成功、3xx ならリダイレクト、4xx ならクライアントの責任、5xx ならサーバの責任。エラー対応の最初の手がかりになる。
頻出コードの細かい違い
301 vs 302
どちらも「Location ヘッダで指定された URL に移動して」という指示。
301 Moved Permanently:恒久的な移動。検索エンジンは旧 URL を捨てて新 URL に置き換える。ブラウザもキャッシュして次回から直接新 URL にアクセス。
302 Found:一時的な移動。元の URL は将来また有効になり得る。検索エンジンは旧 URL を維持。
401 vs 403
401 Unauthorized:そもそも 認証していない(誰なのか分からない)。WWW-Authenticate ヘッダで認証方式を提示することが多い。
403 Forbidden:認証は済んだが 権限がない。ログインしているがその管理画面は見られない、というケース。
小問:あるサイトの URL を変更した。新しい URL に永続的に移動したことを検索エンジンに伝えたい。どのステータスコードを返すべき?
正解: B。301 は「恒久的にこっちへ引っ越した」ことを示し、検索エンジンが新 URL でインデックスを書き換えてくれる。302 だと「一時的だから旧 URL も残しておいて」となり、SEO 上の評価が新 URL に移らない。404 は「そのリソースは存在しない」で、移動の意味は伝わらない。
考えてみよう: 304 Not Modified は本文を返さないため通信量を大幅に節約できます。クライアントは If-Modified-Since や If-None-Match ヘッダで「自分はこの版を持っている」と伝え、サーバは変わっていなければ 304 だけ返します。キャッシュの整合性をヘッダで管理 するのが HTTP の設計の妙です。
ステートレスである意味と Cookie / セッション
HTTP は設計上 ステートレス(stateless) なプロトコルです。つまりサーバは リクエスト1件ずつを独立して処理 し、HTTP そのものは過去の同じクライアントのリクエストを 覚えていない。一方、実際の Web ではログイン状態が維持されます。これは HTTP が状態を覚えているからではなく、Cookie という仕組みで小さな目印を毎回送り返させ、アプリケーション側で状態を後付けしているからです。
POINT
ステートレスの利点 = サーバ側の状態管理が不要で スケールしやすい(複数台のサーバに均等に振っても矛盾しない)。
欠点 = HTTP 単体ではユーザを継続的に識別できない → Cookie + サーバ側セッション で「毎回、同じ人だと分かる」ように補う。
現実とのつながり: 「ログイン状態を維持できない」とは、HTTP だけでは維持できない という意味です。ブラウザはログイン後に受け取った Cookie を保存し、次のリクエストから自動で付けて送ります。サーバはその Cookie のセッション ID を見て、「このリクエストはさっきログインしたユーザから来た」と判断します。つまり、Cookie はステートレスな HTTP の上にログイン状態を無理やり実現するための目印です。
Q. 「HTTP がステートレスだと何が困るのか?」を、具体的なユースケースを2つ以上挙げて答えてみよう。
- HTTPだけではログイン状態が維持できない:ログインフォームで認証成功しても、次のページ要求だけを見るとサーバは「あなた誰?」となる。現実には Cookie を一緒に送ることで同じユーザだと判断している
- ショッピングカートが作れない:カートに入れた商品が、次のリクエストでは消えてしまう
- 多段のフォームが組めない:ステップ1で入力した内容を、ステップ2のサーバが知らない
- ユーザ別の設定(言語・テーマ)が保てない:毎回設定し直すことになる
これらを解決するために、サーバが Set-Cookie ヘッダ でクライアントに小さなテキスト(セッション ID など) を持たせ、次回以降クライアントが Cookie ヘッダ でそれを送り返すという仕組みが導入されました。
Cookie の流れ
ステップ1. 最初のログイン要求では、まだログイン用Cookieはありません。HTTPだけを見ると、これはただの1回の POST /login です。
ステップ2. 認証に成功すると、サーバから Set-Cookie ヘッダ付きの応答が返り、クライアント側のブラウザがセッションIDを保存します。同時にサーバ側では abc123 → alice のような対応をセッション表に持ちます。
ステップ3. 2回目以降、ブラウザは対象サイトへのリクエストに保存済みの Cookie を自動で同封します。ユーザが毎回入力しているわけではありません。
ステップ4. サーバはCookieの値をセッション表と照合し、「このリクエストはaliceから来た」と復元します。HTTP自体が記憶しているのではなく、Cookieとアプリ側の表で状態を後付けしています。
1 / 4
図の見方:HTTP 自体はステートレスのまま、Cookie に「セッション ID」という小さな目印を持たせることで、サーバ側のセッションテーブルと突き合わせて状態を復元する。ログイン状態は HTTP が覚えているのではなく、Cookie を毎回持参させることでアプリケーション側が後付けで実現している。
Cookie の主な属性
- Secure:HTTPS でのみ送信(平文の HTTP 上では送らない)
- HttpOnly:JavaScript からアクセス不可(XSS でセッション ID が盗まれにくくなる)
- SameSite:他サイトからのリクエストに同梱するかを制御(CSRF 対策。Strict / Lax / None)
- Domain / Path:Cookie を送る対象のスコープを限定
- Max-Age / Expires:有効期限
つながる知識: 「JWT(JSON Web Token) を用いた認証」「OAuth 2.0 のアクセストークン」なども、結局は 「ステートレス HTTP の上で何らかの認証情報を毎回運ぶ」 という発想の延長です。Cookie ベースか Authorization ヘッダベースか、というのは実装の選択。詳細は 第36回 アプリ層プロトコルのセキュア化 や 発展 編で扱います。
パーシステント接続:HTTP/1.0 と HTTP/1.1 の差
Web ページは通常、HTML 1つだけでなく、画像・CSS・JS など 多数のオブジェクト から構成されます。これらをどう運ぶかが HTTP/1.0 と HTTP/1.1 の大きな違いです。
ステップで見る:通信路を毎回作るか、使い回すか
ステップ1. Webページは HTML だけではなく、CSS・画像・JavaScript など複数の部品でできている。部品ごとに HTTP の要求と応答が必要になる。
ステップ2. HTTP/1.0 では、HTML を取るために通信路を作り、要求を送り、応答を受け取ったら閉じる。
ステップ3. 次の部品を取るときも、また通信路を作る。オブジェクト数が多いほど、往復確認の待ち時間が積み重なる。
ステップ4. HTTP/1.1 では最初に作った通信路を開いたままにし、次の要求にも使えるようにする。
ステップ5. HTML や CSS を同じ通信路で続けて取りに行けるため、通信路を作る待ち時間は最初の1回だけになる。
1 / 5
図の見方:ボタンで進めると、HTTP/1.0 の「部品ごとに通信路を作る」流れと、HTTP/1.1 の「1本の通信路を使い回す」流れを順番に比較できる。
HTTP/1.0:ノンパーシステント
HTTP/1.0 は 1リクエスト=1 TCP コネクション が基本です。ここでいう TCP コネクションとは、HTTP のリクエストを流す前にブラウザとサーバの間で作る 通信路 のことです。通信路を作るたびに「送ってよい?」「よい」「では送る」のような往復確認(後で学ぶ 3-way ハンドシェイク)が必要になるため、オブジェクトごとに 1往復ぶんの待ち時間 が積み重なります。この往復時間を RTT と呼びます。
- HTML を取るために通信路を作る → リクエスト → レスポンス → クローズ
- 画像 1 を取るために再び通信路を作る → … → クローズ
- 画像 2、CSS、JS … と同じことを繰り返す
オブジェクトが 50 個あれば、通信路を作る確認だけで 50 回ぶん発生します。仮に1往復が 50 ms なら、それだけで 2.5 秒の待ち時間になります。
HTTP/1.1:パーシステント + パイプライン
HTTP/1.1 は パーシステント(継続型)接続 を 標準で有効 にしました。1本の TCP コネクションで複数のリクエスト・レスポンスを連続して送れます。Connection: keep-alive ヘッダ(または HTTP/1.1 のデフォルト動作) でこの挙動を表します。
- TCP の通信路を作るコストは最初の1回だけ
- サーバ側にはアイドルなコネクションを一定時間保持するためのタイマが必要(オーバーヘッドだが利得が大きい)
- さらに パイプライン処理(pipelining):応答を待たずに複数のリクエストを連続送信できる
ただしパイプラインには弱点があります:応答は 送った順番 で返ってこないと困るため、サーバは順序を守って返す必要があり、先頭のリクエスト処理が遅いと後続の応答も詰まる(後述の HOL ブロッキング)。実際にはブラウザはパイプラインを 無効化 していることが多く、代わりに 1サイトあたり6本前後の TCP コネクションを並列に張る という回避策を取っていました。
HTTP/2:多重化
HTTP/2 は別のアプローチで根本解決します:1本の TCP コネクションの中で論理的な「ストリーム」を複数同時に流す(多重化)。次のセクションで詳述します。
考えてみよう: HTTP/1.0 → 1.1 の進化は、「通信路の使い回し」によって往復確認の回数を減らす工夫でした。ネットワークでは、どれだけ高速な回線でも相手との距離に応じた往復待ち時間が残ります。そのため 「往復回数を減らす」 はネットワーク高速化の重要な考え方です。HTTP/2・HTTP/3 もこの哲学の延長線上にあります。
HTTP/2 の改善点
HTTP/2(RFC 9113、当初 RFC 7540) は セマンティクス(メソッド・ステータス・ヘッダの意味) は HTTP/1.1 と同じ まま、下層のフレーミングと多重化を全面的に作り変えた 版です。Google の SPDY を出発点に IETF で標準化されました。
POINT
HTTP/2 の4つの柱:
① バイナリフレーミング(テキスト → バイナリ)
② ストリームの多重化(1 TCP に複数論理ストリーム)
③ ヘッダ圧縮(HPACK)(冗長ヘッダの圧縮)
④ サーバプッシュ(クライアントが要求する前にサーバから関連リソースを送る)
① バイナリフレーミング
HTTP/1.x のテキストパーサは「行末を探す」「空行を探す」といった処理が複雑でした。HTTP/2 は 固定長ヘッダ + ペイロード の フレーム 単位に再設計し、パーサがシンプル・高速になりました。フレームの種類は HEADERS / DATA / SETTINGS / PING / GOAWAY / WINDOW_UPDATE などがあります。
② ストリームの多重化(multiplexing)
1 本の TCP コネクションの中に 論理的な「ストリーム」 を複数走らせ、それぞれを並行して進めます。各ストリームには ID が付き、フレームには「どのストリームに属するか」が書かれているので、受信側が再組立てできます。
図の見方:色は同じオブジェクトを表す。HTML は緑、img1 は黄、img2 は紫、CSS は青。左の HTTP/1.1 はオブジェクトを1つずつ直列で送るため、先頭のオブジェクトの応答完了を待たないと次が始められない。右の HTTP/2 は1つの TCP の中で複数のストリームのフレームを 細切れに混ぜて送る ため、全リクエストがほぼ同時並行で進む。
③ ヘッダ圧縮 ─ HPACK
HTTP/1.x では、毎リクエストごとに同じような User-Agent / Accept / Cookie を平文で繰り返し送っていました。これは特に多数の小さなリクエストでは無視できないオーバーヘッドです。HTTP/2 は HPACK(RFC 7541) という専用の圧縮アルゴリズムを導入しました。
もっと詳しく:HPACK の概要
- 静的テーブル:よく使われるヘッダ(:method GET、:status 200、accept-encoding gzip, deflate など) を番号で参照できるよう RFC で固定的に定義
- 動的テーブル:そのコネクション内で過去に送ったヘッダを覚えておき、次回からは テーブル参照番号 1 つ で済ませる
- ハフマン符号化:文字列値もハフマン符号で短縮
結果として、HTTP/2 のヘッダは数バイト〜数十バイトに収まることが多く、ネットワーク負荷とレイテンシが大きく減少します。
なお、HPACK は 状態を持つ(動的テーブル) ためにヘッダを順序通り処理する必要があり、これが HOL ブロッキングの一因にもなります。HTTP/3 では順不同でも安全な QPACK(RFC 9204) に置き換えられています。
④ サーバプッシュ(server push)
サーバが「どうせクライアントは次にこれを要求するだろう」と予測して、要求を待たずに関連リソースを 先回りで送る 機能です。たとえば HTML の応答と一緒に、その HTML が参照する CSS や画像をプッシュしておけば、クライアントが <link rel="stylesheet"> を解析してから改めて要求する RTT を節約できます。
実運用では キャッシュされていることに気づかずに重複送信してしまう 等の問題があり、結局あまり活用されませんでした。Chrome は 2022 年にサーバプッシュのサポートを廃止しています。代替として 103 Early Hints(早期ヒント) でリンク情報を先に伝える方式が普及しつつあります。
HOL ブロッキング問題と HTTP/3 への動機
HTTP/2 でアプリ層の HOL は解決しましたが、下層 TCP の HOL ブロッキング という新たな限界が見えてきました。これが HTTP/3 / QUIC の設計動機です。
POINT
HOL(Head-of-Line) ブロッキング:列の先頭が詰まると、後ろが順番待ちで全部止まる現象。
HTTP/1.1 パイプライン → アプリ層 HOL(順序保証のため先頭が遅いと後続も止まる)
HTTP/2 → アプリ層 HOL は解消。だが TCP の順序保証 によって 1パケットでも欠落すると、別のストリームの後続パケットまで配送が止まる(TCP 層 HOL)
図で見る:TCP 層 HOL と QUIC の違い
図の見方:HTTP/2 はストリームを多重化しても、下層の TCP は1本の順序付きの列として扱う。そのため途中のパケットが1つ欠けると、後ろにある別ストリームのデータもアプリへ渡せず待たされる。QUIC はストリームごとに順序保証を分けるため、欠けたストリームだけが待ち、他のストリームは進められる。
なぜ TCP 層で HOL が起きるのか
TCP は受信したセグメントを 必ず順序通りにアプリへ渡す 仕様です。HTTP/2 のように1本の TCP に複数の論理ストリームを乗せると、たとえ ストリーム3 のパケットだけ落ちて、ストリーム5 や 7 のパケットが先に届いていても、TCP は「3 が来るまで全部保留」してしまいます。アプリ層では並行に進められるはずなのに、トランスポート層が足を引っ張る形です。
HTTP/3 = QUIC + HTTP の新しい組み合わせ
QUIC は Google が開発し IETF で標準化された UDP の上で動く新しいトランスポート です。TCP の「コネクション」「再送」「輻輳制御」「TLS による暗号化」を UDP の上で1つにまとめて 実装し、ストリームごとに独立した順序保証を持ちます。これにより TCP 層 HOL が解消されます。HTTP/3 は QUIC の上で HTTP のセマンティクスを動かすマッピングです。
QUIC は OS カーネルではなく
ユーザ空間で実装される ため、進化が速いという別の利点もあります。ただし通信路の機器が UDP を絞っている環境では使えないなど、現場での課題も残ります。詳細は
発展編 QUIC/HTTP3 で扱います。
まとめと用語チェック
SUMMARY
1. HTTP は要求応答型・テキスト(HTTP/1.x) ベースのアプリ層プロトコル。下層は通常 TCP(80) または TLS+TCP(443)
2. メッセージは 先頭行 + ヘッダ行 + 空行 + 本文 の4ブロック構造
3. 主要メソッドは GET / POST / PUT / DELETE / HEAD / OPTIONS。安全性・冪等性で性質が分かれる
4. ステータスコードは 1xx〜5xx の5分類。よく出る 200/301/302/304/400/401/403/404/500/502/503 は意味を覚える
5. 主要ヘッダ:Host・User-Agent・Content-Type・Content-Length・Cookie・Cache-Control・Authorization
6. HTTP はステートレス。継続的な状態は Cookie + サーバ側セッション で実現
7. HTTP/1.0 → 1.1:パーシステント接続(keep-alive) で TCP を再利用。パイプラインは HOL のため実用化されず
8. HTTP/2:バイナリフレーム、ストリーム多重化、HPACK ヘッダ圧縮、サーバプッシュ。アプリ層 HOL を解消
9. ただし TCP 層 HOL が残るため、HTTP/3 = QUIC(UDP 上) で根本対処
用語チェック
| 用語 | 1行説明 |
| リクエスト行 / ステータス行 | HTTP メッセージの先頭1行。メソッド+URI+版 / 版+コード+理由句 |
| メソッド | サーバへの動詞指示。GET / POST / PUT / DELETE / HEAD / OPTIONS など |
| 安全 / 冪等 | サーバ状態を変えない / 何度実行しても結果が同じ。メソッド設計の指針 |
| ステータスコード | レスポンスの3桁数値。1xx 情報・2xx 成功・3xx リダイレクト・4xx クライアント・5xx サーバ |
| ヘッダ | 「フィールド名: 値」の形式でメッセージのメタ情報を運ぶ |
| Host ヘッダ | HTTP/1.1 必須。同一 IP の仮想ホストを識別 |
| Content-Type / Length | 本文の MIME タイプと長さ |
| Cookie / Set-Cookie | サーバが状態管理用に小さなテキストを保存させ、毎回送り返させる仕組み |
| Cache-Control | キャッシュ可否・寿命のディレクティブ群(max-age / no-cache / no-store 等) |
| Authorization | 認証情報を運ぶヘッダ。Basic / Bearer 等 |
| ステートレス | サーバが過去のリクエストを覚えていない設計性質 |
| パーシステント接続 | 1 本の TCP で複数 HTTP リクエストを使い回す(HTTP/1.1 デフォルト) |
| パイプライン | 応答を待たずに連続でリクエストを送る。HOL のため実用化されず |
| バイナリフレーミング | HTTP/2 のメッセージ表現。テキスト行ではなくフレーム |
| ストリーム多重化 | 1 TCP の中で複数論理ストリームを並行に流す HTTP/2 の機構 |
| HPACK | HTTP/2 のヘッダ圧縮(RFC 7541)。静的+動的テーブル+ハフマン |
| サーバプッシュ | クライアント要求前にサーバが関連リソースを送る機能(HTTP/2) |
| HOL ブロッキング | 列の先頭が詰まると後続も止まる現象。アプリ層・TCP 層の両方で起きうる |
| QUIC / HTTP/3 | UDP 上に再設計された次世代トランスポートと、その上の HTTP |
NEXT: 次回(第13回)は本講で学んだ HTTP を 自分で書いて動かす 「HTTP プログラミング」のハンズオン。telnet で生 HTTP を打つところから、curl・Python・Node で簡単なクライアント/サーバを実装します。
確認問題
問1. HTTP/1.1 のリクエストメッセージの構造として最も正しいものを1つ選べ。
次の選択肢から最も適切なものを選択してください。
A. メソッド行 + 本文 + ヘッダ行 + 空行
B. ステータス行 + ヘッダ行 + 空行 + 本文
C. リクエスト行 + ヘッダ行(複数) + 空行 + 本文
D. ヘッダ行 + メソッド行 + 本文(空行は不要)
正解:C
HTTP/1.x のリクエストは「リクエスト行(METHOD URI VERSION) + 0個以上のヘッダ行 + 空行(ヘッダの終端) + 本文」。空行はヘッダと本文の境界を示す重要な区切り。B はレスポンスの構造(ステータス行で始まる)、A・D は順序が誤り。
問2. HTTP メソッドの性質について正しい記述を選べ。
次の選択肢から最も適切なものを選択してください。
A. POST は冪等であり、何度送っても結果は同じになる
B. PUT は冪等で、同じ URI に同じ本文を何度 PUT しても結果は同じ
C. GET は安全ではない(サーバ状態を変える)
D. HEAD は POST と同じ意味を持ち、本文を送るためのメソッドである
正解:B
PUT は「指定 URI をこの内容で置き換えよ」なので、同じ要求を何度送っても最終状態は同一(冪等)。A は誤り(POST は非冪等で、二重投稿が起きうる)。C も誤り(GET は安全=サーバ状態を変えない)。D は誤り(HEAD は GET と同等で本文を返さない)。
問3. 301 と 302 の違いとして最も正しいのはどれか。
次の選択肢から最も適切なものを選択してください。
A. 301 は認証が必要で、302 は認証が不要
B. 301 はキャッシュ用で、302 はリダイレクトには使われない
C. 301 は恒久的な移動、302 は一時的な移動を意味する
D. 301 はサーバエラー、302 はクライアントエラーである
正解:C
301 Moved Permanently は「恒久移動」、302 Found は「一時移動」。検索エンジンは 301 を見ると新 URL でインデックスを更新するが、302 だと旧 URL のままにする。A は無関係(認証は 401)、B も誤り(304 がキャッシュ関連)、D も誤り(3xx はリダイレクトで、サーバ/クライアントエラーは 5xx/4xx)。
問4. HTTP がステートレスであることに関する説明として最も適切なものを選べ。
次の選択肢から最も適切なものを選択してください。
A. ステートレスとは通信経路で暗号化されないことを意味する
B. ステートレスでは Cookie をサーバが保存できないため、ログインは不可能である
C. ステートレスとは TCP コネクションを使わずに UDP で通信することである
D. ステートレスとはサーバが過去のリクエストを記憶しない設計で、Cookie 等で状態を補う
正解:D
HTTP は本来「リクエスト1件ずつを独立に処理し、過去を覚えない」設計。これによりスケーラビリティが高い反面、ログインのような継続状態が表現できないので、Set-Cookie / Cookie ヘッダで小さな目印をクライアントに持たせ、サーバ側のセッションテーブルと突き合わせて状態を復元する。A(暗号化と無関係)、B(Cookie + セッションでログインは可能)、C(トランスポートとは別の話) はすべて誤り。
問5. HTTP/2 の改善点として誤っているものはどれか。
次の選択肢から最も適切なものを選択してください。
A. メッセージをテキスト行ではなくバイナリフレームで表現する
B. UDP の上で動作することにより TCP の HOL ブロッキングを完全に解消する
C. 1 本の TCP コネクションの中で複数のストリームを多重化する
D. HPACK によりリクエスト/レスポンスのヘッダを圧縮する
正解:B
HTTP/2 は依然として TCP の上 で動くため、TCP の順序保証に起因する HOL ブロッキングは残る。これを根本解決したのは HTTP/3 = QUIC(UDP の上に再設計された新トランスポート)。A・C・D は HTTP/2 の正しい改善点(バイナリフレーミング・ストリーム多重化・HPACK ヘッダ圧縮)。