curl -I の結果を読めるようになる ― HTTPレスポンスヘッダーを1行ずつ見る

ネットワーク・RFCカテゴリを表すパンダのイラスト ネットワーク・RFC

この記事について
この記事は、curl公式ドキュメントとHTTP仕様を確認して整理しています。

検証ステータス:📘 公式仕様確認済み・接続先依存部分は未固定
HTTPヘッダーの値は接続先や時点で変わります。記事では「特定の値になること」ではなく、読み方を扱います。

curl -I は、Webサーバーが返すHTTPレスポンスのメタデータを確認する入口です。最初から全ヘッダーを覚える必要はありません。Status、Content-Type、Content-Encoding、Cache-Control、Content-Lengthを順に見るだけでも、Webサーバーの調査がかなりしやすくなります。

curl -I は何を送っているのか

HTTP URLに対する -I / –head はHEADリクエストを使います。

curl -I https://example.com/
sequenceDiagram
    participant C as curl
    participant S as Web server
    C->>S: HEAD /
    S-->>C: Status + Header fields
    Note over C,S: response bodyは送信しない

HEADは、GETに対応するメタデータを本文なしで確認するためのHTTPメソッドです。したがって、curl -I の結果と実際のGETが常に一字一句同じになるわけではありません。

最初に見る5項目

概念的には、次のような出力を読みます。

HTTP/2 200
content-type: text/html; charset=UTF-8
content-encoding: gzip
cache-control: max-age=300
content-length: 12345
項目何を見るか
Statusリクエストの結果
Content-TypeHTML、JSON、JavaScriptなど表現の種類
Content-Encodinggzipなどのcontent coding
Cache-Controlキャッシュに対する指示
Content-Length表現の長さに関する情報
flowchart LR
    A[HTTP response] --> B[Status]
    B --> C[Content-Type]
    C --> D[Content-Encoding]
    D --> E[Cache-Control]
    E --> F[Content-Length]

Statusだけで「サイト正常」と判断しない

200はHTTPリクエストが成功したことを示します。ただし、アプリケーション内部の全機能が正常、データベースも正常、といった意味までは含みません。

逆に301や302は、別URLへ移動するためのredirectであり、必ずしも障害ではありません。

Content-Type は何を返しているか

content-type: text/html; charset=UTF-8

この例なら、表現はHTMLで、charsetとしてUTF-8が示されています。API調査なら application/json、JavaScriptなら text/javascript や application/javascript など、対象によって異なります。

gzip確認では Content-Encoding を見る

Webサーバーでgzipを有効にしていても、すべてのレスポンスが必ずgzipになるとは限りません。リクエスト側のAccept-Encoding、Content-Type、サイズ、サーバー設定などが関係します。

圧縮を受け入れるリクエストとして確認したい場合は、たとえば次のように明示できます。

curl -sS -D - -o /dev/null -H 'Accept-Encoding: gzip' https://example.com/

レスポンスに次があれば、gzip content codingが使われています。

content-encoding: gzip

Cache-Control は「キャッシュする・しない」だけではない

Cache-Controlには max-age、no-cache、no-store など複数のdirectiveがあります。それぞれ意味が異なるため、単に「no-cacheという文字があるからキャッシュしない」とだけ覚えると誤解しやすくなります。

HTTPキャッシュを調査するときはRFC 9111と合わせて読みます。

Content-Length がない場合もある

HEADレスポンスでContent-Lengthが表示されないからといって、直ちに異常とは限りません。転送方法や動的生成、HTTPバージョン、サーバー実装などによって見える情報は変わります。

「あるはずのヘッダーを探す」より、「実際に返ってきたヘッダーから意味を読む」方が安全です。

-I と -i を混同しない

  • -I: HTTPではHEADを送り、レスポンスヘッダーを確認する

  • -i: 通常のレスポンスで、ヘッダーを本文と一緒に表示する

GET時の実際のレスポンスも見たいなら、-i や -D – が候補になります。

curl -i https://example.com/

Nginx調査へつなげる

Nginxでgzipやcacheを調べるなら、設定ファイルだけを見るのではなく、最終的にHTTPレスポンスへどう現れたかをcurlで確認します。

flowchart LR
    A[Nginx設定] --> B[リクエスト]
    B --> C[レスポンス]
    C --> D[Content-Type]
    C --> E[Content-Encoding]
    C --> F[Cache-Control]
    D --> G[設定と実測を照合]
    E --> G
    F --> G

設定値と実際のレスポンスを分けて確認すると、「設定は書いたが対象レスポンスには適用されていない」といった切り分けができます。

まとめ

  • curl -I はHTTPではHEADリクエストを使う

  • まずStatusと主要なヘッダーだけ読む

  • gzipはContent-Encoding、キャッシュはCache-Controlを中心に見る

  • HEADとGETは目的が違うため、必要ならGET側も確認する

  • Webサーバー調査では「設定」と「実際のHTTPレスポンス」を照合する

公式情報・一次情報

curl command line tool and library — manual
https://curl.se/docs/manpage.html

RFC 9110 — HTTP Semantics
https://www.rfc-editor.org/rfc/rfc9110.html

RFC 9111 — HTTP Caching
https://www.rfc-editor.org/rfc/rfc9111.html

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました