2010年11月30日火曜日

apacheの.confのRewriteRuleを通すとなぜか%3とかが消えてしまう

ちょっとタイトルの意味が分からない
結局はとても初歩なんですが…。
どういうコトかというと。
apacheの設定ファイル(http.confなど)のRewriteRuleディレクティブにて、以下のような記述があったとします(URLは全部アテです)。
RewriteCond %{HTTP_USER_AGENT} IE的な何か
RewriteRule ^/(.*)$ http://example.com/redirect/http%3A//example.co.jp/ [R=302,L]

「IE的な何か」のユーザーエージェントでの全てのリクエストを「http://example.com/redirect/http%3A//example.co.jp/」にhttp status code 302でリダイレクトさせる、という記述です(のはず)。
で、最終的には 内部ロジックで「%3A」が「:」に解釈されて、http://example.co.jp/ にリダイレクトさせたいはずです。URL的には。

キモはhttp%3A//example.co.jp/となっている部分です。
http://example.com/redirect/ のエントリポイントの仕様により、「:」が「%3A」にURLエンコードされているところです。

実際に「IE的な何か」のUAでリクエストを実行すると、
  1. http://example.com/redirect/httpA//example.co.jp/みたいな形でリダイレクトされる
  2. httpA//example.co.jp/にリダイレクト
  3. 「httpA」だと、なんだそれ?とブラウザに怒られる

となってしまいました。
1.の時点で「%3」が消えてる!

なぜか
「%3」や「%1」がRewriteRuleで使われる特殊な記法だからです。
勉強不足なんで曖昧ですが、RewriteCondの後方参照として、「%n」このような記法があります。
mod_rewriteで動的ページを静的ページっぽいURLにする(Freak)にてこの辺りの解説がされています。
RewriteRuleで「%n」という文字列は避けた方がよさそうです。

「%」をエスケープしたらいいんじゃね?
「%n」が使えないなら「%」をエスケープしたら、「%n」の「%」は正しく認識されるのでは?
と思ってapacheの設定ファイルを変えてみます。
RewriteCond %{HTTP_USER_AGENT} IE的な何か
RewriteRule ^/(.*)$ http://example.com/redirect/http\%3A//example.co.jp/ [R=302,L]


で、再度「IE的な何か」のUAでリクエストを実行すると、
  1. http://example.com/redirect/http%253A//example.co.jp/みたいな形でリダイレクトされる
  2. http%253A//example.co.jp/にリダイレクト
  3. 「http%253A」だと、なんだそれ?とブラウザに怒られる

となってしまいました。
「%」がエスケープされて、「\%3」が「%253」になってる!

ではどうすればよいのか
RewriteRuleの[NE]フラグを使用するです。
[NE]フラグとは「No Escape」=「エスケープしない」。
「%」を「\%」とエスケープし、かつ[NE]でエスケープしない、とすればよいのです。

最終的には以下の形になります。
RewriteCond %{HTTP_USER_AGENT} IE的な何か
RewriteRule ^/(.*)$ http://example.com/redirect/http\%3A//example.co.jp/ [R=302,L,NE]


こうすると、「IE的な何か」のUAでリクエストを実行すると、
  1. http://example.com/redirect/http%3A//example.co.jp/みたいな形でリダイレクトされる
  2. http//example.co.jp/にリダイレクト
  3. 完了

0 件のコメント:

コメントを投稿


Related Posts Plugin for WordPress, Blogger...