Apacheのmod_rewriteによる設定でルートを除外したい-2

http://q.hatena.ne.jp/1377657374
で質問させていただきましたが、終了間近になってしまいましたので再質問致します。
現在、httpd.conf内の<VirtualHost>内にて
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
を指定しているにも関わらず、存在するファイルへのアクセス結果のログを確認すると
RewriteCond: input='/index.php' pattern='!-f' => matched
となり、rewriteされたページが表示されてしまいます。
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
の利用に制限もしくは必要なモジュール等があるのでしょうか?

回答の条件
  • 1人50回まで
  • 登録:2013/09/04 09:43:17
  • 終了:2013/09/04 13:30:15
id:naonaosnf

<VirtualHost>内記載内容
DirectoryIndex index.php
RewriteEngine On
RewriteLog /tmp/rewrite.log
RewriteLogLevel 9
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !/?prg/?
RewriteRule ^.*$ /prg/index.php?name=$1 [L,QSA]

    • ここまで

アクセス結果
~.jp/
~.jp
などのドメイン直下指定のアクセスやファイルが存在する
~.jp/index.php
~.jp/aaa/index.php
にアクセスした場合
RewriteCond: input='/index.php' pattern='!-f' => matched
のようになり、rewriteされたページが表示される。
~.jp/prg/内へのアクセスはログはpattern='!/?prg/?'でnot-matchedになってpass throughとログ出力されております。

ベストアンサー

id:tezcello No.2

tezcello回答回数460ベストアンサー獲得回数692013/09/04 11:49:56

質問者さんの状況が再現できないので、似た様な環境を作って色々とテストしてみました。

バーチャルホストの記述はおよそ以下の様だと思います。

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot "/var/www/html/hatena"
    ServerName hatena.localhost
    ServerAlias www.hatena.localhost
    ErrorLog logs/hatena_error.log
    CustomLog logs/hatena_access.log combined

    RewriteLog logs/rewrite.log
    RewriteLogLevel 9

    <<  ア  >>

    <Directory "/var/www/html/hatena">
      Options FollowSymLinks Indexes
      AllowOverride all

      DirectoryIndex index.php
      <<  イ  >>

    </Directory>
</VirtualHost>

そして、書換ルールの本体部分

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !/?prg/?
    RewriteRule ^.*$ /prg/index.php?name=$1 [L,QSA]

を「ア」「イ」どちらに書くかで状況が変わってくるようです。

質問者さんは「ア」でしょう。
ここに書くと、RewriteCond: input='/index.php' pattern='!-f' => matched となります。
「イ」に書くと RewriteCond: input='/var/www/html/hatena/index.php' pattern='!-f' => not-matched となります。
(.htaccess も「イ」と同じ)

ここからは推測ですが、「RewriteCond %{REQUEST_FILENAME} !-f」はフルパスで判断しているのでしょう。
なのに、「ア」だとカレントディレクトリが不明なために %{REQUEST_FILENAME} そのものがフルパスと判断されてしまうのだろうと思います。

という事で、「ア」ではなく、「イ」あるいは .htaccess にルール本体を記述すべきだと思います。

他1件のコメントを見る
id:naonaosnf

追加のコメントまでありがとうございます。
正式に設定する内容としては(abc、defフォルダは存在しない)
 .jp/abc/
 .jp/abc/index.php
にアクセスされたものは
 .jp/prg/index.php?name=abc
にrewriteされ
 .jp/abc/mb.php
 .jp/abc/sp.php
にアクセスされたものは、それぞれ
 .jp/prg/mb.php?name=abc
 .jp/prg/sp.php?name=abc
にrewriteされるように設定する予定です。(存在しないdefフォルダの場合もabcと同様のrewrite)
プログラムの中で(存在しない)フォルダ名を引数として受け取り、その名前に応じた結果画面を表示するように検討しています。
コメントいただいた内容を参考に最終的な設定内容を作成していきたいと思います。
(おそらくいただいたコメントでいうdef.phpの設定の上にも-fのRewriteCond設定がいるのかと思ってます。)

ありがとうございました!!

2013/09/04 16:45:56
id:tezcello

mod_Rewrite の正規表現はそれほど複雑な事が出来なかったと思うので、予定されているのを全部 mod_Rewrite だけでやろうとはしないのが吉と考えます。

現時点で判っている、あるいは固定のアクセスは mod_Rewrite でやって、それ以外は index.php の方でやるのが自由度が高いと思います。

例えば、
RewriteEngine on
RewriteRule ^.*/def\.php$ prg/def.php [L,QSA]
# exists_dir は後で削除する予定の(現時点では実在する)ディレクトリ
RewriteRule ^exists_dir/.*$ prg/index.php?name=exists_dir [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|ico|gif|jpg|png|css|html|xml|js)$ prg/index.php [L,QSA]

のようにして(特定の拡張子以外は全て prg/index.php に書換)
prg/index.php 内で $_SERVER['REQUEST_URI'] を preg_match() 等で調べて
必要なプログラム本体を include する

