• 締切済み

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のほうだけが後方参照できるというのも中途半端な気がして、何か方法があるのではと探しています。 どなたか御存じないでしょうか。 それとも仕様なのでしょうか。

  • SV576
  • お礼率83% (40/48)

みんなの回答

回答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

  • mod_rewriteで直リン防止

    直リン防止のためmod_rewriteを.htaccessで設定してみました。 RewriteEngine On RewriteCond %{HTTP_REFERER} !^http://xxxx\.com/.*$ [NC] RewriteRule ^(.*)$ - [F] この設定で画像は直リン防止できましたが動画は直リン防止が できず、リンクからも読み込めなくなりました。 どうにか動画直リンを防ぐ設定はないでしょうか?

  • mod_rewrite について

    mod_rewrite について お世話になります。php初心者です。 URLのリライトを行いたくて色々調べてみたのですが問題が解消できず質問させて頂きます。 (サブドメインを使用しています) htaccessに下記のように記述しました。 RewriteEngine On RewriteCond %{HTTP_HOST} ^(www\.test\.aaa\.ne\.jp)(:80)? [NC] RewriteRule ^(.*)$ http://test.aaa.ne.jp/$1 [R=301,L] すると、 「http://www.test.aaa.ne.jp」 は、 「http://test.cns.ne.jp」 とならずにエラー画面が表示されます。(エラーコード404) URLの表示方法を換えたいと考えております。 (●●●できたら×××と表示する) それともそもそもの私の捉え方が間違っているのでしょうか。 サブドメインを使用しているからでしょうか。 ご教授頂けると大変ありがたいです。 宜しくお願い申し上げます。

    • 締切済み
    • PHP
  • 画像を直リンクできないようにする

    .htaccessに次の記述を追加 RewriteEngine On RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http://(www\.)?example.com/.*$ [NC} RewriteRule \.(gif\jpg)|png$ - [F] すみません、ここで簡単な質問なのかもしれないのですが、2行目の!^$というのは、どういう意味になるのでしょうか?^が行頭で、$が行末なんですよね・・・。

  • mod_rewriteの初歩的な質問なのですが

    すいません。今データベースを使った簡単なウェブサイトを作っていまして mod_rewriteについて分からないことがあります。 (phpなど勉強を始めたばかりで質問の意味が分かりにくいかもしれません) やりたいことは実際には存在しないhtmlのサイトを検索にスクロールしてもらって クライアントから要求があったアドレスに従いデータベースから任意のデータを表示すると いったものです。 例えば 1000.html 1001.html 1002.html・・・・・に要求があった場合phpの$_SERVER['HTTP_HOST']を 使って要求のあったアドレスを抜き取り任意のhtmlを表示させるといった事を考えています。 リダイレクト自体は初心者向けのサイトを見て簡単にできたのですが、 1000.html 1001.html 1002.html・・・ の部分を一度に表記する方法はないでしょうか。(1000.html~5000.htmlのようなこの範囲を全て条件としてRewriteCondに入れたい) 最終的には5000ページ程度を考えているため一つ一つ記載するのは難しいです。 RewriteEngine on RewriteCond %{HTTP_HOST} ^(1001\.html)(:80)? [NC] RewriteRule ^(.*) http://abcdefg.com/$1 [R=301,L]

  • apacheのmod_rewriteモジュール

    WebサーバにてHTTP TRACEメソッドが有効になっている場合の処置として、いろいろなページを見てるとhttpd.confに次のように記述するとありますが RewriteEngine On RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) RewriteRule .* - [F] 2行目と3行目の意味を教えてください。 特に2行目については、TRACKメソッドを指定しているようですが、TRACKメソッドとは如何なるものでしょうか?

  • Apacheのmod_rewriteに関してお

    Apacheのmod_rewriteに関してお教えください。 お世話になります。 色々なサイトを参考に試していますが、思う様にいかず困っています。 知恵をお借り頂けたらと存じます。 ・「mod_rewrite」を利用したメンテナンス画面の表示。 ・「F5」等で更新した際、本来の画面が表示される様、内部的な置き換えのみとしたい。 ・使用しているWebサーバは(Apache2.2系) ・「mod_proxy_ajp」を利用したコネクタ連携を行っている。 ・ホスト名によるバーチャルホスト ・configファイルに記載する方法で試し中 ・メンテ用html メンテナンス用htmlは、別途指定した「DocumentRoot」に配備しており、 同ディレクトリにイメージファイル格納用フォルダがある。 そのフォルダ内にimgファイルが配備されている。(pngファイル等) DocumentRoot Lhtmlファイル L格納フォルダ\イメージファイル 現在、Apacheの機能に関して勉強中です。 メンテナンス用画面表示用として、例えば色々なサイトに有るような、以下記載をしたとします。 --------- RewriteCond %{REQUEST_FILENAME} !(/メンテナンス画面.html|.*\.(gif|jpe?g|png|js|css|ico))$ RewriteRule ^(.*)$ /メンテナンス画面.html [R=503,P,L] --------- 「http://ホストIP/」等でアクセスした場合、ドキュメントルートを参照、意図した動きとなるのですが、 「http://ホストIP/^ユーザディレクトリ/」や、「http://ホストIP/Aliasディレクトリ/」等 一階層深いURLだった場合、メンテ用htmlは、表示されるのですが、参照イメージファイルがパス違いにより 参照出来なくなり、意図した動きとなりません。 ※ 「http://ホストIP%{REQUEST_URI}」配下を参照しようとしている。(RewriteLogより) 「RewriteRule ^(.*)$」だと全てになってしまう為、ルールを分け設定してみましたが 第3引数の指定が悪いのか設定した「RewriteRule」を全て参照し「RewriteCond」が動いてしまう。 引数や正規表現の問題だとは考えておりますが、なかなか正解に辿り着けません。 よろしくお願いします。

  • .htaccess の書き方

    以下の .htaccess では、http://hoge.jp への携帯からのアクセスを http://hoge.jp/mobile ディレクトリへ転送させていますが、これを、 http://m.hoge.jp へ転送するには、どう記述を変えれば良いのでしょうか? ちなみに、使用予定のレンタルサーバでは、サブドメインつきのリクエストで 所定のディレクトリへアクセスさせるには、自分で .htaccess を書く必要が あるとのことです。(設定画面で設定できません) PC・携帯からのhttp://hoge.jp へのアクセスを、それぞれ PC: http://www.hoge.jp (/www/) 携帯: http://m.hoge.jp (/m/) という具合に振分転送させたいのですが・・・。 -------------------------------------- #携帯振り分け Options +FollowSymLinks RewriteEngine on RewriteBase / RewriteCond %{REQUEST_URI} !^/mobile RewriteCond %{HTTP_USER_AGENT} DoCoMo [NC,OR] RewriteCond %{HTTP_USER_AGENT} (J-PHONE|Vodafone|Softbank|MOT-) [NC,OR] RewriteCond %{HTTP_USER_AGENT} (KDDI|UP\.Browser) [NC,OR] RewriteCond %{HTTP_USER_AGENT} (PDXGW|DDIPOKET|WILLCOM) [NC,OR] RewriteCond %{HTTP_USER_AGENT} ASTEL [NC,OR] RewriteCond %{HTTP_USER_AGENT} L-mode [NC] RewriteRule ^(.*)$ /mobile/$1 [R,L] #「www」ありに統一 RewriteCond %{HTTP_HOST} ^(hoge\.jp)(:80)? [NC] RewriteRule ^(.*)$ http://www.hoge.jp/$1 [R=301,L]

  • 特定サイトからのアクセス制限。

    通常のサイトからリンクされていたら、拒否することはわかりますが、 以下の場合はどおでしょうか。 そのサイトが例えば、ページの文法チェック等するサイト、 cgiでチェックしていると思いますが、 それで私のサイトの文法チェックも拒否したいです。 RewriteEngine On RewriteCond %{HTTP_REFERER} ^http(s)?://(www\.)?htmllint.net [NC] RewriteRule ^.*$ - [NC,F,L] このようなチェックでは、見れてしまいます。 どのようにしたらこのようなサイトも制限をかけれるでしょうか 宜しくお願いいたします

    • ベストアンサー
    • HTML
  • mod_rewrite 動的ページを静的ページへ

    SEO対策として、動的ページを静的ページへリダイレクトさせたいと考えています。 レンタルサーバーのため、.htaccessへ記入するしか方法はないと思っているのですが、 そもそも「静的化するってこと自体」がよく分かってないので、教えてください。 <現状> ▼URL /hoge/index.php?id=1 ▼.htaccess RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([0-9A-Za-z]+)\.html$ details.php?id=$1 [L] <結果> 実行すると、/hoge/1.htmlとなり、望む結果を得られるのですが、 念のためディレクトリを指定しておきたいと思い、 RewriteRule ^/hoge/([0-9A-Za-z]+)\.html$ /hoge/details.php?id=$1 [L] としたところ、全く静的表示されなくなりました。 ■質問1 なぜ、ディレクトリを指定すると静的化できないのでしょうか? ■質問2 ネットでmod_rewriteの解説ページを検索してみると、静的化の例として、 「hoge/1.html へアクセスがあった際に、index.php?id=1の結果を返す」、 と記載されてます。 「index.php?id=1へアクセスした際に、hoge/1.html の結果を返す」 ようにした方がいいと思うのですが、 これって結果的には同じことをしている、と考えてよいのでしょうか? ■質問3 例えば、「/hoge/index.php?id=1」に対して、 「index.php?id=1へアクセスした際に、hoge/1.html の結果を返す」 ようにするには、どう書けばよいのでしょうか?

    • ベストアンサー
    • PHP
  • mod_rewriteについて

    初めて質問させていただきます。 よろしくお願いします。 Solaris8にてApacheを動かしています。 【問題】「HTTP TRACE」を拒否するためにmod_rewriteモジュールをインストールしようと思うのですがうまくいきません。 【詳細】mod_rewriteをインストールするとmod_soが消えてしまい、mod_soを入れなおすとmod_rewriteが消えてしまいます。  ./configure --enable-module=so --enable-module=rewrite とすると両方が入るみたいなんですが、 /usr/local/apache/bin/apachectl startssl としても、  Syntax error on line 206 of /usr/local/apache/conf/httpd.conf: Cannot load /usr/local/apache/libexec/libssl.so into server: ld.so.1: /usr/local/apache/bin/httpd: 重大なエラー: 再配置エラー: ファイル /usr/local/apache/libexec/libssl.so: シンボル ap_global_ctx: 参照シンボルが見つかりません。 /usr/local/apache/bin/apachectl startssl: httpd could not be started と、こんなエラーが出てhttpdがスタートできません。 どこに原因があるためのエラーなのでしょうか??