うまいぼうぶろぐ

linuxとhttpdとperlのメモ

mod_rewrite - RewriteCondのANDとORの優先順位について

## 追記
改めて自分の書いた記事を見たら日本語の意味がよくわからないw
結論はRewriteCondに[OR]を書くと、次のRewriteCond とのORになる、ということ
## 追記おわり

ANDのほうが優先順位高いと思ったら、RewriteCondはORのほうが上なのか?

携帯から/m/以外にアクセスした場合は/m/に飛ばしてください、と頼まれた。こんな感じ。(例なのでdocomoauだけに省略)

条件A: URLが/m/以外
条件B: UAがdocomo
条件C: UAがau

とすると、設定したいのは"条件A かつ (条件B または 条件C)"の場合。


試しにこういう風に書いてみて

RewriteEngine On
## 条件A
RewriteCond %{REQUEST_URI}     !^/m/
## 条件B
RewriteCond %{HTTP_USER_AGENT} ^DoCoMo     [OR,NC]
## 条件C
RewriteCond %{HTTP_USER_AGENT} ^KDDI       [NC]
RewriteRule ^/  http://%{HTTP_HOST}/m/     [R,L]

実際に想定通り動いてくれて良かったんだけど、なんかしっくりこない。大抵のプログラムではandのほうが優先順位高いので

(条件A and 条件B) or 条件C

こうなると思ったんだけど、実際には

条件A and (条件B or 条件C)

こう動いているみたい。変な感じだー。

追記

そもそも今回の場合だったら

RewriteEngine On
RewriteCond %{REQUEST_URI}     !^/m/
RewriteCond %{HTTP_USER_AGENT} ^(DoCoMo|KDDI) [NC]
RewriteRule ^/  http://%{HTTP_HOST}/m/        [R,L]

こうして、User-Agentの中でORを取れば優先順位どうこうに悩まなくて良かったではないか。

追記2

おっと。さらに言えばURLの判定はRewriteCondで書かずにRewriteRuleだけで良いではないか。つまり最終的には

RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^(DoCoMo|UP.Browser|KDDI|SoftBank|Vodafone|J-PHONE|MOT-) [NC]
RewriteRule !^/m/  http://%{HTTP_HOST}/m/      [R,L]

これだけのシンプルな設定で良かった。