はじめに
これは肖佳先生の書籍『HTTP抓包实战』を読んだ後にまとめた HTTP に関する学習メモです。主に HTTP メッセージ関連の内容を整理しました。(記録:読書+本記事作成に5日間かかりました)
HTTPメッセージ構造
HTTPメッセージには「リクエストメッセージ(Request)」と「レスポンスメッセージ(Response)」の2種類があります。
HTTPリクエストメッセージ(Request)
HTTPリクエストは以下の3つのパートで構成されます:
開始行(Request line):リクエストメソッド、URI、HTTPバージョン
例:GET https://blog.yexca.net/ HTTP/2ヘッダ部(Header):追加情報や制御情報を含む
ボディ部(Body):フォームデータやファイルなどの実データ(※省略される場合もあり)
注意:ヘッダとボディの間には必ず空行が入ります。
HTTPレスポンスメッセージ(Response)
HTTPレスポンスも同様に3つのパートから成ります:
ステータス行(Response line):HTTPバージョン、ステータスコード、ステータスメッセージ
例:HTTP/2 200 OKヘッダ部(Header)
ボディ部(Body)
こちらもヘッダとボディの間には空行が入ります。
HTTPリクエストメソッドとステータスコード
URLの構造
URL(Uniform Resource Locator)は、インターネット上のリソースを一意に識別するためのものです。
基本構成:
 |  | 
