C
ネットワーク/HTTP/Lesson 04

HTTP — メソッド・ステータスコード・ヘッダー・HTTPS・TLS・HTTP/2・3

45分·theory

HTTP — メソッド・ステータスコード・ヘッダー・HTTPS・TLS・HTTP/2・3

🎯 このlessonを読み終えたら

このlessonを最後まで読み終えたら、以下の3つを自信を持って説明できるようになります。

  • ✅ HTTP 1.0 → 1.1 → 2 → 3 の変遷のポイント
  • ✅ GET・POST・PUT・DELETE・PATCHの冪等性
  • ✅ Cache-Control・ETag・304のキャッシュ動作

学習目標をチェックリストとして手元に置き、すべて答えられるようになったらlessonを閉じてください。

HTTPメソッド・ステータスコード・ヘッダー

HTTPメソッド(8種類):

メソッド意味冪等?安全?
GET取得
HEADヘッダーのみ
POST作成
PUT全体置換
PATCH部分更新❌(通常)
DELETE削除
OPTIONS許可メソッド確認(CORSプリフライト)
TRACE·CONNECTデバッグ・トンネル

冪等性 = 同じリクエストをN回送っても1回と同じ結果になること。決済・POST以外はすべて冪等であることが推奨。


HTTPステータスコード(5グループ):

コード意味
1xx情報100 Continue(リクエスト本文を送信してOK)
2xx成功200 OK · 201 Created · 204 No Content
3xxリダイレクト301 永続 · 302 一時 · 304 Not Modified(キャッシュ)
4xxクライアントエラー400 Bad Request · 401 Unauthorized · 403 Forbidden · 404 Not Found · 409 Conflict · 422 Unprocessable · 429 Too Many Requests
5xxサーバーエラー500 Internal · 502 Bad Gateway · 503 Service Unavailable · 504 Gateway Timeout

よく混同されるケース:

  • 401 = 未認証(ログインが必要)
  • 403 = 認証済みだが権限なし
  • 404 = リソースが存在しない(または権限なしを隠すための使用)

主要なHTTPヘッダー:

ヘッダー用途
Authorization: Bearer xxx認証トークン
Content-Type: application/json本文の形式
Accept: application/json希望するレスポンス形式
Cache-Control: max-age=3600キャッシュポリシー
Cookie: session=xxxクッキー
User-Agent: Mozilla...クライアント情報
Origin: https://a.comリクエスト元(CORS)
X-Forwarded-For: 1.2.3.4プロキシ経由の実際のIP
Strict-Transport-SecurityHSTS(HTTPS強制)
Content-Security-PolicyCSP(XSS対策)

HTTPS + TLS 1.3 ハンドシェイク

HTTPS = HTTP + TLS。平文のHTTPはパケットを傍受されるとすべての内容が漏洩します。

TLS 1.3 ハンドシェイク(1-RTT、2018年標準化):

code
Client                                Server
  │  ── Client Hello (サポートアルゴリズム) ──▶  │
  │                                       │
  │  ◀── Server Hello + 証明書          │
  │      + キー交換情報                   │
  │                                       │
  │     [クライアントが証明書検証]         │
  │                                       │
  │  ── Finished (暗号化開始)        ──▶ │
  │  ◀── Finished                       │
  │                                       │
  │     [暗号化された HTTP 通信]              │