ってのは如何でしょうか?
Cookie(SESSION でも)をデフォルトで使うとディレクトリの問題(ほとんど全てのアクセスを書き換えるので呼出し時のディレクトリを忘れやすいとか、呼出しのディレクトリ以外でも Cookie を使いたくなるとか)があるかもしれませんのでご注意を。
  (有効範囲を適宜設定する事で回避可能だと思います)


何れにしても mod_Rewrite は奥が深いので色々とテストが必要ですね。
頑張ってください。

2013/09/04 17:49:13

その他の回答(1件)

id:windofjuly No.1

うぃんど回答回数2625ベストアンサー獲得回数11492013/09/04 11:28:33

id:naonaosnf

情報ありがとうございます。
参考にいたします。

2013/09/04 13:27:00
id:tezcello No.2

tezcello回答回数460ベストアンサー獲得回数692013/09/04 11:49:56ここでベストアンサー

質問者さんの状況が再現できないので、似た様な環境を作って色々とテストしてみました。

バーチャルホストの記述はおよそ以下の様だと思います。

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot "/var/www/html/hatena"
    ServerName hatena.localhost
    ServerAlias www.hatena.localhost
    ErrorLog logs/hatena_error.log
    CustomLog logs/hatena_access.log combined

    RewriteLog logs/rewrite.log
    RewriteLogLevel 9

    <<  ア  >>

    <Directory "/var/www/html/hatena">
      Options FollowSymLinks Indexes
      AllowOverride all

      DirectoryIndex index.php
      <<  イ  >>

    </Directory>
</VirtualHost>

そして、書換ルールの本体部分

    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !/?prg/?
    RewriteRule ^.*$ /prg/index.php?name=$1 [L,QSA]

を「ア」「イ」どちらに書くかで状況が変わってくるようです。

質問者さんは「ア」でしょう。
ここに書くと、RewriteCond: input='/index.php' pattern='!-f' => matched となります。
「イ」に書くと RewriteCond: input='/var/www/html/hatena/index.php' pattern='!-f' => not-matched となります。
(.htaccess も「イ」と同じ)

ここからは推測ですが、「RewriteCond %{REQUEST_FILENAME} !-f」はフルパスで判断しているのでしょう。
なのに、「ア」だとカレントディレクトリが不明なために %{REQUEST_FILENAME} そのものがフルパスと判断されてしまうのだろうと思います。

という事で、「ア」ではなく、「イ」あるいは .htaccess にルール本体を記述すべきだと思います。

他1件のコメントを見る
id:naonaosnf

追加のコメントまでありがとうございます。
正式に設定する内容としては(abc、defフォルダは存在しない)
 .jp/abc/
 .jp/abc/index.php
にアクセスされたものは
 .jp/prg/index.php?name=abc
にrewriteされ
 .jp/abc/mb.php
 .jp/abc/sp.php
にアクセスされたものは、それぞれ
 .jp/prg/mb.php?name=abc
 .jp/prg/sp.php?name=abc
にrewriteされるように設定する予定です。(存在しないdefフォルダの場合もabcと同様のrewrite)
プログラムの中で(存在しない)フォルダ名を引数として受け取り、その名前に応じた結果画面を表示するように検討しています。
コメントいただいた内容を参考に最終的な設定内容を作成していきたいと思います。
(おそらくいただいたコメントでいうdef.phpの設定の上にも-fのRewriteCond設定がいるのかと思ってます。)

ありがとうございました!!

2013/09/04 16:45:56
id:tezcello

mod_Rewrite の正規表現はそれほど複雑な事が出来なかったと思うので、予定されているのを全部 mod_Rewrite だけでやろうとはしないのが吉と考えます。

現時点で判っている、あるいは固定のアクセスは mod_Rewrite でやって、それ以外は index.php の方でやるのが自由度が高いと思います。

例えば、
RewriteEngine on
RewriteRule ^.*/def\.php$ prg/def.php [L,QSA]
# exists_dir は後で削除する予定の(現時点では実在する)ディレクトリ
RewriteRule ^exists_dir/.*$ prg/index.php?name=exists_dir [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule !\.(pdf|ico|gif|jpg|png|css|html|xml|js)$ prg/index.php [L,QSA]

のようにして(特定の拡張子以外は全て prg/index.php に書換)
prg/index.php 内で $_SERVER['REQUEST_URI'] を preg_match() 等で調べて
必要なプログラム本体を include する

ってのは如何でしょうか?
Cookie(SESSION でも)をデフォルトで使うとディレクトリの問題(ほとんど全てのアクセスを書き換えるので呼出し時のディレクトリを忘れやすいとか、呼出しのディレクトリ以外でも Cookie を使いたくなるとか)があるかもしれませんのでご注意を。
  (有効範囲を適宜設定する事で回避可能だと思います)


何れにしても mod_Rewrite は奥が深いので色々とテストが必要ですね。
頑張ってください。

2013/09/04 17:49:13

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません