QA@IT

【Apache 2.4】サーバ設定ファイルに記述したRewriteRuleが動かない

14423 PV

CentOS 6.4 上で、Apache 2.4.6 を利用しています。

最終的にやりたいことは、拡張子無しのURIでアクセスできるようにし、拡張子付きのURIを拡張子無しのURIにリダイレクトさせることです。

最初はmod_negotiationモジュールのMultiViewsオプションを利用していました。しかしRedirectMatchディレクティブなどとの相性が悪いようで、MultiViewsオプションの本来の目的からも外れるので、mod_rewriteモジュールを利用することにしました。

RewriteRuleディレクティブの第2引数を、ファイルシステムの絶対パスとして扱わせたい([PT|passthrough]フラグが付加されないようにしたい)ので、 サーバ設定ファイル コンテキストに記述しました。以下のように/etc/httpd/conf/extra/httpd-vhosts.confに追記しているのですが、動作しません(mod_rewriteのログが何も出力されません)。RewriteRuleディレクティブを<Directory>セクション内に入れると動作します。

RewriteEngine on
LogLevel alert rewrite:trace8
RewriteMap adjust-extension "prg:/usr/bin/perl -e '$| = 1; while (<STDIN>) { chomp($_); @file = glob($_ . \".*\");     open(OUT, \"> /tmp/rewrite_log\"); print OUT \"$_ -> @file[0]\\\\n\"; close(OUT);     print((@file[0] || $_) . \"\\\\n\"); }'"
RewriteRule ^(/var/www/[^/]+/polyfill/.+)$ $1
RewriteRule ^(/var/www/[^.]+)$ ${adjust-extension:$1}

RewriteRuleディレクティブを サーバ設定ファイル コンテキストで動かすには、どうすれば良いのでしょうか。


【2013-10-12追記】

教えていただいた内容をもとに修正した設定ファイルを追記しておきます。

<VirtualHost *:80>
    ServerName default-virtual-host.invalid
    Redirect permanent / http://example.jp/
</VirtualHost>
<VirtualHost *:80>
    ServerName example.jp
    DocumentRoot /var/www/html
    RewriteOptions inherit
</VirtualHost>
<VirtualHost *:80>
    ServerName subdomain.example.jp
    DocumentRoot /var/www/subdomain
    RewriteOptions inherit
    <Directory /var/www/share/subdomain/core>
        Require all granted
    </Directory>
</VirtualHost>

RewriteEngine on
# 拡張子無しのファイルシステムの絶対パスから、拡張子付きのファイルを探し、最初に見つかったファイルのパスを返す。ファイルが見つからなければそのまま返す
RewriteMap adjust-extension "prg:/usr/bin/perl -e '$| = 1; while (<STDIN>) { chomp($_); @file = glob($_ . \\'.*\\'); print((@file[0] || $_) . \"\\\\n\"); }'"
# Alias /polyfill/ /var/www/common/polyfill/ の代替
RewriteRule ^/(polyfill/[^.]+)$ /var/www/common/$1
# ServerName subdomain.example.jp ⏎ AliasMatch ^/(index|style)$ /var/www/share/subdomain/core/$1 の代替
RewriteCond %{SERVER_NAME} ^subdomain\.[^.]+\.[^.]+$
RewriteRule ^/(index|style)$ /var/www/share/subdomain/core/$1
# バーチャルホストで %{REQUEST_FILENAME} が %{REQUEST_URI} と同じ値になる問題への対処
RewriteCond expr "%{REQUEST_FILENAME} == %{REQUEST_URI}"
RewriteRule ^[^.]+$ %{DOCUMENT_ROOT}%{REQUEST_URI}
# 拡張子無しのURIでアクセスできるようにする
RewriteRule ^[^.]+$ ${adjust-extension:%{REQUEST_FILENAME}}

回答

追記

<IfModule mod_rewrite.c>

</IfModule>

の中に書いた場合はどうでしょうか?

それ以外で RewriteEngine Directive にある、

Note that rewrite configurations are not inherited by virtual hosts. This means that you need to have a RewriteEngine on directive for each virtual host in which you wish to use rewrite rules.

(virtual hostには引き継がれないから都度 RewriteEngine onを設定せよ)

RewriteMap directives of the type prg are not started during server initialization if they're defined in a context that does not have RewriteEngine set to on

(RewriteEngineが Onに設定されていないコンテキストの RewriteMap のprgはサーバー初期化中に処理されない)

が気になったんですが、前者は CentOSのようですのでそういう事もなさそうですし(Ubuntuだと ルートがバーチャルホストなのでひっかかりそうですが)、
後者も ONに設定してますので関係ないですよね。
ただconfのファイル名が httpd-vhosts.confとなってましたので、もしバーチャルホストを使っている場合はその辺も気を付けてください。

追記ここまで


httpd.conf で 対象のファイルが Include されるようになっていますか?

編集 履歴 (2)
  • 有り難うございます。`Include /etc/httpd/conf/extra/httpd-vhosts.conf`と記述し、読み込まれるようにしています。`httpd-vhosts.conf`内の、RewriteRule以外は動きます。また、RewriteRuleも`<Directory /var/www> 〜 </Directory>`等で囲めば、mod_rewriteのログが出力されます。 -
  • おっしゃる通り、バーチャルホストに関する注意事項を見落としていたのが原因でした。バーチャルホストを利用しているという情報も質問文に書いておらず、申し訳ございませんでした。各<VirtualHost>セクションに「RewriteOption inherit」を記述し、RewriteRuleを手直ししたところ、希望通りの動作をするようになりました。この度はどうも有り難うございました。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。