証明書の3段階検証:
1. 信頼性: 発行者は信頼されたCAか?(ブラウザ内蔵のCAリスト)
2. 有効性: 期限切れでない?失効していない(CRL・OCSP)?
3. 一致性: ドメインが一致しているか?(*.example.comapi.example.com

Forward Secrecy(TLS 1.3では必須):

  • セッションごとに新しい鍵を生成
  • サーバー鍵が漏洩しても過去のトラフィックは復号できない

HTTP/1.1 vs 2 vs 3:

バージョンリリース特徴
HTTP/1.01996リクエストごとに新しいTCP接続
HTTP/1.11997Keep-Alive・パイプライン・チャンク転送
HTTP/22015多重化・ヘッダー圧縮(HPACK)・サーバープッシュ
HTTP/32022(RFC 9114)QUIC(UDP)ベース・0-RTT

HTTP/2の多重化1つのTCP接続で複数のストリーム:

  • HTTP/1.1: 同時接続は6本まで(ブラウザ制限)
  • HTTP/2: 1接続で無制限のストリーム。Head-of-Lineブロッキングを解消

HTTP/3(QUIC) — TCPの限界を克服:

  • TCPのHoLブロッキングを解消(1パケット損失で全体が待機)
  • 0-RTT再接続(PSK)
  • モバイルでIPが変わっても接続を維持
💻 📌 curlでHTTPをデバッグする
# === 基本 ===
curl https://api.example.com/users        # GET
curl -i https://api.example.com           # ヘッダーを含む
curl -v https://api.example.com           # 詳細 (TLS ハンドシェイクまで)
curl -I https://api.example.com           # HEAD (ヘッダーのみ)
curl -L https://example.com               # リダイレクトを追跡

# === POST + JSON ===
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name":"ホン・ギルドン","email":"[email protected]"}'

# === 認証 ===
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/me
curl -u user:pass https://api.example.com/secret      # Basic Auth
curl --cookie "session=abc" https://api.example.com   # クッキー

# === ファイル ===
curl -O https://example.com/file.zip      # その名前で保存
curl -o out.json https://api.example.com  # 指定した名前
curl -F "[email protected]" https://upload.example.com  # アップロード

# === HTTP/2·3 確認 ===
curl --http2 -I https://example.com       # HTTP/2 を強制
curl --http3 -I https://cloudflare.com    # HTTP/3 (サポート時)

# === TLS デバッグ ===
openssl s_client -connect example.com:443 -servername example.com
# 証明書チェーン出力
curl -vI https://example.com 2>&1 | grep -E "subject|issuer"

# === 応答時間測定 ===
curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nTCP: %{time_connect}s\nTLS: %{time_appconnect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" https://example.com

# === HTTP ステータス確認 (CI で有用) ===
curl -o /dev/null -s -w "%{\nhttp_code}\n" https://api.example.com/health
# 200 / 404 / 500 のみ出力

HTTPキャッシュ — Cache-Control・ETag・304

キャッシュが必要な理由

同じリソースを毎回再取得しない — 帯域幅・サーバー負荷・体感速度のすべてが改善されます。

Cache-Control — 現代の標準

code
Cache-Control: public, max-age=3600
Cache-Control: private, max-age=0, no-cache
Cache-Control: public, max-age=31536000, immutable

よく使う6つのディレクティブ

ディレクティブ意味
publicすべてのキャッシュ(CDN含む)に保存可能
privateブラウザのみ保存(CDN不可)
max-age=NN秒間はfresh
no-cache使用前に必ずサーバーで検証(キャッシュはする)
no-store絶対に保存しない(ログイン・決済)
immutable絶対に変わらない — 検証リクエストも不要

実務パターン

code
# HTMLページ(コードが頻繁に変わる)
Cache-Control: no-cache

# JS/CSSバンドル(ファイル名にhash含む)
Cache-Control: public, max-age=31536000, immutable

# APIレスポンス(ユーザーごと)
Cache-Control: private, max-age=60

# ログイン・決済
Cache-Control: no-store

ETag — 変更確認のための指紋

code
# 初回リクエスト
GET /img.png
→ 200 OK
  ETag: "abc123"
  (画像本文)

# 2回目のリクエスト
GET /img.png
  If-None-Match: "abc123"
→ 304 Not Modified    (本文なし — キャッシュをそのまま使う)

ETagが一致すれば本文は送信されない — 帯域幅の節約。本文1MB → レスポンス0KB。

Last-Modified — 旧来の方式

code
Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT
If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT

ETagより精度が低い(秒単位)。現代のサーバーはETagを優先。

ブラウザキャッシュ vs CDNキャッシュ

code
[ブラウザ] ↔ [CDN(Cloudflareなど)] ↔ [オリジンサーバー]
  • ブラウザキャッシュ: private または public の両方を保存。自分のPCのみ
  • CDNキャッシュ: public のみ保存。世界中のエッジサーバーで共有

Vary ヘッダーでどのリクエストの違いに応じて別キャッシュを作るかを指定:

code
Cache-Control: public, max-age=3600
Vary: Accept-Encoding, Cookie

stale-while-revalidate — ゼロ遅延 + 最新性

code
Cache-Control: max-age=60, stale-while-revalidate=300

60秒まではfresh60〜360秒は古いレスポンスを即座に返しつつ、バックグラウンドで新しいデータを取得して更新ユーザーは即座にレスポンスを受け取り次のリクエストでは新しいデータが返る

Next.jsとTanStack Queryは内部的にこの戦略を使用しています。

🤖 AIへの質問例

  • 「Next.jsのnext.config.jsで静的ファイルに1年キャッシュ + HTMLにno-cacheを設定して」
  • 「このAPIレスポンスに60秒キャッシュ + stale-while-revalidate 300秒のヘッダーを追加して」
HTTP — メソッド・ステータスコード・ヘッダー・HTTPS・HTTP/2・3 - ネットワーク