mod_rewriteを使う場合、URLに「%2F」が含まれるとApacheの設定によっては思い通りに動作しない可能性があります。

mod_rewriteについては第15回のメーリングリストを参照していただくとして、まずは以下のようなURLを考えてみましょう。

http://example.com/search/keyword%2Fkeyword

ここでは、以下のようなルールで変換を行うとします。

RewriteEngine On
RewriteRule \/search\/(.+)$ /search.php?q=$1 [L]

また、search.phpはmod_rewriteの動作確認用に、以下のような簡単なコードを使用するとします。

<?php
echo $_GET['q'];
?>

先ほどのURLにアクセスした場合、search.phpを呼び出して「keyword%2Fkeyword」のデコード結果を出力することが期待されます。

しかし、実際にアクセスしてみると404エラーが発生してしまいます。しかし、エンコードを行っていない状態の「/」を含んだ、http//example.com/search/keyword/keywordというURLでアクセスしてみると、今度はうまくいくはずです。

なぜこのような問題が起きるかというと、ApacheではURLにパスの分離文字である「/」をURLエンコードした「%2F」が含まれると404エラーで拒否してしまうからです。

なお、GETの値として「%2F」が含まれる場合は、問題なくアクセスすることができます(http://example.com/search.php?q=keyword%2Fkeyword)。

Apacheの設定を変更することで、404エラーを発生させずに、mod_rewriteの処理エンジンを実行することができます。

しかし、2.0.46以降でないと設定用のディレクティブが存在しないので注意が必要です。

2.0.46より古いバージョンの場合は、アプリケーション側で変数のエンコード後に「%2F」のみさらに置換するなどの工夫が必要になるでしょう。実際には、以下のようにApacheの設定ファイル (httpd.conf等)でAllowEncodedSlashesディレクティブをOnにします。

AllowEncodedSlashes On

こうすることで、「%2F」が含まれるURLにアクセスしてもmod_rewriteの条件判定が行われ、期待されるファイルが実行されます。なお、「%2F」が含まれるURLにアクセスできないという問題は、PATH_INFOを使用する場合でも同様に起こります。

こちらについてもAllowEncodeSlashesディレクティブをOnにすれば問題なく動作させることができます。

この問題は意外と知られていないかもしれませんが、一旦はまると中々抜け出せなくなるので注意が必要です。