| 項目 | 説明 | 
|---|---|
| スキーム | http, https, ftp などの通信プロトコル | 
| ホスト | ドメインまたは IP アドレス | 
| ポート番号 | 通常 HTTP は 80、HTTPS は 443(省略可) | 
| パス | リソースのパス | 
| クエリ文字列 | ?以降のパラメータ(例:?id=1&name=test) | 
| アンカー | ページ内リンク(例:#top) | 
主なHTTPメソッド
| No. | メソッド | 説明 | 
|---|---|---|
| 1 | GET | サーバーからデータを取得する | 
| 2 | HEAD | GETと似ているが、レスポンスボディは返されない(ヘッダのみ) | 
| 3 | POST | サーバーにデータを送信(例:フォーム送信、ファイルアップロードなど) | 
| 4 | PUT | リソースを新しく作成または完全に置き換える | 
| 5 | DELETE | 指定したリソースを削除する | 
GETとPOSTの違い
データの送信位置
GET は URL の末尾(?以降)に付ける。POST はボディに含まれる。サイズ制限
GET は URL 長に制限あり(ブラウザ依存)。POST は基本的に制限なし。取得方法
GET はrequest.queryString、POST はrequest.formなどを使う。
HTTPステータスコード
HTTPレスポンスの中に含まれる数字で、リクエストの結果を示すものです。
| コード範囲 | 意味 | 
|---|---|
| 1XX | 情報(処理中) | 
| 2XX | 成功 | 
| 3XX | リダイレクト | 
| 4XX | クライアントエラー | 
| 5XX | サーバーエラー | 
よく使われるステータスコード
| コード | 説明 | 
|---|---|
| 200 OK | リクエストが成功した | 
| 301/302 | 恒久的/一時的リダイレクト。Location ヘッダに新しいURLが含まれる | 
| 304 | コンテンツが更新されていない(キャッシュ利用可能) | 
| 401 | 認証が必要(Basic認証など) | 
| 403 | アクセス禁止(アクセスは認識されたが拒否された) | 
| 404 | リソースが見つからなかった | 
| 500 | サーバー内部エラー(スクリプトエラーなど) | 
| 503 | 一時的にサービス利用不可(メンテ中など) | 
206 Partial Content(部分的コンテンツ)
- サーバーがリクエストされた一部のコンテンツを返した場合
 - 動画のストリーミングやダウンロード再開などに使われる
 - ヘッダに 
Range(要求)やContent-Range(応答)が含まれる 
301 vs 302(リダイレクト)
- 301: 永続的な移動 → 検索エンジンもリンク先を更新
 - 302: 一時的な移動 → ユーザーセッションやログイン時など
 
304 Not Modified(未更新)
- ブラウザキャッシュが最新 → サーバーは新しいデータを送らない
 
400 Bad Request(不正リクエスト)
- リクエストの構文エラー(例:クッキー不正、フォーム誤送信など)
 
401 Unauthorized(認証エラー)
- 認証ヘッダがない/不正な場合。Basic 認証などで返される
 
403 Forbidden(禁止)
- サーバーがリクエストを明示的に拒否したい時に使用(理由は非公開)
 
404 Not Found(見つからない)
- 該当リソースなし
 - 例:非ログイン状態では一部URLが 404 を返す(実際は制限付き)
 
500 Internal Server Error(サーバー内部エラー)
- プログラムのバグ、DB接続エラー、例外など
 
503 Service Unavailable(サービス一時停止)
- 過負荷やメンテナンス時など
 
その他のコードを見るには
HTTP ヘッダー構成
ヘッダーの形式は「キー: 値」で 1 行ずつ記述され、それぞれが特定の機能を持ちます。
キャッシュ関連ヘッダー
HTTP リクエスト・レスポンスの両方にキャッシュ制御に関連するヘッダーがあります。
HTTP キャッシュとは、同じリソースを再び取得する際にローカルのキャッシュを使用して、再ダウンロードを避ける仕組みです。
Cookie
Cookie は HTTP のキャッシュ制御手段のひとつで、key=value 形式のデータです。
- ブラウザ → サーバー:
Cookie:ヘッダーで Cookie を送信 - サーバー → ブラウザ:
Set-Cookie:ヘッダーで Cookie を設定 
例:ip_country=CN
Accept
Accept ヘッダーは、クライアントが受け入れ可能な MIME タイプを通知します。
例:Accept: text/html は HTML を受信可能という意味です。
ワイルドカード(*)を使って任意タイプを表現できます。
例:Accept: text/html, */*;q=0.8
Accept-Encoding
圧縮方式に関するヘッダーで、クライアントが対応する圧縮形式を通知します。
例:Accept-Encoding: gzip, deflate
Accept-Language
Accept-Language は、クライアントが受け入れられる言語の一覧を通知します。
例:Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,zh-TW;q=0.2
言語(日本語、中国語など)と文字コード(UTF-8、GBK など)は別物です。
User-Agent
User-Agent は、クライアントの環境情報(OS、CPU、ブラウザバージョンなど)を通知する文字列です。
例:User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:103.0) Gecko/20100101 Firefox/103.0
これを書き換えることで、他のブラウザやデバイスを装ったリクエストも可能になります。
Referer(リファラー)
リファラーはアクセス元の URL を示し、どこから来たのかをサーバー側が判断できます。
アクセス解析や不正リンク検出などに利用されます。
Connection
HTTP/1.1 以降は、デフォルトで Connection: Keep-Alive によって TCP 接続が継続されます。
この接続維持時間は Web サーバー側(Apache など)で設定可能です。
Host
Host ヘッダーは、リクエスト対象のホスト名とポート番号を明示します。HTTP/1.1 以降は必須です。
ポートが 80 の場合は省略可能です。
HTTP キャッシュの仕組み
HTTP のキャッシュは、主にブラウザやプロキシサーバーで動作します。
キャッシュの利点
- 不要なデータ転送の削減
 - レスポンス速度の向上
 - サーバー負荷の軽減
 
キャッシュの鮮度判断方法
方法①:If-Modified-Since / Last-Modified
クライアントが If-Modified-Since ヘッダーでローカルの更新日時を通知します。
サーバーが Last-Modified ヘッダーと比較し、変更がなければ 304 Not Modified を返します。
方法②:If-None-Match / ETag
クライアントが If-None-Match で ETag(ハッシュ値)を送信し、サーバーが照合して同一なら 304 を返します。
キャッシュ関連ヘッダー一覧
リクエスト側
| ヘッダー名 | 説明 | 
|---|---|
| Cache-Control: max-age=0 | キャッシュの有効期限(秒) | 
| If-Modified-Since: Tue, 28 Jun 2022 … | 最終更新日時 | 
| If-None-Match: “etag-value” | キャッシュの ETag | 
| Cache-Control: no-cache | キャッシュを使用しない | 
| Pragma: no-cache | 上記と同じ(HTTP/1.0 用) | 
レスポンス側
| ヘッダー名 | 説明 | 
|---|---|
| Cache-Control: public | 共有キャッシュ可(プロキシ等) | 
| Cache-Control: private | ユーザー固有キャッシュ | 
| Cache-Control: no-cache | 必ず再検証 | 
| Cache-Control: no-store | 完全非キャッシュ(機密データ用) | 
| Cache-Control: max-age=60 | 相対時間での有効期限(秒) | 
| Date: Thu, 01 Sep 2022 … | サーバー送信日時 | 
| Expires: Thu, 01 Sep 2022 … | 絶対時間による有効期限 | 
| Last-Modified: Tue, 28 Jun 2022 … | 最終更新日時 | 
| ETag: “etag-value” | キャッシュ判定用の識別子 | 
※ 通常は Cache-Control 優先、なければ Expires が参照されます。
ETag とは?
- 「Entity Tag」の略で、ファイル内容から生成されるハッシュ文字列です
 - 内容が変われば ETag も変わるので、更新判定が高精度
 
ETag は、Last-Modified では対応できない問題(ミリ秒単位の変更や内容が同じ等)を補います。
強制再読み込みとキャッシュ
Ctrl + Shift + R:強制リロード(キャッシュ無効)Ctrl + R:再読み込み(条件付き GET)
アドレスバーから直接 URL 入力時は、ブラウザは「キャッシュ命中(cache hit)」としてサーバーと通信せず、ローカルキャッシュを使用します。
パブリックとプライベートキャッシュ
| 種類 | ヘッダー | 説明 | 
|---|---|---|
| パブリック | Cache-Control: public | 共有可能(例:プロキシキャッシュ) | 
| プライベート | Cache-Control: private | 個別ユーザーのローカルキャッシュ | 
HTTP 圧縮と URL エンコード
HTTP 圧縮の概要
Web サーバーとブラウザ間で送受信される「テキストデータ」を圧縮する技術です。
例:HTML / CSS / JavaScript など → gzip 圧縮
圧縮とエンコードの違い
HTTP ボディの「Content-Encoding」は、単にサイズ削減の gzip 圧縮だけでなく、暗号化なども可能です。
つまり、HTTP 圧縮は HTTP エンコーディングの一種です。
圧縮の流れ
クライアントは
Accept-Encoding: gzip, deflateで対応可圧縮形式を提示サーバー側は
- 元のレスポンスを生成
 - ボディ部分を gzip 圧縮
 Content-Encoding: gzipを付与- ブラウザへ返却
 
ブラウザは Content-Encoding を見てデコードし、元データを表示
※リクエストの圧縮は一般的ではない
Content-Encoding 種類
| エンコーディング | 内容 | 
|---|---|
| gzip | GNU Gzip 形式 | 
| compress | UNIX compress | 
| deflate | zlib 圧縮 | 
| identity | 無圧縮(指定なし時のデフォルト) | 
gzip / deflate は一般的な可逆圧縮で、gzip のほうが効率が良く広く使われています。
Cookieメカニズムの仕組み
HTTPはステートレスなプロトコルであり、同じブラウザからの複数のリクエストでもサーバー側では独立したものとして扱われ、関連性は持ちません。
セッションとCookie
サーバーがクライアントの識別を行うには、状態管理が必要になります。HTTPがステートレスであるため、クライアントとサーバーが共同で状態を管理する「セッションメカニズム」が使用されます。
- クライアントが初めてアクセスした際、サーバーはセッションIDを生成し、レスポンスに含めて返す
 - ブラウザはセッションIDを保存し、以後のリクエストに含める
 - サーバーはセッションIDによって同じクライアントかどうかを判別する
 
このセッションの仕組みにCookieが使われています。
Cookieとは
Cookieとは、ブラウザが少量のデータを key=value の形式で保持する仕組みです。複数のCookieは ; で区切られ、リクエスト時に自動的に送信されます。
主に認証情報やユーザー設定の保持、または広告追跡・ターゲティングなどに利用されます。
現在では、EUなどの国ではCookieの使用に関する法的制限があり、ユーザーの同意が必要です。
Cookieの属性
Expires
有効期限を指定。未指定の場合、ブラウザを閉じると削除されます。Path
Cookieが有効なパス範囲を指定します。例:/test/に設定すると、/test/配下でのみ有効。HttpOnly
JavaScript からアクセス不可にする属性で、XSS対策に効果的。ログイン用Cookieには必須。
Cookieの種類と保存場所
| 種類 | 説明 | 
|---|---|
| セッションクッキー | 一時的なCookie。ブラウザを閉じると削除される | 
| 永続クッキー | 有効期限があり、再起動しても保持される | 
ブラウザごとに保存場所は異なり、例:Linux + Firefox の場合~/.mozilla/firefox/xxxxxxxx.default-release/cookies.sqlite
HTTP基本認証
HTTPはステートレスであるため、Cookieによる認証のほか、Basic認証(基本認証)も用いられます。
クライアントは ユーザー名:パスワード をBase64でエンコードし、Authorization ヘッダーに含めて送信します。
基本認証の流れ
- サーバーが 
401 Unauthorizedを返し、WWW-Authenticateヘッダーで認証を要求 - ブラウザがログインダイアログを表示し、認証情報を取得
 - 入力されたユーザー名とパスワードをBase64エンコードし、リクエストに含めて送信
 
家庭用ルーターや一部のREST APIではこの方式がよく使われます。
例:curl -u ユーザー名:パスワード https://example.com
基本認証の欠点
- ステートレスなので、リクエストごとに認証が必要
 - Base64は簡単に復号できるため、パスワードが平文で送信されるのと同等。HTTPS必須
 - 明示的にログアウトできない(Cookieと違って期限切れの仕組みがない)
 - リプレイ攻撃 に弱い
 
Digest認証(要約認証)
Digest認証は、基本認証のセキュリティ上の欠点を補った改良方式です。
- パスワードの代わりにハッシュ値を送信することで、平文送信を回避
 - サーバー側で nonce(ワンタイムトークン)を生成してリプレイ攻撃を防止
 - クライアントも nonce を用いることでサーバー認証が可能
 - コンテンツの整合性チェックにも対応