Web Protocol Lab

HTTPレスポンスとキャッシュ挙動を、curl・ブラウザ・プロキシ経由で確認するための検証サイトです。

プロキシやTLSインスペクション装置を挟んだときに、ヘッダーやキャッシュ応答がどう変わるかを確認できます。

RFC 9110 RFC 9111 RFC 9113 RFC 9114 RFC 9000 RFC 6455

#HTTP Status Code Lab

代表的なステータスコードを nginx の return でそのまま返します。curl -i でステータスラインとヘッダーを確認してください。すべてのエンドポイントは X-Demo ヘッダーを返します。

$ curl -i http://localhost:8080/status/200
200 OK
正常応答。ボディとヘッダーの基本形。
/status/200
Observe: Status line, Content-Type
204 No Content
ボディなしの成功応答。Content-Length の扱いに注目。
/status/204
Observe: ボディ無し, Content-Length
301 Moved Permanently
恒久リダイレクト。キャッシュ可能で、ブラウザが保存・再利用する場合がある。
/status/301
Observe: Location, キャッシュ挙動
302 Found
一時リダイレクト。curl は -L を付けない限り追跡しない。
/status/302
Observe: Location, curl -L の挙動
304 Not Modified
本エンドポイントは形を観測する固定応答。本来は条件付きリクエストに対する「変更なし」を示し、ボディは返さない。
/status/304
Observe: ボディ無し, ETag との組合せ
400 Bad Request
構文不正なリクエストへの応答。
/status/400
Observe: Status line
401 Unauthorized
認証が必要。WWW-Authenticate ヘッダーを返す。
/status/401
Observe: WWW-Authenticate
403 Forbidden
サーバーがリクエストを理解したが実行を拒否。認証済みでも返る場合がある。
/status/403
Observe: 401 との違い
404 Not Found
対象リソースを見つけられない、または存在を明かしたくない場合の応答。
/status/404
Observe: Status line
405 Method Not Allowed
許可されないメソッド。Allow ヘッダーを返す。
/status/405
Observe: Allow
408 Request Timeout
サーバー側のリクエスト受信タイムアウト。
/status/408
Observe: Connection の扱い
409 Conflict
リソースの状態と競合。PUT の競合などで使われる。
/status/409
Observe: Status line
410 Gone
対象へのアクセスが意図的に失われ、その状態が永続的と見込まれる場合の応答。
/status/410
Observe: 404 との違い
429 Too Many Requests
レート制限超過。Retry-After ヘッダーを返す。
/status/429
Observe: Retry-After
500 Internal Server Error
サーバー内部エラー。
/status/500
Observe: Status line
502 Bad Gateway
上流サーバーからの不正応答。プロキシ環境の定番エラー。
/status/502
Observe: プロキシ経由での見え方
503 Service Unavailable
一時的に処理不能。Retry-After ヘッダーを返す。
/status/503
Observe: Retry-After

観測ポイント

curlcurl -i でステータスライン・ヘッダーを確認。リダイレクトは -L の有無で挙動比較。
DevToolsNetwork タブで Status 列と Response Headers を確認。301 はディスクキャッシュから返る場合がある((from disk cache) 表示)。
Proxyプロキシ経由時に ViaX-Forwarded-For が付与されるか、5xx がプロキシ自身のエラーページに差し替えられないかを確認。
tcpdump / Wireshark平文HTTPなら http フィルタでステータスライン確認。HTTPS は TLS 復号設定(SSLKEYLOGFILE)が必要。
TLS inspectionインスペクション装置がステータスコードを書き換えないか、direct と proxy 経由でレスポンスを diff して確認。

#Cache Control Lab

各エンドポイントは異なる Cache-Control ディレクティブを返します。ブラウザのリロード / スーパーリロード、curl の条件付きリクエストで挙動の違いを観測してください。

no-store
HTTPキャッシュに応答を保存させない。プライベート・共有キャッシュの両方が対象。
/cache/no-store
Observe: HTTPキャッシュから再利用しない
no-cache
保存は可能だが、成功した再検証なしに応答を再利用できない。「保存しない」とは異なる。
/cache/no-cache
Observe: ETag + 再検証リクエスト
max-age=60
保存された場合、60秒間はfreshとして再利用できる。リロード操作や実装によっては期間内でも通信が発生し得る。
/cache/max-age-60
Observe: 60秒以内の再訪問
public, max-age=3600
共有キャッシュ(プロキシ/CDN)にも保存可能。
/cache/public-max-age
Observe: プロキシ経由の Age ヘッダー
private, max-age=60
ブラウザなどのプライベートキャッシュには保存可能。共有キャッシュには保存させない。
/cache/private
Observe: 共有キャッシュでの非保存
max-age=0, must-revalidate
staleな応答は、再検証に成功するまで再利用しない。再検証先に到達できない場合もstaleのまま使わない。
/cache/must-revalidate
Observe: 再検証の強制
stale-while-revalidate
指定期間内であれば、stale応答を返しつつ非同期に再検証することをキャッシュに許可する。
/cache/stale-while-revalidate
Observe: stale 応答と非同期再検証
ETag / If-None-Match
静的ファイル配信で自然な ETag と 304 を検証。
/cache/static/etag-demo.txt
Observe: ETag → 304 Not Modified
Last-Modified / If-Modified-Since
更新日時ベースの条件付きリクエストと 304 を検証。
/cache/static/last-modified-demo.txt
Observe: Last-Modified → 304

ETag → 304 を体験する

curl
# 1回目: 200 OK と ETag を受け取る
$ curl -i http://localhost:8080/cache/static/etag-demo.txt

# 2回目: 受け取った ETag を If-None-Match に入れて送る → 304
$ curl -i -H 'If-None-Match: "<上で受け取ったETag値>"' \
    http://localhost:8080/cache/static/etag-demo.txt
応答例 (ETag値はファイルと環境で変わる)
HTTP/1.1 304 Not Modified ETag: "<実際に受け取った値>" Cache-Control: public, max-age=0, must-revalidate

Last-Modified → 304 を体験する

curl
# 1回目: Last-Modified を受け取る
$ curl -i http://localhost:8080/cache/static/last-modified-demo.txt

# 2回目: その日時を If-Modified-Since に入れて送る → 304
$ curl -i -H 'If-Modified-Since: <上で受け取ったLast-Modified値>' \
    http://localhost:8080/cache/static/last-modified-demo.txt
注意: nginx は if_modified_since exact; 設定時、日時が完全一致した場合のみ 304 を返します。1秒でもずれると 200 になります。この違い自体が観測ポイントです。

観測ポイント

curl条件付きヘッダー(If-None-Match / If-Modified-Since)有無での 200 / 304 の変化。304 のときボディが無いこと。
DevToolsNetwork タブの Size 列: (from memory cache) / (from disk cache) / 304 の違い。リロードとURL再入力で挙動が変わる。
Proxy共有キャッシュが Age ヘッダーを付けるか、private をキャッシュしないか、Vary をキーに含めるか。
tcpdump / Wireshark応答がキャッシュに保存され、freshなまま再利用された場合は、ネットワークへのリクエスト自体が発生しないことを確認。
TLS inspectionインスペクション装置自身がキャッシュを持つ場合、オリジンに到達せず応答が返るケースを diff で確認。

#Header Lab

セキュリティヘッダー、CORS、Content-Type、圧縮、リダイレクトチェーンの挙動を確認します。

HSTS (Strict-Transport-Security) は、ブラウザがHTTPS接続上で受け取った場合にのみポリシーとして有効です。本ラボの http://localhost:8080/headers/security はヘッダーを観測する固定応答であり、それだけでHSTSのブラウザ動作を検証できるわけではありません。

curl
# 圧縮: Accept-Encoding の有無で Content-Encoding が変わる
$ curl -i http://localhost:8080/headers/compression
$ curl -i --compressed http://localhost:8080/headers/compression

# リダイレクトチェーンを追跡
$ curl -iL http://localhost:8080/headers/redirect

#Protocol Guides

各プロトコルの仕様・通信シーケンス・観測方法をまとめた解説ページです。シーケンス図・検証コマンド・プロキシ/TLSインスペクション環境での見え方を掲載しています。