みなさんこんにちは。 Webサイトの動作確認をしている際に、少しハマってしまった点がありましたので記事にしました。
概要
HTTPステータスコードを取得する際、Linuxなどでは curl コマンドで簡単にできるのですが、Windows標準のcurlでは内部的にエラーとなってしまいそのまま同じコマンドを使用することはできません。WindowsでHTTPステータスコードを取得する際の注意点や取得コマンドについて簡単にまとめてみました。
HTTPステータスコードとは
まずは前提のHTTPステータスコードについてですが、ご存じの方の方が多いと思いますので下記リンクの紹介のみとして詳細は割愛させていただきます。
HTTPステータスコードは、HTTPにおいてWebサーバからのレスポンスの意味を表現する3桁の数字からなるコードである。RFC 7231等によって定義され、IANAがHTTP Status Code Registryとして管理している。
ステータスコードの取得方法(Powershell)
WindowsのコマンドプロンプトでHTTPステータスコードを調べる場合は、Powershellのコマンドを使用するか curl を使用するかの2択となり、Powershellの場合は以下のコマンドを使用することで調査できます。
PS C:\> Invoke-WebRequest -uri "https://blog.serverworks.co.jp/" |Select StatusCode StatusCode ---------- 200
HTTPステータスコードだけ知りたいときは、下記のようなコマンドにするとコードだけ得ることができます。
PS C:\> (Invoke-WebRequest -uri "https://blog.serverworks.co.jp/").StatusCode 200
Powershell はとても便利なのですが、HTTPステータスコードが404の場合 Invoke-WebRequest コマンドのエラーとして処理されてしまいます。この場合コマンド自体に問題がないため、エラー処理として「 -ErrorAction SilentlyContinue」のオプションを追加しても結果は変わらずエラーのままとなります。
PS C:\> Invoke-WebRequest -uri "https://blog.serverworks.co.jp/1" |Select StatusCode Invoke-WebRequest : リモート サーバーがエラーを返しました: (404) 見つかりません 発生場所 行:1 文字:1 + Invoke-WebRequest -uri "https://blog.serverworks.co.jp/1" |Select Sta ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest]、WebExce ption + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
try catchなどでエラー処理を組み込んでもいいのですが、ステータスコードの数値を取得するためにそこまで時間をかけるのもどうかと思いますので、curl コマンドを使った方法について調べてみました。
ステータスコードの取得方法(curl)
LinuxやMacなどでは curl コマンドを使用することができますが、Windows10以降はこのコマンドもOS標準コマンドとなっています。 HTTPステータスコードはレスポンスヘッダの中に含まれますので、オプションでヘッダを含むようにします。
c:\>curl -I "https://blog.serverworks.co.jp/" HTTP/1.1 200 OK Server: nginx Date: Fri, 18 Feb 2022 08:33:52 GMT Content-Type: text/html; charset=utf-8 Connection: keep-alive Vary: Accept-Encoding Access-Control-Allow-Origin: * :
余談な話ですが、オプションは大文字と小文字で指定でき、大文字の場合はヘッダ情報のみ、小文字の場合はヘッダ情報+ソースHTMLが出力されるようです。
ここからが本題ですが、Windowsでcurl を使用してHTTPステータスコードだけ出力したい場合は以下のコマンドを使用します。
curl -s -o nul -w "%{http_code}" URL
指定しているオプションを掘り下げると以下の通りとなります。
-s :サイレント出力 -o :出力先指定 -w :フォーマットを指定して表示
ヘッダ情報からの情報取得は ヘッダ情報の一覧を表示する-i の代わりに、特定の内容を指定して出力する -w を使用します。 curlで-w オプションを出力した際に一緒に出力されてしまうHTMLの出力については、-oのオプションを指定してNULLデバイスにリダイレクトします。
LinuxやMacの場合は /dev/null になりますので、コマンドはこのようになります。
curl -s -I -o /dev/null -w "%{http_code}" URL
Windowsでもコマンドとしては /dev/null を指定しても実行はされますが、実は内部的にエラーとなっています。それを確認するために、サイレントオプションを外した結果を見てみましょう。
Windowsに /dev/null のデバイスが存在するはずがないので、「curl: (23) Failure writing output to destination」のエラーが出るのは妥当なところでしょう。Windowsではどのように指定するかというと、Windowsのコマンドプロンプト内のNullデバイスはNULになりますので、以下のように出力先はNULを指定します。
curl -o NUL -w %{http_code} URL
エラーが出なくなくなりましたので、サイレントオプションを元に戻すとHTTPステータスコードだけ出力することができます。存在しないページを指定した場合でも、このコマンドをそのまま使用することができます。
c:\>curl -s -o NUL -w %{http_code} "https://blog.serverworks.co.jp/" 200 c:\>curl -s -o NUL -w %{http_code} "https://blog.serverworks.co.jp/1/" 404
まとめ
余談な話ですが、curl で一緒に出力されてしまうHTMLソースコードの出力先のNULLデバイスを指定する際に、以下のようにコマンドの出力結果すべてリダイレクトさせてしまい、一緒に出力されるHTMLだけでなくHTMLステータスコードも表示されないという初歩的な罠が、今回ハマっていたところです。
c:\>curl -s -w %{http_code} "https://blog.serverworks.co.jp/" > NUL
ワンショットでHTTPステータスコードだけ調べるなら、エラーを無視して出力先を /dev/null のままでもよかったのですが、あまりエラーが出たままコマンドを実行するのもよくないかと思って少し深堀してみることで、Windows特有のクセと対処方法はそんなに難しいものではないということがわかりました。おそらく他の移植されたLinux系コマンドでも、今回と同様に /dev/null の代わりに NUL 指定すればいいのではないかと思います。
どなたかのお役に立てれば幸いです。