今回はコマンド curl でのレスポンスのHTTPヘッダ情報取得のお話です。
経緯
「ターミナルで curl コマンドを使って得たレスポンス内容のヘッダだけを表示するにはどうしたらいいのだ?」と必要にかられ、ググりました。
いくつか方法を紹介しているウェブページに、大文字の -I
(アイ)オプションをつけて、
curl -I リクエストURL
とすればよいと紹介されています。
むむむ、でもこれ、厳密には 違いました。
とりま答えです
コマンド curl
を使ってHTTP(s)にドキュメントを取得する場合、特にオプションを指定せずリクエストするとGETメソッドが利用されます。
このGETメソッド利用時でHTTPヘッダだけを表示させる方法をいくつか提示しましょう。
-i
オプションを利用
-i
オプションはレスポンスのヘッダも表示させるオプションです。(ロングオプションだと --include
)
表示させるというか、HTTPにおける素の応答テキストが表示されるので、プロトコル仕様上ヘッダ部とボディ部が空行で区切られていることを利用してヘッダ部を抽出します。
curl -si https://qiita.com | awk '/^HTTP/,/^[\r\n]+$/'
Awkのフリップフロップ機能を使っています。1
HTMLドキュメントの改行コードはまちまちなので、”空行”判定はどの改行コードでも判断できるようにしてみました。
なお、-s
オプションは任意です(以下同じ)。
-v
オプションを利用
-v
オプションではデバッグ用にレスポンスヘッダも含めた情報が表示されます。(ロングオプションだと--verbose
)
ヘッダ情報は >
(リクエストの場合) か <
(レスポンスの場合) に続いて表示されるので、これを条件に抽出します、
curl -sv https://qiita.com 2>&1 >/dev/null | grep '^<'
ただこれ、標準エラー出力に出力されるので、リダイレクトを使って標準出力に流してgrepします。2
-D
オプションを利用
-D
オプションはヘッダ情報のみをファイルに出力します。(ロングオプションだと --dump-header
)
curl
実行時のターミナルに直接表示されないとは言え、一番素直な方法かもしれません。
curl -s -D headers.txt https://qiita.com > /dev/null
# cat headers.txt
-w
オプションを利用
比較的新しいオプションである -w
を使います。これは得られた情報を任意のフォーマットに整形できます。(ロングオプションは --write-out
)
ただこのオプション、今のところ必ずレスポンスのボディ部が表示されるので、フォーマット指定した内容のみ表示させるにはちょっと工夫が必要でした。今後もう少し使いやすくするのかな。
curl -s -w '%{stderr}%{header_json}' https://qiita.com 2>&1 >/dev/null
サンプル実行例は標準エラー出力にJSON化したヘッダを出力させ、それを標準出力にリダイレクトさせています。
JSON化された情報になるので jq
などにパイプも可能です。それを使うとちょっと見やすくなるかもですね。
なぜ -I
ではダメなのか
さて、冒頭で書いた”厳密には違った”理由の説明です。
curl の -I
(ロングオプションは --head
)は、レスポンスのヘッダ情報のみを出力するオプションではなくて、HEADメソッドによって得られた結果を表示する、というのが正しい説明になります。3
それゆえサーバによってはGETメソッドで得られるドキュメント内容と異なる場合があります。具体例として Qiita の API(v2) がそのタイプでした。APIドキュメントで”レスポンスのヘッダにある”と書かれているヘッダ情報が得られないなぁ、、、と悩んだのがこの記事のきっかけですね。
なお、HEADメソッドを使うので、APIのような動的ではない静的なコンテンツの場合には、ほぼ”ヘッダのみ表示させる”と等価な結果とはなるのかなと思われます。
この記事を参考にうまく使い分けてもらえればと思います!
(おわり)
資料
-
フリップフロップについては小生の別な記事『Ruby でフリップフロップ』 が参考になるかと。AwkでなくともRubyやPerlなどでも表現は可能です。フリップフロップはあまり使われない機能ですが時々便利なかわいいやつです。 ↩
-
当方Macで確認しているのでちょっと Windows WSLx でできるかは不明です。 ↩