mod_rewriteを書く場所によってRewriteRule がマッチする対象が異なる件

これちょいちょい忘れてはまる。

ex: http://example.com/foo/bar/ => http://example.com/hoge/bar/ にリダイレクト

いつもは基本的にvirtualhost内に書くからこう書いてる。

RewriteEngine On
RewriteRule ^/foo/bar/ /hoge/bar/ [R, L]

これをvirtualhostのDirectory内で書くと

<Directory /path/to/docroot/foo/>
  RewriteEngine On
  RewriteRUle ^bar/  /hoge/bar/ [R, L]
</Directory>

という風に頭の/foo/ を取りのぞいたものとマッチさせないといけない。

Per-directory Rewritesに色々詳細が書いている。特に最後のところ: 内でも使用可能だが、ここに書く必要はないし サポートされないよ、と書いているのでこれも覚えておこう。

おまけ

サポートされない、と書いているけどLocation内に書いてみたところ、そのディレクトリへのfull path を頭につけることでマッチした。うーん、不思議。まあ、サポートされてないので書かなければいいだけど。

<Location /foo >
  RewriteEngine On
  RewriteRule ^/home/hogem/www/default/public_html/foo/bar/ /hoge/bar/ [R,L]
</Location>

document 引用

  • What is matched?

In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html").

In Directory and htaccess context, the Pattern will initially be matched against the filesystem path, after removing the prefix that lead the server to the current RewriteRule (e.g. "app1/index.html" or "index.html" depending on where the directives are defined).

If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.

  • Per-directory Rewrites

The rewrite engine may be used in .htaccess files and in sections, with some additional complexity.

To enable the rewrite engine in this context, you need to set "RewriteEngine On" and "Options FollowSymLinks" must be enabled. If your administrator has disabled override of FollowSymLinks for a user's directory, then you cannot use the rewrite engine. This restriction is required for security reasons.

When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is automatically removed for the RewriteRule pattern matching and automatically added after any relative (not starting with a slash or protocol name) substitution encounters the end of a rule set. See the RewriteBase directive for more information regarding what prefix will be added back to relative substitions.

If you wish to match against the full URL-path in a per-directory (htaccess) RewriteRule, use the %{REQUEST_URI} variable in a RewriteCond.

The removed prefix always ends with a slash, meaning the matching occurs against a string which never has a leading slash. Therefore, a Pattern with ^/ never matches in per-directory context.

Although rewrite rules are syntactically permitted in and sections, this should never be necessary and is unsupported.