UNIX的なアレ:gihyo.jp出張所

第15回知っておきたいApacheの基礎知識 その11

mod_rewriteの記事ももう3回目になります。なかなか慣れるまではクセのあるモジュールですが、非常に便利なモジュールであることは認識していただけているかと思います。

さて、前回では正規表現を利用したURLの書き換えを実践してきました。今回はよりmod_rewriteを使いこなしていきましょう。

rewrite_ruleの適用条件を指定する

1つのURL書き換えを行うときはあまり気になりませんが、複数のアプリケーションをハンドリングしようとなってくると条件を指定したくなるものです。そこで、RewriteCondというディレクティブを使用しましょう。⁠○○という条件のときは、RewriteRuleを適用する」といったif文のような記述をすることができます。

それではhttpd.confのVirtualHostの内容を以下のものに変更をしてみましょう。

<VirtualHost *:80>
    DocumentRoot /usr/local/apache2/htdocs
    ServerName www.example.com
    ErrorLog /usr/local/apache2/error_log
    CustomLog /usr/local/apache2/access_log combined

    ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"

    RewriteEngine on
    RewriteLogLevel 9
    RewriteLog  /tmp/rewrite.log

    RewriteCond  %{HTTP_USER_AGENT}  Firefox
    RewriteRule  ^/$                 /firefox.html  [L]

    RewriteCond  %{HTTP_USER_AGENT}  MSIE
    RewriteRule  ^/$                 /ie.html  [L]

</VirtualHost>

さて、上記の設定ができましたらDocumentRootにファイルを設置しましょう。

$ echo "I am firefox" | sudo tee /usr/local/apache2/htdocs/firefox.html
$ echo "I am Internet Explorer" | sudo tee /usr/local/apache2/htdocs/ie.html

ファイルが設置できたら、Firefox、Internet Explolerでそれぞれアクセスしてみてください。それぞれのブラウザで、⁠I am fireflx⁠⁠I am Internet Explorer⁠と表示されれば成功です。これはUserAgentを見てそれぞれ適用させるRewriteRuleを変えている例です。

さて、それではディレクティブを詳しく見ていきましょう。

まずはRewriteCondという部分に注目してください。RewriteCondはif文のようなもので、以降につづくRewriteRuleを適用するかどうかを判定するためのものです。 構文としては以下のとおりです。

RewriteCond 判定の対象 判定パターン [オプション]

上記の例を当てはめますと、UserAgentの情報を環境変数からとってきて、FirefoxやIEにマッチさせています。その結果、それぞれ当てはめているRewriteRuleを分岐させ、書き換え先のHTMLファイルを変更しています。

その他にもApacheで使うことのできる環境変数は、cgi-binの配下にあるprintenvというCGIを実行することで確認できます。

なお、このprintenvを使う際は、実行権限を設定することとPerlのpathがあっているかどうかを注意してください。

rewrite_mapでURLのマッピングを行う

URLの書き換えを行う際、独自のマッピング情報によって書き換えを行いたい場合はあることでしょう。URL上では意味のある文字列を使用したいが、アプリケーションのデータ上はID管理をされているようなケースです。

いままでのテクニックで実装するなら、RewriteRuleで実現することが可能です。ただし、マッピング情報が変更されるたびにhttpd.confを修正したりapacheの再起動がはいることは現実的ではありません。

そこでrewrite_mapという機能を使うことでrewrite_ruleの適用時に書き換えのマッピング情報を与えることができます図1⁠。

図1 rewrite_mapによるマッピング例
図1 rewrite_mapによるマッピング例

それでは設定ファイルを見ていきましょう。なお、確認用に前回使用したCGIを使いますので準備しておいてください。

<VirtualHost *:80>
    DocumentRoot /usr/local/apache2/htdocs
    ServerName www.example.com
    ErrorLog /usr/local/apache2/error_log
    CustomLog /usr/local/apache2/access_log combined

    ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"

    RewriteEngine on
    RewriteLogLevel 9
    RewriteLog  /tmp/rewrite.log
    RewriteMap mapping txt:/usr/local/apache2/conf/mapping.txt
    RewriteRule ^/(.*)$ /cgi-bin/index.pl?id=${mapping:$1} [PT]

</VirtualHost>

さらにマッピング情報を管理するためのファイルが必要になりますので、作成します。

$ sudo tee /usr/local/apache2/conf/mapping.txt << EOF
SiteA 1
SiteB 2
SiteC 3
EOF

それでは、アクセスしてみましょう。

http://{$servername}/SiteA でアクセスし、id --> 1 と表示されれば成功です!

RewriteMapディレクティブの記述方法

RewriteMap、RewriteRuleのディレクティブにそれぞれ注目してください。RewriteMapディレクティブがとることのできる引数は以下です。

RewriteMap  マッピング名 マッピングファイル(テキスト、DBM形式が選択可能)

RewriteMapディレクティブでマッピング名を指定したら、RewriteRuleディレクティブではそのマッピング名を使って呼び出しましょう。${マッピング名:キー} という形式でキーに対応する値を取得することができます。

サンプルで用意した設定ファイルのように、書き換え後のURLで利用することで、有効活用することができます。

なお、マッピングファイルにはテキスト形式とDBM形式を選択することができます。今回はtxt形式で利用をしていますがDBM形式で利用したい場合も、httxt2dbmという変換用のツールがapacheに同梱されているので簡単に使用することができます。

最後に

さて、全3回にわたり、mod_rewriteについて説明をしてきました。ここで紹介したmod_rewriteの利用方法はまだまだ一部で、工夫次第ではより様々な処理を担当させることができます。しかし、mod_rewriteは便利すぎるため使いすぎには注意してください。 気がつけば誰も触ることができないような設定ファイルができあがってしまうようなこともしばしばあります。ご利用は計画的に。

おすすめ記事

記事・ニュース一覧