• 締切済み

mod_rewrite 環境変数への参照

mod_rewriteで、RewriteCondディレクティブの条件パターンから環境変数を参照する方法は、無いものでしょうか…。 具体的には、たとえばよくある「直リンク禁止」がありますよね。 RewriteCond %{HTTP_REFERER} !^https?://([^/]+\.)?hogehoge.com/ [NC] …(拒否指定) という感じに書きますが、この「hogehoge.com」の部分を、いちいちバーチャルホストごとに書き換えなくていいとか、もっと言えばグローバル設定に1回だけ設定すれば良いようにすべく、 RewriteCond %{HTTP_REFERER} !^https?://([^/]+\.)?%{SERVER_NAME}/ [NC] …(拒否指定) と書きたいわけです。 しかしパターンの中で%{SERVER_NAME}が展開されないようで、後方参照はどうかとためしに RewriteCond %{SERVER_NAME} ^(.+)$ RewriteCond %{SERVER_NAME} ^$1$ としても2つ目はnot-matchedが返されます。環境変数も参照変数も展開されない?… ダメモトで RewriteCond %{SERVER_NAME} ^(.+)$ RewriteCond %{SERVER_NAME} ^%1$ でも同様でした(%1という書き方はテスト文字列のほうだと、解ってはいます…)。 RewriteRuleのほうだけが後方参照できるというのも中途半端な気がして、何か方法があるのではと探しています。 どなたか御存じないでしょうか。 それとも仕様なのでしょうか。

みんなの回答

回答No.3

仕様のようですね。。 URLをご提示いただいたマニュアルを読むと、 RewriteCond ディレクティブの構文は、 Syntax: RewriteCond TestString CondPattern となっています。 CondPattern に指定する条件は、どのように書けるのかとみると、 Remember: CondPattern is a perl compatible regular expression with some additions: と記述されています。 PCRE (Perl5互換の正規表現) とあとは、some additions (その下の説明 1, 2, 3 )が使える、ということでしょうか。 TestString の説明には、 Server-Variables (サーバ環境変数)を参照できると書かれていますが、 CondPattern の説明には、そのような記述はありません。

SV576
質問者

お礼

ご回答ありがとうございます。 やはり仕様みたいですねぇ…。 何とも納得いかないのが、PCREと言っておきながら、後方参照が正規表現から変数取得できないなんて…、むしろ逆に、なぜわざわざそんな変な仕様にしたんだろう。 参照できれば、あらゆる場面で相当便利になるし、mod_rewrite自体がさらに強力になると思うんですがね、将来バージョンで改善されるんでしょうか。 ま、そんなこと考えててもしょうがなさそうなので、とりあえず解決策を考えました。 RewriteMap を使う方法もありますが、もっと手っ取り早く簡単に、しかも柔軟かつ強力な方法ということで、RewriteCondのチェック部分だけmod_perlを使うことにしました。 単に、環境変数のチェックだけをmod_perlにやらせて、その結果をmod_rewriteに渡す、という極めて単純な方法です。かつ、これなら柔軟な対応も可能だと思います。 同じ問題で悩んでいる人がいたら、この方法をお勧めします。 特に注意点もありませんが、強いて言えば、変換フェーズのmod_rewriteが動く前にmod_perlスクリプトが動くようにさえしておけば、後は問題ないです。

回答No.2

どちらかというと、 「RewriteCondディレクティブの条件パターンから環境変数を参照する方法」 というよりも、 「設定ファイルの中で、環境変数を設定する方法」 を求めておられるような気がするのですが。 Apacheにmod_envモジュールが組み込まれていれば、 SetEnv ディレクティブによって、httpd.conf や .htaccess で、 環境変数を設定することができます。 シェルからの環境変数を渡す PassEnv ディレクティブもありますが、 いずれにせよ、設定した環境偏すをCGIやSSIに渡してしまうので、 注意が必要です。

参考URL:
http://httpd.apache.org/docs/2.0/ja/mod/mod_env.html#setenv
SV576
質問者

補足

ご回答ありがとうございます。 > 「設定ファイルの中で、環境変数を設定する方法」 > を求めておられるような気がするのですが。 いえ、あくまでも、質問文に書いたようにRewriteCondのパターンの中、つまり右側です。 もちろんmod_envはロードしているので、実際のところ他の箇所では環境変数は問題なく取得できています。 それに、たとえば RewriteCond %{SERVER_NAME} ~ と書けば、ログを見るとちゃんと%{SERVER_NAME}の部分は RewriteCond: input='hogehoge.com' とホスト名が取得できています。 問題は、パターンの中から参照できないのです。 どうも、これは仕様なので不可能…なのかな?という気がしてきました…。 しかしマニュアルにはそのようなことは書いていない(同時に、環境変数が参照できるとも書いていないけど)。 需要はありそうなんですけどねぇ。 参考↓ http://httpd.apache.org/docs/2.0/ja/mod/mod_rewrite.html

  • kalze
  • ベストアンサー率47% (522/1092)
回答No.1

アクセスURLのホスト部分を参照したいなら、 %{HTTP_HOST} で良いのでは?とおもいますが、要求を満たしませんか?

SV576
質問者

補足

早速のご回答ありがとうございます。 > アクセスURLのホスト部分を参照したいなら、 いえいえ、そうじゃなくて^^; 質問文に書いたように、RewriteCondディレクティブの条件パターンから環境変数を参照する方法を探してるんです。 たとえば%{HTTP_HOST}でたとえるなら、 RewriteCond %{HTTP_HOST} ^(.+)$ [NC] RewriteCond %1 ^%{HTTP_HOST}$ [NC] この2番目でnot-matchedが返ってしまうんです。つまり取得できないわけです。

関連するQ&A