Apacheのエラーレスポンスをちょっと工夫して書く方法をご紹介します。
Apacheでは、サーバでエラーが発生した場合に表示されるレスポンス(以下、エラーレスポンス)をカスタマイズする手段が提供されています。たとえば、ユーザが存在しないURLを指定したり、デッドリンクをたどって来た場合などに表示される"404 Not Found"というメッセージは、エラーレスポンスの1つです。
Apacheでは、ユーザがカスタマイズしたエラーレスポンスを「カスタムエラーレスポンス」と呼んでいます。カスタムエラーレスポンスの提供手段としては、以下の3つが用意されています:
これら、カスタムエラーレスポンスの設定方法については、apache.orgのカスタムエラーレスポンスに関するドキュメントが参考になります。
しかし、apache.orgのドキュメントだけでは、実際に設定するのに有用そうな情報が得られませんでした。そこで、ここでは、motchie.comで採用している方法をご紹介します。
ここでご紹介する設定を使うと、以下のような機能を備えたエラーレスポンスを生成できます:
以下に、ここでご紹介した機能を用いたエラーレスポンスの例を示します:
図1: 英語を使用するビジター用のエラーレスポンス
図2: 日本語を使用するビジター用のエラーレスポンス
以下に、"404 Not Found"を例に手順をご紹介します。まず、DocumentRoot(public_htmlなど)となるディレクトリに、.htaccessファイルを作成し、以下のディレクティブを追加します(既にDocumentRootに.htaccessファイルがある場合は以下の記述を追加します。また、ファイル名はApacheの管理者の設定により.htaccessではない場合があります)。
ErrorDocument 404 /errordocs/404.shtml
ここで、/errordocs/404.shtml というのは、エラーレスポンスを記述する.shtmlファイルへのパスです。パスは、DocumentRootからの相対パスで指定します。例えば、この指定がmotchie.comのものだったとしたら、http://www.motchie.com/errordocs/404.shtmlというURLでブラウザからアクセス可能になるようなパス、ということになります。
また、今回ご紹介するエラーレスポンスは、SSI ( Server Side Include )を用いているので、少なくとも /errordocs ディレクトリでSSIが有効になる必要があります。また、SSIの解析対象となる拡張子が、.shtmlではない場合も考えられます。
エラーの元になったURLは、SSI用の環境変数と、カスタムエラーレスポンス用の環境変数から取得することができます。
まず、エラーの元になったURLのうちサーバのFQDNの部分については、SSIのSERVER_NAME環境変数で取得することができます。また、パス名の部分はカスタムエラーレスポンス用のREDIRECT_URL環境変数から取得することができます。また、スキーム名の部分は自分で書く必要があります。
以上より、例えば、「http://www.motchie.com/foo/は存在しないURLです。」と出力しようとすると、
http://<!-- #echo var="SERVER_NAME" --><!-- #echo var="REDIRECT_URL" -->は存在しないURLです。
実は、このトピックスに関しては、apache.orgに"Using XSSI and ErrorDocument to configure customized international server error responses"があり、以下でご紹介するよりも高機能だと思われますが、ここでは簡易版ともいえる方法をご紹介しています(簡易版とは言いながら、以下でご紹介する機能は、"MultiViews"ディレクティブが無効だったり、type-mapハンドラが用意されていなくても動くという利点があります)。
ブラウザは一般に、閲覧したい言語を指定することができます。

図3: Internet Explorer5.5で使用する言語を指定するダイアログ

図4: Netscape Communicatorで使用する言語を指定するダイアログ

図5: Netscape 6で使用する言語を指定するダイアログ
ここで設定した内容は、ブラウザがWebサイトに接続する際に、Webサイト側にACCEPT_LANGUAGE環境変数として渡されます。例えば、ブラウザで日本語を優先順位で1番、次に英語を指定すると、Webサイト側にはACCEPT_LANGUAGE環境変数の内容として"ja,en"が渡されます。
SSIでこの環境変数を受け取り、さらにその内容がjaから始まっている場合は日本語のエラーレスポンスを、それ以外は英語のエラーレスポンスを返すようにするには、Apacheに備わっているSSIベースの条件分岐を用います。
SSIベースの条件分岐については、やはりapache.orgのmod_includeモジュールに関するドキュメントが参考になります。
今までのことから、ACCEPT_LANGUAGE環境変数の内容による条件分岐は以下のようになります:
<!--#if expr="$HTTP_ACCEPT_LANGUAGE = /^ja,*/" -->
<p>日本語のメッセージ</p>
<!--#else -->
<p>Messages in English.</p>
<!--#endif -->
結果的に、作成するカスタムエラーレスポンス用の.shtmlファイルは、以下のようになります。
<html>
<head><title>404 Not Found.</title></head>
<body><h1>404 Not Found.</h1>
<!--#if expr="$HTTP_ACCEPT_LANGUAGE = /^ja,*/" -->
<p>要求されたページ:
http://<!--#echo var="SERVER_NAME" --><!--#echo var="REDIRECT_URL" -->
は見つかりません。</p>
<!--#else -->
<p>The URL path in your request:
http://<!--#echo var="SERVER_NAME" --><!--#echo var="REDIRECT_URL" -->
doesn't match anything we have available.</p>
<!--#endif -->
</body></html>
このページの内容は、完全に無保証です。全ての環境において、この記事の内容が正しいことを保証するものでもありません。また、この記事の内容について、みなさまがどのような損害/不利益を被られても、私はそれらに対して何らの賠償などを行うものでもありません。しかし、これらの記事についての訂正、質問、苦情、その他ご意見は歓迎いたします。それらに対しては、ぼくのできる範囲で対応させていただきたいと思います。