Apacheの404用ページが全然ステータスコード404を返していなかった | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

存在しないページへアクセスした際に表示する404ページをカスタマイズしているサイトはよくありますが、自分が担当するサイトでも同様にうまく設定していたはずのこの Not Found用のページが全然HTTPステータスコードとして404を返していないということがありました。

しかも、何故か大量にカスタマイズをした404ページへのアクセスログが出てたり。


A Day In The Boy's Life-Apache404error-1


上記のように、存在しないページ(/test)にアクセスした際に返されるHTTPステータスが302(Found)に、そしてカスタム404エラー用のmissing.htmlページが、ステータスコード200で返ってきています。

想定していた動作としては、/testのHTTPステータスコードが404で返ってくるというものです。



ApacheのErrorDocumentの設定を見直す


結論から言えば、ApacheのErrorDocumentの設定が誤っていました。

というか、設定ファイルの書き方次第で挙動が大きく異なります。


ErrorDocument 404 http://www.example.com/missing.html


上記のように、URLとしてエラードキュメントのパスを指定すると、該当のURLへ”転送”されます

正しくは、下記のように相対パスで指定します。


ErrorDocument 404 /missing.html

これで、再度アクセスしてみると・・・。


A Day In The Boy's Life-Apache404error-2


きっちり、404が返ってきています。

また、先ほどはURLバーに表示されているのが、missing.htmlでページが転送されていますが、今回は/testでユーザーがアクセスしたURLがそのまま表示されています。


設定したはずなのに、なんで404が返ってこないんだろうと少しはまってたのですが、Apacheのドキュメント を読めばちゃんと書いていました。


リモート URL (例えば、頭に http と付与した方法) を ErrorDocument に指定するとき、 たとえ文書が同じサーバにあろうとも、ドキュメントがどこにあるかを通知するために、 Apache はリダイレクトをクライアントに送出するということに、注意してください。 これにはいろいろと関連して起こる問題があります。 中でも最も重要なのは、クライアントは元々のエラーステータスコードを受け取らず、 代わりにリダイレクトのステータスコードを受け取るということです。 これにより、ステータスコードを使って URL が有効であるかどうかを決定しようとする ウェブロボットやその他クライアントを、混乱させるかもしれません。


書いてある通り、自分が混乱をしてしまっていたわけですが。

大量のカスタム404ページ(missing.html)がログに出ていた理由は、上記の設定の誤りから404ページへ転送されて正常なページアクセスと変わらないリクエストの状態となり、Apacheのアクセスログに出ていたわけですね。

ちなみに、404が大量に発生していた理由は、faviconによるものです。

これは余談ですが、以下のように設定すれば、faviconの404エラー出力を抑制することができます。

Redirect 404 /favicon.ico