mod_rewrite モジュール
URL 書き換えエンジンこのモジュールは、要求された URL をリアルタイムで書き換える ための、ルールベースの書き換えエンジンを提供します。
ステータス: Extension
ソースファイル: mod_rewrite.c
モジュール識別子: rewrite_module
互換性: Apache 1.2 以降で使用可能
概要
`` mod_rewrite のすばらしいところは、 Sendmailのような設定性と柔軟性を与えてくれるところだろう。 また、mod_rewrite のよくないところは、 Sendmailのような設定性と柔軟性を与えてくれるところだろう。''-- Brian Behlendorf
Apache GroupURL を操作するためのスイス製のアーミーナイフ、mod_rewrite へようこそ!`` 膨大な設定例やドキュメントがあるにもかかわらず、 mod_rewrite は黒魔術である。かなりイケてるっぽい黒魔術だが、 やっぱり所詮は黒魔術である。''-- Brian Moore
bem@news.cmc.netこのモジュールは、(正規表現パーサに基づく)ルールベースの 書き換えエンジンを使い、要求された URL を適宜書き換えます。 サポートするルールの数、および各ルールを適用する際のルール条件 の数に制限はなく、本当にフレキシブルでかつパワフルな URL 操作 メカニズムを提供します。この URL 操作に先立ち、次のようにいろいろな 評価を行なうことができます。たとえばサーバ変数、環境変数、HTTP ヘッダ、 タイムスタンプ、さらに外部データベースの検索結果までを評価の対象として、 各種のフォーマットを使った粒度の高い URL マッチングを実現できます。
このモジュールは、サーバ単位のコンテキスト (
httpd.conf
) およびディレクトリ単位のコンテキスト (.htaccess
) において (PATH-INFO 部分を含む) フル URL に対する操作を行いますが、さらに結果 としてクエリー文字列部分を生成することもできます。出力された結果を 内部のサブプロセスや外部リクエストのリダイレクション、さらには内部の プロキシ処理ルーチンに渡すこともできます。ただ、これらすべての機能や柔軟性が、欠点や複雑さの元にもなって います。なので、このモジュール全体を一日程度で覚えようなどとは 思わないほうがいいでしょう。
このモジュールは 1996 年の 4 月に
らにより考案されてオリジナルが書かれ、Ralf S. Engelschall
rse@engelschall.com
www.engelschall.com
1997 年の 7 月に、The Apache Group に対して独占的に贈呈されました。
目次
内部処理
設定ディレクティブ
その他
- RewriteEngine
- RewriteOptions
- RewriteLog
- RewriteLogLevel
- RewriteLock
- RewriteMap
- RewriteBase
- RewriteCond
- RewriteRule
内部処理
このモジュールの内部処理はとても複雑ですが、ありがちなミスを避け、 また全機能を活用できるように、平均的ユーザに対しても一度は説明して おく必要があります。
API フェーズ
まずは、Apache が HTTP リクエストを処理する際に、このモジュールが このフェーズで行なうことを理解しておかなければなりません。Apache API では、これらの各フェーズに対するフックが提供されています。 mod_rewrite は以下の 2 つのフックを使います: HTTP リクエストが 読まれた後でかつすべての認証が開始される前に使われる URL-to-filename 変換フック、そして、認証フェーズの後でディレクトリ毎の設定ファイル (
.htaccess
) が読まれたが、まだ content ハンドラが 有効になる前に起動される fixup フックです。そしてあるリクエストが入って来て、Apache がこれに対応するサーバ (もしくはバーチャルサーバ) を決定した後書き換えエンジンは、サーバ毎の 設定を元に、URL-to-filename フェーズですべての mod_rewrite ディレクティブの処理を開始します。その後多少のステップを経て最後の データディレクトリが見つかった時、ディレクトリ毎の mod_rewrite 設定ディレクティブが fixup フェーズで起動されます。この各々の タイミングの間に特に明らかな違いはないのですが、それでも mod_rewrite はいずれの時にも各 URL を新しい ULR またはファイル名に書き換えます。 これはこの API がデザインされた時に想定された使い方ではないのですが、 Apache 1.x においてはこれが mod_rewrite が動ける唯一の方法でした。 この点をよりはっきりさせるために、以下の 2 点について覚えておいて ください:
- mod_rewrite は URL を URL へ、URL をファイル名へ、さらにファイル 名をファイル名へと書き換えますが、API では現在のところ URL-to-filename フックのみを提供しています。Apache 2.0 ではそれまでには なかった 2 つのフックが追加され、処理がより明確になりました。しかし この点でユーザにとっての不利益はなく、単に覚えておくべき事実として: Apache は URL-to-filename フックにおいて API が意図する以上のことを 行ないます。
- mod_rewrite では、信じられないことに、URL がファイル名に翻訳 されてからずっと後に辿り着くところにある、ディレクトリ毎の コンテキストすなわち
.htaccess
ファイルの中で URL 操作を行えるようになっていす。.htaccess
ファイルは ファイルシステム中にあるためにこのようになっているのですが、 処理の流れはすでにこの段階まで到達しているのです。つまりこの時点で API フェーズに従えば、どの URL を操作するにもすでに遅きに失して いるのです。この鶏と卵問題を打開するため、mod_rewrite ではちょっと したトリックを使っています:ディレクトリ毎のコンテキストで URL / ファイル名 の操作を行なう際、mod_rewrite はまずファイル名を対応する URL に戻し (これは通常不可能ですが、これを可能にするトリック についてはRewriteBase
を見てください) 、その新しい URL で内部的に新しいサブリクエストを生成しているのです。これで API フェーズ処理が再度起動されます。このように、mod_rewrite は複雑なステップをユーザに対して全般に 透過的にしようとがんばっていますが、とりあえず以下のことは覚えて おいておくべきでしょう:サーバ毎のコンテキストにおける URL 操作は 実際高速でかつ有用であるのに対し、ディレクトリ毎の書き換えは、この 鶏と卵の問題のため遅い上に役に立ちません。しかしこれは、ごく平均的 なユーザにとって、(ローカルに制限された) URL 操作のための唯一の方法 なのです。
これら2つの点を忘れないでください!
ルールセット処理
ここで、これら2つの API フェーズで mod_rewrite が起動されると、 mod_rewrite はまず自分自身の設定用構造体(これらはサーバ毎の コンテキストに伴う起動時か、または Apache カーネルがディレクトリ 毎のコンテキストに従ってディレクトリ間を探索する途中のいずれかに 生成される)より構成されたルールセットを読み込みます。そして その中に入っているルールセット(条件を伴う1つ以上のルールの集まり) と共に URL 書き換えエンジンが開始されます。URL 書き換えエンジン 自体は、双方の設定内容と全く同じように動作します。最終結果の処理が 異なるだけです。ルールセット中のルールの書き順は重要です。これは、書き換えエンジン はそれらを特別な(かつ、あまり分かりやすいとは言えない)順序で処理 するからです。ルールは以下のように処理されます:書き換えエンジンは ルール(
RewriteRule
ディレクティブ)を1つずつなめながら ルールセット中をループしますが、ある特別なルールがマッチしたら、それ に対応する条件(RewriteCond
ディレクティブ)がある間その 中をループします。歴史的な理由によりまず条件が与えられ、その後に制御 フローを書くところがちょっとくどいところです。詳細は Figure 1 をご覧 下さい。
Figure 1: 書き換えルールセットにおける制御フロー もうお分かりのように、まず URL を各ルールのパターン に対してマッチングします。マッチしない場合、mod_rewrite はすぐに このルールの処理を中止して次のルールを見に行きます。パターン にマッチすると、mod_rewrite はそれに対応する条件を探します。もし 何もなければ、単に URL を置換対象文字列から作られた新しい 値に置換し、そのルールのループを続けます。何らかの条件があれば、 内部ループを開始し、それらの条件が列挙されている順に処理を繰り返し ます。 その条件に合わなかった場合:現在の URL に対してパターンのマッチング を行ないません。その代わり、まず変数を展開し、後方参照を行い、 検索テーブルをマッピングするなどしてテスト文字列 を生成し、それに対して条件パターンとのマッチングを行ない ます。パターンにマッチしない場合、条件の組合せ全体とそれに対応する ルールは成立しないことになります。パターンにマッチした場合、次の 条件が評価され、それが条件のある限り繰り返されます。もしすべての 条件にマッチすれば、URL は置換対象文字列に置換され、 処理が継続されます。
特殊文字のクウォート
Apache 1.3.20 に関しては、テスト文字列と置換対象 文字列の中の特殊文字は、その直前にバックスラッシュ ('\') を置くことで エスケープ(すなわち、それらの持つ特殊な意味を打ち消して、通常の文字 として扱うこと)できます。たとえば、置換対象文字列の中でも '
\$
' という文字列を使って本来のドル記号を入れることが できるわけです。これにより、mod_rewrite がそれを後方参照として扱おうと するのを防いでいます。正規表現の 後方参照を使う
ここでひとつ覚えておいて欲しいことがあります:パターン の中や条件パターンのうちのどこかで括弧を使えば、文字列$N
と%N
で使える後方参照が内部的に生成 されます(後述)。これらは置換対象 文字列やテスト文字列 を生成するのに使えます。Figure 2 では、この後方参照が転送されて展開 される場所について解説します。
Figure 2: ルールを通した後方参照の流れ これまでは mod_rewrite の内部処理に関する短期集中コースでした。 ここからは使用可能なディレクティブに関することがかかれています。 これを読めば役立つ知識になってゆくはずです。
設定ディレクティブ
RewriteEngine
書式: RewriteEngine on|off
デフォルト:RewriteEngine off
コンテキスト: server config, virtual host, directory, .htaccess
オーバーライド: FileInfo
ステータス: Extension
モジュール: mod_rewrite.c
互換性: Apache 1.2
RewriteEngine
ディレクティブを使うと、実行時の 書き換えエンジンを有効にしたり無効にしたりできます。これがoff
に設定されていると、このモジュールは実行時の 処理を一切行ないません。またSCRIPT_URx
環境変数の 更新さえもしなくなります。
RewriteRule
を全部コメントアウトしたりしないで、 このディレクティブを使ってくださいね。デフォルトでは、rewrite の設定は継承されないので注意してください。 つまり、この機能を使いたいと思うバーチャルホスト毎に
RewriteEngine on
ディレクティブを書かなければいけない ということです。
RewriteOptions
書式: RewriteOptions オプション
デフォルト: なし
コンテキスト: server config, virtual host, directory, .htaccess
オーバーライド: FileInfo
ステータス: Extension
モジュール: mod_rewrite.c
互換性: Apache 1.2
RewriteOptions
ディレクティブは、現在のサーバ単位 もしくはディレクトリ単位の設定で使用する、特別なオプションをセット します。オプション文字列は以下のいずれかです:
- '
inherit
'
これは、現在の設定値を親の設定値から強制的に継承させます。 これにより、仮想サーバ単位のコンテキストにおいて、メインサーバ のマップ、条件、ルールが継承されることになります。また ディレクトリ単位のコンテキストでは、親ディレクトリの.htaccess
設定に記述されている条件やルールが継承 されることになります。
RewriteLog
書式: RewriteLog file-path
デフォルト: なし
コンテキスト: server config, virtual host
オーバーライド: 適用不可
ステータス: Extension
モジュール: mod_rewrite.c
互換性: Apache 1.2
RewriteLog
ディレクティブは、すべての書き換え動作 に関してサーバがログを書き込むためのファイルの名前をセットします。 この名前がスラッシュ ('/
') で始まらない場合は Server Rootから相対であると見なされます。このディレクティブ はサーバ単位の設定の中で一度だけ記述されるべきものです。
注意: 書き換え動作のロギングを抑制する ためにファイル名を /dev/null
にするのは お勧めできません。これは、書き換えエンジンは実際にはログ ファイルへの出力を行わないのに、未だ内部的にはログファイル への出力を生成しているからです。 これはサーバのパフォーマンスを低下させるだけで、 管理者にとってよいことはありません。ロギングを 抑止する場合はRewriteLog
ディレクティブを コメントアウトするか、RewriteLogLevel 0
を 使うようにしてください!
セキュリティ: ログファイルを格納する ディレクトリが、サーバを起動するユーザ以外にも書き込み可能である 場合に、なぜセキュリティが脅かされるかについての詳しい説明は、 Apache Security Tipsドキュメントをご覧ください。 例:
RewriteLog "/usr/local/var/apache/logs/rewrite.log"
RewriteLogLevel
書式: RewriteLogLevel Level
デフォルト:RewriteLogLevel 0
コンテキスト: server config, virtual host
オーバーライド: 適用不可
ステータス: Extension
モジュール: mod_rewrite.c
互換性: Apache 1.2
RewriteLogLevel
ディレクティブでは、書き換え動作時の ログファイルの冗長レベルを指定します。デフォルトのレベルは 0 で、 これは一切ログを書かないことを意味します。一方 9 もしくはそれ以上を 指定すると、ほとんどすべての動作についてログが書かれます。書き換え動作のログを取らないようにするには、単にLevel を 0 にします。これで書き換え動作に関するすべてのログが無効となります。
注意:Levelに大きな値を指定 すると、Apache サーバの動作速度が劇的に低下します!書き換え時 のログファイルでLevelに 2 以上の値を指定するのは デバッグ時のみにしておいてください! Example:
RewriteLogLevel 3
RewriteLock
書式: RewriteLock file-path
デフォルト: なし
コンテキスト: server config
オーバーライド: 適用不可
ステータス: Extension
モジュール: mod_rewrite.c
互換性: Apache 1.3
このディレクティブは、mod_rewrite がRewriteMap プログラムと通信するのに必要な、同期用ロックファイルの名前を セットします。RewriteMap プログラムを使いたい場合には、このロック ファイルに(NFS マウントされたデバイスではなく)ローカルパスをセット します。それ以外のタイプの書き換えマップを使う場合には、セットする必要 はありません。
RewriteMap
書式: RewriteMap MapName MapType:MapSource
デフォルト:デフォルトでは使用されない
コンテキスト: server config, virtual host
オーバーライド: 適用不可
ステータス: Extension
モジュール: mod_rewrite.c
互換性: Apache 1.2 (partially), Apache 1.3
RewriteMap
ディレクティブでは、マッピング関数 を使ってルール置換文字列の内部で使える書き換えマップ を定義します。これにより、キーを検索する際に、フィールドを挿入 したり置換したりできます。検索対象には各種のタイプが使えます。MapNameはマップの 名前です。以下の書き方のいずれかを通して、書き換えルールの置換文字列 におけるマッピング関数を特定するのに使われます。
このような書式が現れると、MapNameマップが評価されて キーLookupKeyが検索されます。キーが見つかれば、置換される 代わりにSubstValueによりマップ関数が呼ばれます。キーが 見つからない場合、DefaultValueがあればそれで置換され、 DefaultValue指定されていなければ空文字列に置換されます。${
MapName:
LookupKey}
${
MapName:
LookupKey|
DefaultValue}
以下はMapTypeとMapSourceを使った組合せです:
- 標準のプレーンテキスト
MapType:txt
, MapSource: 有効な通常ファイルへの Unix ファイルシステムのパスこれは、MapSourceが空白行や(行頭が '#' 文字で始まる) コメント行、もしくは以下のような一行にひとつのペアから構成されるような プレーンな ASCII ファイルである場合の、標準の書き換えマップ機能です。
MatchingKey SubstValueExample:
## ## map.txt -- rewriting map ## Ralf.S.Engelschall rse # Bastard Operator From Hell Mr.Joe.Average joe # Mr. Average
RewriteMap real-to-user txt:/path/to/file/map.txt- ランダムなプレーンテキスト
MapType:rnd
, MapSource: 有効な通常ファイルへの Unix ファイルシステムのパスこれは前述の標準プレーンテキストの類とは別のものであり、 特殊な後処理機能を持っています:値を検索した後、``or'' の 意味を持つ ``
|
'' 文字にしたがってパースされます。 つまりこれらは変換候補とみなされ、実際に返される値はこれらの 中からランダムに選ばれます。これは一見妙な感じがして意味が なさそうに思えますが、これは実際にリバースプロキシにおける 負荷分散用として設計されており、検索した値がサーバ名として 使われます。例を挙げます:
## ## map.txt -- rewriting map ## static www1|www2|www3|www4 dynamic www5|www6
RewriteMap servers rnd:/path/to/file/map.txt- ハッシュファイル
MapType:dbm
, MapSource: 有効な通常ファイルへの Unix ファイルシステムのパスプレーンテキストフォーマットのファイルと同じ内容を 持つバイナリファイルで、高速な検索を行なうために最適化が施された NDBM フォーマットファイルというものがあり、これをソースとして使う こともできます。このようなファイルは、NDBM ツールを使ったり、 以下のような perl スクリプトを使って作ることができます。
#!/path/to/bin/perl ## ## txt2dbm -- convert txt map to dbm format ## use NDBM_File; use Fcntl; ($txtmap, $dbmmap) = @ARGV; open(TXT, "<$txtmap") or die "Couldn't open $txtmap!\n"; tie (%DB, 'NDBM_File', $dbmmap,O_RDWR|O_TRUNC|O_CREAT, 0644) or die "Couldn't create $dbmmap!\n"; while (<TXT>) { next if (/^\s*#/ or /^\s*$/); $DB{$1} = $2 if (/^\s*(\S+)\s+(\S+)/); } untie %DB; close(TXT);
$ txt2dbm map.txt map.db- 内部関数
MapType:int
, MapSource: 内部 Apache 関数ソースとして、内部 Apache 関数というものもあります。今現在は エンドユーザが自分用に独自のものを作ることはできませんが、以下の ものが用意されています。
- toupper:
見つかったキーをすべて大文字に変換する。- tolower:
見つかったキーをすべて小文字に変換する。- escape:
見つかったキーの中の特殊文字を 16 進エンコーディングに変換する。- unescape:
見つかったキーにの中の 16 進エンコーディングを特殊文字に戻す。- 外部の書き換えプログラム
MapType:prg
, MapSource: 有効な通常ファイルへの Unix ファイルシステムのパスソースにはマップファイル以外にプログラムを使うこともできます。 これ用のプログラムを作成するには、まずいずれかの言語を選択する ことになりますが、作成されたものは実行可能ファイル (すなわちオブジェクトコード、もしくは1行目に '
#!/path/to/interpreter
' のようなマジッククッキー トリックの入ったスクリプト)でなければなりません。このプログラムは Apache サーバの起動時にすぐに起動され、 自分の
stdin
およびstdout
ファイル ハンドルを通して、書き換えエンジンとのやりとりを行ないます。 このプログラムは、各々のマップ関数の検索のたびに、検索対象の キーを、改行文字で終端された文字列としてstdin
から受け取ります。そして、見つかった値を改行文字で終端された 文字列として、もしくは見つからなかった(すなわち、 与えられたキーに対応する値がない)場合、4 文字の文字列 ``NULL
'' を返されなければなりません。1:1 の マップ(すなわちキー = 値)を実現する単純なプログラム 例としては、以下のようになります:
#!/usr/bin/perl $| = 1; while (<STDIN>) { # ...put here any transformations or lookups... print $_; }しかし、十分に気をつけてほしいことがあります:
- ``Keep it simple, stupid(アホ、もっと簡単に 書けよ!)」'' (KISS) ということなのですが、もしこの プログラムがハングしてしまうと、そのルールが現れた瞬間に Apache サーバ自体がハングしてしまいます。
- ありがちな間違いとしては:
stdout
に対して バッファード I/O を使ってはなりません!これをやると永久ループ にハマってしまいます!だから上のコードでも ``$|=1
'' とやってるんです。。。- RewriteLock ディレクティブを使ってロック ファイルを定義し、mod_rewrite が当該プログラムへの通信において 同期合わせができるようにしてください。デフォルトではそのような 同期合わせは行なわれません。
RewriteMap
ディレクティブは何度でも書くことが できます。各々のマッピング関数について 1 つのRewriteMap
を使い、その書き換え用マップファイルを宣言します。ディレクトリ毎の コンテキスト内部でマップを宣言することはできませんが、 ディレクトリ毎のコンテキストでこのマップを使うことは もちろん可能です。
注意:プレーンテキストと DBM フォーマット のファイルに関しては、マップファイルの mtime
が変更 されるかまたはサーバが再起動されるまで、検索されたキーはメモリ内に キャッシュされます。それにもかかわらず、毎回の リクエストで使われるマップ関数をルール内に書くことができます。 外部検索は一度しか行なわれないので、これでも大丈夫なのです。
RewriteBase
書式: RewriteBase URL-path
デフォルト: デフォルトは物理 ディレクトリのパス
コンテキスト: directory, .htaccess
オーバーライド: FileInfo
ステータス: Extension
モジュール: mod_rewrite.c
互換性: Apache 1.2
RewriteBase
ディレクティブは、ディレクトリ毎の 書き換えにおいてベースとなる URL を明示的に指定するものです。以下 で示すように、RewriteRule
はディレクトリ毎の設定ファイル (.htaccess
)で使えます。そこでは、これはローカルに振舞い ます。すなわち、この処理段階ではローカルディレクトリの接頭辞 が取り除かれ、その残りの部分に対してのみ書き換えルールが適用されます。 そして書き換え後、取り除かれた部分が再度自動的にパスに付加されます。新しい URL に対する置換が発生すると、このモジュールは当該 URL をサーバ処理に再投入しなければなりません。これを行なうには、対応する URL のプリフィックスもしくは URL のベースが何なのかを知る必要が あります。デフォルトではこのプリフィックスはファイルパスそのものに 対応しています。しかしながら、ほとんどの Web サイトでは URL は物理的なファイル名のパスを直接指している *わけではない* ので、 一般的にこの仮定は間違っていることになります。そのため、
RewriteBase
ディレクティブを使って正しい URL プリフィックス を指定してやらなければならないのです。
注意:もしあなたの Web サーバの URL が 物理的なファイルパスを直接指しているのでなければ、 RewriteRule
ディレクティブを使おうとしているところ すべてについて、各.htaccess
ファイルでRewriteBase
ディレクティブを使わなければなりません。例:
以下は、ディレクトリ毎の設定ファイルだと思ってください:
# # /abc/def/.htaccess -- ディレクトリ /abc/def のための dir 別設定ファイル # 参考:/abc/def は パス /xyz の物理パス名である。すなわちサーバには # 'Alias /xyz /abc/def' といったディレクティブの設定がある。 # RewriteEngine On # 物理的なパスのプリフィックスである /abc/def でなく、/xyz を通して # アクセスしていることをサーバに知らせる。 RewriteBase /xyz # これが書き換えルール RewriteRule ^oldstuff\.html$ newstuff.html上記の例では、
/xyz/oldstuff.html
へのリクエストで 物理ファイル/abc/def/newstuff.html
への正しい 書き換え操作が行なわれます。
Apache ハッカーのための注釈:
以下のリストで示しているのは、内部処理ステップに関する 詳細情報です:リクエスト: /xyz/oldstuff.html 内部処理: /xyz/oldstuff.html -> /abc/def/oldstuff.html (per-server Alias) /abc/def/oldstuff.html -> /abc/def/newstuff.html (per-dir RewriteRule) /abc/def/newstuff.html -> /xyz/newstuff.html (per-dir RewriteBase) /xyz/newstuff.html -> /abc/def/newstuff.html (per-server Alias) 処理結果: /abc/def/newstuff.htmlこれは非常に複雑に見えるものの、Apache の 内部処理に関する正しい動きです。なぜなら、ディレクトリ単位の 書き換え操作は処理の中において来るのが遅すぎるのです。 そのためこれが発生すると、(書き換えが行なわれた)リクエスト は Apache カーネルの中に再投入されなければなりません! しかし:これは深刻なオーバーヘッドを伴うように見えるものの、 実際には大した事はありません。それは、この再投入は完全に Apache サーバの内部で起こる事であり、Apache の内部における その他の多くの動作中にも同様のことが起こっているからです。 なので、その設計と実装は正しいのだと確信して構わないのです。
RewriteCond
書式: RewriteCond テスト文字列 条件パターン
デフォルト: なし
コンテキスト: server config, virtual host, directory, .htaccess
オーバーライド: FileInfo
ステータス: Extension
モジュール: mod_rewrite.c
互換性: Apache 1.2 (部分的に), Apache 1.3
RewriteCond
ディレクティブはルール条件を定義します。RewriteRule
ディレクティブの前に 1 つ以上のRewriteCond
ディレクティブを置くことができます。それ以降の 書き換えルールは、そのパターンが現在の URI の状態とマッチし、 かつこれらの追加条件が適用される場合にのみ使われます。テスト文字列は文字列であり、プレーンテキストに加え、 以下の拡張構造を持つことができます:
- RewriteRule 後方参照:この書式で、後方参照 を表します。
(0 <= N <= 9) これは、対応する$N
RewriteRule
ディレクティブ(現在のRewriteCond
ディレクティブの ブロックの最後にあるもの)からのパターンを、(括弧で!)グループ 化したものへのアクセスを提供します。- RewriteCond 後方参照: この書式で、後方参照 を表します。
(1 <= N <= 9) これは、現在の条件ブロックの中で最後に マッチした%N
RewriteCond
ディレクティブからのパターン を、(括弧で!)グループ化したものへのアクセスを提供します。- RewriteMap 拡張: この書式で、拡張を表します。
詳細はRewriteMap のドキュメントを 参照のこと。${mapname:key|default}
- サーバ変数: 以下は変数を表します。
ここで、変数名は以下の一覧にある文字列のいずれかです:%{
変数名}
HTTP ヘッダ: HTTP_USER_AGENT
HTTP_REFERER
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST
HTTP_PROXY_CONNECTION
HTTP_ACCEPT
コネクション & リクエスト: REMOTE_ADDR
REMOTE_HOST
REMOTE_USER
REMOTE_IDENT
REQUEST_METHOD
SCRIPT_FILENAME
PATH_INFO
QUERY_STRING
AUTH_TYPE
サーバ内部変数: DOCUMENT_ROOT
SERVER_ADMIN
SERVER_NAME
SERVER_ADDR
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE
システム関連: TIME_YEAR
TIME_MON
TIME_DAY
TIME_HOUR
TIME_MIN
TIME_SEC
TIME_WDAY
TIME
特殊なもの: API_VERSION
THE_REQUEST
REQUEST_URI
REQUEST_FILENAME
IS_SUBREQ
注意:これらの変数は、全て同様の 名前を持つ HTTP MIME ヘッダや Apache サーバの C 変数、 または Unix システムの
struct tm
フィールド に対応します。ほとんどのものは、マニュアルや CGI 仕様の どこかに説明があります。この中で mode_rewrite で特別な 意味を持つものに以下のものがあります:
IS_SUBREQ
- これは、サブリクエストを処理中は "true" に、そうで なければ "false" になります。与えられたタスクを完了する ために追加のファイルや URI を解決する必要があるモジュールは、 サブリクエストを生成する場合があります。
API_VERSION
- これは現在の httpd のビルドにおける Apache モジュール API(サーバとモジュール間の内部インターフェース)の バージョンであり、include/ap_mmn.h で定義されています。 モジュール API のバージョンは使用している Apache の バージョン(たとえば Apche 1.3.14 であれば 19990320:10)に 対応しますが、これは主にモジュールの作者が関心を持つもの です。
THE_REQUEST
- ブラウザからサーバに送られた HTTP リクエストの完全な もの(すなわち、"
GET /index.html HTTP/1.1
")。 これには、ブラウザから送られた追加ヘッダは一切含みません。REQUEST_URI
- HTTP リクエスト行でリクエストされたリソース (上記の例では "/index.html" がそれにあたります)。
REQUEST_FILENAME
- リクエストにマッチしたファイルまたはスクリプトの、 完全なローカルファイルシステムのパス。
考慮事項:
- SCRIPT_FILENAME および REQUEST_FILENAME には同じ名前、 すなわち、Apache サーバの
request_rec
内部構造体の中のfilename
フィールドの値が入って います。前者は単によく知られている CGI 変数名であるのに対し、 後者は(request_rec
フィールドのuri
の値が入っている)REQUEST_URI に一致するものです。- 特別な書式:
%{ENV:変数}
ここで変数は任意の環境変数 です。これは Apache の内部構造体もしくは(そこに存在しなければ) Apache サーバプロセスが発行するgetenv()
を通して 検索されます。- 特別な書式:
%{HTTP:ヘッダ}
ここで ヘッダ は任意の HTTP MIME ヘッダ名です。これは HTTP リクエストから検索されます。 例:%{HTTP:Proxy-Connection}
は HTTP ヘッダの ``Proxy-Connection:
'' の値です。- 特別な書式:
%{LA-U:変数}
は前方参照であり、内部の(URL ベースの) サブリクエストを実行して変数の最終値を決定します。 実際には API フェーズの後のほうでセットされるために、現時点では アクセスできないような変数を使って書き換えを行ないたい場合に 使用します。たとえば、サーバ単位のコンテキスト(httpd.conf
file)から来るREMOTE_USER
変数にしたがって 書き換えを行ないたい場合には、%{LA-U:REMOTE_USER}
を使用しなければなりません。なぜなら、この変数は mod_rewrite が 動作する URL 変換フェーズの後にある認証フェーズでセット されるものだからです。一方、mod_rewrite は API の Fixup フェーズ を通してディレクトリ単位のコンテキスト(.htaccess
file)を実装しており、かつ認証フェーズはこのフェーズの前 に行なわれるため、そこでは単に%{REMOTE_USER}
とする ことができるのです。- 特別な書式:
%{LA-F:変数}
これは内部の(ファイル名ベースの)サブ リクエストを実行して変数の最終値を決定します。ほとんどの 場合これは前述の LA-U と同じです。条件パターン は、現在のテスト文字列の実体に 対して適用される正規表現です。テスト文字列は評価された後に 条件パターンに対してマッチングが行なわれます。
備考: 条件パターンは、標準の 拡張正規表現にいくつか追加を行なったものです:
- '
!
' 文字(エクスクラメーションマーク)をパターン 文字列の前につけることで、マッチしないパターン を指定できます。- 条件パターンのちょっとした変種もあります。実際の正規表現 文字列の代わりに以下のように使うことができます:
- '<条件パターン' (字句の並び的に、 より小さい)
条件パターンを単なる文字列として扱い、字句の並びと してテスト文字列と比較します。テスト文字列が 字句の並びとして条件パターンより小さい場合に真に なります。- '>条件パターン' (字句の並び的に、 より大きい)
条件パターンを単なる文字列として扱い、字句の並びと してテスト文字列と比較します。テスト文字列が 字句の並びとして条件パターンより大きい場合に真に なります。- '=条件パターン' (字句の並び的に等しい)
条件パターンを単なる文字列として扱い、字句の並びと してテスト文字列と比較します。テスト文字列が 字句の並びとして条件パターンと等しい場合、すなわち、 2 つの文字列が(1 文字ずつ比較して)正確に等しい場合に真に なります。もし条件パターンが単なる"" (2 つの引用符)であれば、テスト文字列は空文字列と 比較されます。- '-d' (directory)
テスト文字列をパス名として扱い、それが存在して、かつ ディレクトリであれば真。- '-f' (通常 file)
テスト文字列をパス名として扱い、それが存在して、かつ 通常ファイルであれば真。- '-s' (size がある通常 ファイル)
テスト文字列をパス名として扱い、それが存在して、かつ サイズが 0 より大きい通常ファイルであれば真。- '-l' (シンボリック link)
テスト文字列をパス名として扱い、それが存在して、かつ シンボリックリンクであれば真。- '-F' (サブリクエストを通した既存ファイル)
テスト文字列が有効なファイルであること、そしてこの サーバにおいて、現時点で設定されているすべてのアクセス制御を 通して、そのパス名でアクセスできるかどうかをチェックします。 これは内部のサブリクエストを使ってチェックを行なうので、注意 して使わないとサーバのパフォーマンスを低下させることに なりかねません!- '-U' (サブリクエストを通した既存 URL)
テスト文字列が有効な URL であること、そしてこの サーバにおいて、現時点で設定されているすべてのアクセス制御を 通して、そのパス名でアクセスできるかどうかをチェックします。 これは内部のサブリクエストを使ってチェックを行なうので、注意 して使わないとサーバのパフォーマンスを低下させることに なりかねません!
注意:以上すべてのテストについて、 エクスクラメーションマーク ('!') を前に置くことにより それらの意味を否定することができます。 さらに、
RewriteCond
ディレクティブへの第3引数として 条件パターンに特別なを追加することができます:フラグは以下のものをカンマ 区切りで並べたものです:[
フラグ]
- '
nocase|NC
' (no case)
これは大文字小文字を区別せずにテストします。すなわち、 展開されたテスト文字列と条件パターンにおいて、 'A-Z' および 'a-z' の間には違いはないものと見なされます。 このフラグはテスト文字列と条件パターンの間の 比較においてのみ有効です。ファイルシステム上およびサブリクエスト のチェックでは意味を持ちません。- '
ornext|OR
' (or next condition)
ルール条件を結合するに当たり、暗黙の AND の代わりにローカルの OR を使います。典型的な例として、以下を参照してください:このフラグを使わない場合は、条件/ルールを 3 回書くことに なります。RewriteCond %{REMOTE_HOST} ^host1.* [OR] RewriteCond %{REMOTE_HOST} ^host2.* [OR] RewriteCond %{REMOTE_HOST} ^host3.* RewriteRule ...これらのホストに関する特別な処理使用例:
リクエストの中の ``User-Agent:
'' ヘッダにしたがって ホームページサイトの書き換えを行なうには、以下のようにします:解釈:ブラウザとして(自分自身で 'Mozilla' と名乗っている)ネット スケープナビゲータを使う場合、フレームなどを含む max の ホームページを見ることになります。(端末ベースの)Lynxブラウザを 使う場合は、画像やテーブルなどを含まない min のホーム ページが表示されます。それ以外のブラウザの場合は標準(std)のページ が表示されます。RewriteCond %{HTTP_USER_AGENT} ^Mozilla.* RewriteRule ^/$ /homepage.max.html [L] RewriteCond %{HTTP_USER_AGENT} ^Lynx.* RewriteRule ^/$ /homepage.min.html [L] RewriteRule ^/$ /homepage.std.html [L]
RewriteRule
書式: RewriteRule パターン 置換対象
デフォルト: なし
コンテキスト: server config, virtual host, directory, .htaccess
オーバーライド: FileInfo
ステータス: Extension
モジュール: mod_rewrite.c
互換性: Apache 1.2 (partially), Apache 1.3
RewriteRule
ディレクティブは、実際の書き換えを 担当してくれる馬車馬です。このディレクティブは複数回書くことが できます。各ディレクティブは1つの書き換えルールを定義します。 これらルールを定義する順序は重要です。なぜなら、 実行時にルールを適用する際、この順序で行なわれるからです。パターンは、 現在の URL に適用される(Apache 1.1.x では System V8、Apache 1.2.x 以降では POSIX の)正規表現 です。ここで「現在の」と言っているのは、ルールが適用される際の URL の値のことです。これはリクエストされたオリジナルの URL で あるとは限りません。なぜならすでに数多くのルールがマッチして、 それを書き換えた後かもしれないからです。
正規表現の文法に関するヒント:
テキスト:.
任意の一文字[
chars]
文字クラス:いずれかの文字[^
chars]
文字クラス:これら以外の文字 text1|
text2 選択肢:text1 または text2 文字数指定:?
直前の文字の 0 回または 1 回の繰り返し*
直前の文字の 0 回以上の繰り返し+
直前の文字の 1 回以上の繰り返し グルーピング:(
text)
テキストのグルーピング (選択肢の境界を明示する、もしくは後方参照を作成するために使う。 N番目のグループは、RewriteRule の RHS で$
Nとして参照される。) 文字位置の指定:^
行頭$
行末 エスケープ:\
char 特殊文字をエスケープ(効果を打ち消す)する (たとえば ".[]()
" など)正規表現に関する情報は、ローカルの regex(3) man ページか または Apache 1.3 の配布物に含まれる
src/regex/regex.3
を参照してください。もし正規表現やその変種(POSIX regex, Perl regex, など)に興味があれば、以下の専門書をご覧下さい:Mastering Regular Expressions
Jeffrey E.F. Friedl
Nutshell Handbook Series
O'Reilly & Associates, Inc. 1997
ISBN 1-56592-257-3
さらに、mod_rewrite ではパターンの前に NOT 文字('
!
') が使えます。これで後続のパターンを否定することができます。たとえて 言うならば、``もし現在の URL がこのパターンにマッチ しなければpattern'' ということです。これは、反対の パターンを表す方が簡単だったり、最後のデフォルトルールとするなど、 例外的なケースを表現するのにも使えます。
注意:NOT 文字を使ってパターンを否定 する場合は、パターン中にグループ化されたワイルドカード部分を 入れることはできません。これは、パターンがマッチ *しない* 時、 そのグループの中身がなくなってしまうからです。その結果、もし 否定されたパターンが使われると、置き換え文字列の中で $N
が使えなくなってしまいます!書き換えルールの置換対象 は、パターンがマッチした場合にオリジナルの URL から置き 換えられる文字列です。プレーンテキストの他に以下のものが使えます。
後方参照は
- RewriteRule パターンへの後方参照
$N
- 最後にマッチした RewriteCond パターンへの後方参照
%N
- ルール条件のテスト文字列としてのサーバ変数 (
%{変数名}
)- マッピング関数 の呼び出し (
${mapname:key|default}
)$
N(N=0..9) 識別子で表します。これは、マッチしたパターンのグループの 中で、N番目のものの内容に置き換えられます。サーバ 変数はRewriteCond
ディレクティブのテスト文字列 と同じです。マッピング関数はRewriteMap
ディレクティブ から来たもので、ここで説明しています。これら 3 タイプの変数は、 上記の順序で展開されます。前述のように、すべての書き換えルールは置換対象に 対して(設定ファイルに定義してある順に)適用されます。URL は 置換対象によって完全に置き換えられ、 書き換え処理は
L
フラグ -- 後述 -- によって明示的に終端されていない限り、ルールがなくなるまで 続けられます。'
-
' と呼ばれる特殊な置き換え文字列があります。 これは、置換禁止!の意味です。変でしょ?いいえ、 これは URL のマッチングだけを行い、置換を行なわ ないという機能を提供してくれるものです。すなわち、 C (chain) フラグといっしょに使うことによって、 置換が行なわれる前に複数のパターンを適用することができます。もうひとつ注意事項:クエリー文字列部分を付加した置換文字列 で URL を生成することもできます。単に、置換文字列の中にクエス チョンマークを入れるだけで、それ以降は QUERY_STRING に入れるべき ことを示します。既存のクエリー文字列を消去したい場合は、置換文字列 をクエスチョンマークだけで終わらせるようにします。
注意: 特殊機能について述べます: 置換フィールドの前に http://
thishost[:thisport] を置くと、mod_rewriteは自動的にこれを除去 します。この暗黙の外部リダイレクト URL における自動変換機能は、 ホスト名部分を生成するマッピング関数と同時に使う場合に便利で かつ重要なものです。これを理解するには、以下のサンプルの章の 最初の例を見てください。
備考:この機能の影響で、自分自身のサーバ への無条件の外部リダイレクションは、 http://thishost
プリフィックスがついていると動作しません。このような自己 リダイレクトを行なうには、Rフラグを使う 必要があります(後述)。
RewriteRule
ディレクティブの第三引数として、 置換対象に対して上記以外にも以下のようなをつけることができます。フラグは以下のものをカンマで 区切って指定します:[
フラグ]
- '
redirect|R
[=code]' (強制 redirect)
置換対象の前に(新しい URL を URI にする)http://thishost[:thisport]/
をつけることにより、 強制的な外部リダイレクションを行ないます。codeが 指定されない場合、HTTP レスポンスの 302 (MOVED TEMPORARILY) が使われます。300 から 400 に間で他のレスポンスコードを返し たい場合は、直接その番号を指定するか、シンボル名temp
(デフォルト),permanent
,seeother
のいずれかを使います。たとえば、``/~
'' を ``/u/
'' に変換したり、常に/u/
user にスラッシュを追加するなどの、望ましい URL の 正規化を行なうためのルールについては、これを使ってクライアント に結果を返します。
注意:このフラグを使う場合は、置換 フィールドが有効な URL であることを確認してください。もし そうでない場合、無効な場所にリダイレクトしていることになり ます。さらに、このフラグはそれ自身、URL の前に
http://thishost[:thisport]/
を付加するだけで、 その後も書き換え処理は続きます。通常はそこでやめて即時に リダイレクトすることになるでしょう。書き換えを終了するには、 'L' フラグもいっしょに指定しなければなりません。- '
forbidden|F
' (URL を強制的に forbidden(禁止)にする)
これは現在の URL を強制的にアクセス禁止にします。 すなわち、即時に HTTP レスポンスの 403 (FORBIDDEN) を返します。このフラグを適切な RewriteCond といっしょに使って、 特定の URL に対する条件ブロックを行ないます。- '
gone|G
' (URL を強制的に gone(消去済み)にする)
これは現在の URL を強制的に消去済み(gone)にします。 すなわち、即時に HTTP レスポンスの 410 (GONE) を返します。このフラグを使ってもはや存在しないページを 消去済みとしてマークします。- '
proxy|P
' (強制 proxy)
このフラグは、強制的に置換対象部を内部的にプロキシリクエスト とみなし、その場で(すなわち、ここで書き換えルールを 停止して)プロキシモジュールを 通して出力します。置換対象文字列は(たとえば、典型的 にはhttp://
ホスト名で始まるような、) Apacheプロキシモジュールで扱える有効なURIでなければなりません。 そうでなければ、プロキシーモジュールからエラーが報告されます。 このフラグを使ってより強力な ProxyPassディレクティブの実装を行うことで、ローカルサーバ の名前空間をどこかのリモートのところへマッピングしてやるよう にします。注意:この機能を使うにあたっては、ご自分のApacheサーバに コンパイルされたプロキシモジュールが組み込まれていることを 確認してください。確認方法がわからない場合は、``
httpd -l
'' の出力の中にmod_proxy.c
があるか どうかを調べてみましょう。もしあれば、この機能が mod_rewrite に対して使えます。もしなければ、mod_proxy を有効にして ``httpd
''プログラムを再構築する必要があります。- '
last|L
' (last(最後の)ルール)
ここで書き換え処理を中止し、それ以上の書き換えルールを適用 しないようにします。これは Perl のlast
コマンド や C 言語のbreak
コマンドに対応するものです。 このフラグを使うことで、現在の書き換え後の URL が後続のルール によってそれ以上書き換えられることを防止します。たとえば、 これを使ってルートパスの URL ('/
') を実際のもの、 たとえば'/e/www/
'に書き換えます。- '
next|N
' (next(次の)一周)
書き換え処理を(一番最初の書き換えルールから再度)再実行 します。ただしその際マッチングされる URL は当初の URL で はなく、最後に書き換えられた URL です。これは Perl のnext
コマンドや C 言語のcontinue
コマンドに対応するものです。 このフラグを使うことで、書き換え処理を再起動します。 すなわち、ループの先頭にジャンプします。
永久ループを作らないように留意してください!- '
chain|C
' (次のルールにchained (チェイン))
このフラグを指定すると、現在のルールは次のルールにチェインされます (なお次のルールも、後続のルールなどにチェインすることも できます)。これには以下の効果があります:ルールがマッチすると、 処理は通常どおり行なわれます。すなわちフラグは意味を持ち ません。ルールがマッチしない場合、後続のすべての ルールはスキップされます。たとえば(``.www
'' の部分を 除く)外部リダイレクトを発生させたい時に、ディレクトリ毎のルール セットの中から ``.www
'' の部分を取り除くことができます。- '
type|T
=MIME-type' (MIME type の強制指定)
ターゲットファイルの MIME タイプを強制的にMIME-typeに します。たとえばこれを使って、mod_alias
のディレク ティブであるScriptAlias
をシミュレートすることが できます。これは、マッピングされたディレクトリの中にあるすべての ファイルの MIME タイプを、内部的に``application/x-httpd-cgi
'' に強制セットするものです。- '
nosubreq|NS
' (内部の sub-request が no (ない) 時のみ 使われる)
このフラグを使うと、現在のリクエストが内部のサブリクエストである 場合に、書き換えエンジンが書き換えルールをスキップするように強制 します。たとえば、mod_include
がディレクトリのデフォルト の候補となるファイルの情報(index.xxx
)を検索しようと する際に、Apache の中で内部的にサブリクエストが発生することがあり ます。サブリクエストにおいては書き換え操作は常に有用であるとは 限らず、完全なルールが適用されてしまうと書き換えに失敗してしまう 場合もあります。このフラグを使ってそのようなルールを除外します。
以下のルールを使って、このフラグを使うかどうか決めてください: CGI スクリプトの先頭になんらかの URL を付加して、それを CGI スクリプトで処理させようとする場合、サブリクエストの際に問題が 起こったり(オーバーヘッドがかかったり)する可能性が高くなります。 このようなケースでは、このフラグを使ってください。
- '
nocase|NC
' (no case)
これはパターンについて大文字小文字を区別しないようにします。 すなわち、パターンが現在の URL とマッチされる際、 'A-Z' と 'a-z' 区別されません。- '
qsappend|QSA
' (query string append)
このフラグは、置換文字列の中でマッチしたものを書き換えるのではなく、 そこにクエリー文字列部分を追加するように、書き換えエンジンに強制 します。書き換えルールを通してクエリー文字列に何かデータを追加したい 場合にこのフラグを使います。- '
noescape|NE
' (no URI escaping of output)
このフラグは、mod_rewrite が書き換え結果に対して通常行なわれる URL エスケープルールを適用しないようにします。通常は('%', '$', ';' といった)特殊文字については、それらと等価の 16 進数文字列 (順に '%25', '%24', '%3B')にエスケープされます。このフラグは この動作を抑制します。これにより、出力の中にパーセント文字を 使うことができます。以下に例を挙げます。RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]この例では、'/foo/zed
' が安全なリクエストである '/bar?arg=P1=zed
' に変更されます。
注意: The noescape
フラグは Apache 1.3.20 以降でのみ 有効です。- '
passthrough|PT
' (pass through to next handler)
このフラグは、内部のrequest_rec
構造体のuri
フィールドにfilename
フィールドの値をセット するように、書き換えエンジンに指示します。このフラグは単に、RewriteRule
ディレクティブの出力に対して、他の URI からファイル名への変換処理を行なうAlias
,ScriptAlias
,Redirect
といった ディレクティブによる後処理を入れるための小技です。文法を示すため の単純な例:mod_rewrite
の書き換えエンジンで/abc
から/def
への変換を行い、さらにmod_alias
で/def
から/ghi
に書き換えるには、以下のようにします:RewriteRule ^/abc(.*) /def$1 [PT] Alias /def /ghiもしPT
フラグを指定するのを忘れてしまった場合、mod_rewrite
はちゃんとその仕事を行ないます。 すなわち、完全な API に準拠した URI-to-filename 変換 ルーチンが行なうべき、uri=/abc/...
をfilename=/def/...
に書き換えます。その後mod_alias
が起動され、URI-to-filename 変換を 試みますが、これは動作しません 。注意:URL-to-filename 変換を含む異なったモジュールの ディレクティブを混用したい場合には、このフラグを指定する必要が あります。典型的な例としては、
mod_alias
とmod_rewrite
の同時使用です。
注意 - Apache ハッカーへ:
現在の Apache API が URI-to-filename フックに加えて filename-to-filename フックを持っていれば、このフラグを 使う必要はないのです!しかしこのようなフックがない現在、 このフラグが唯一の解決策となります。Apache グループは この問題について議論しており、Apache バージョン 2.0 には そのようなフックが追加されることでしょう。- '
skip|S
=数字' (skip next rule(s))
このフラグは書き換えエンジンに対し、現在のルールがマッチしたら、 次の数字番目のルールをスキップするよう指示します。これを 使って、擬似的に if-then-else 構造を作ることができます:then-句 の最終ルールはskip=N
となります。ここで N は else-句 に入れるルールの数です。(これは 'chain|C' フラグとは 異なります)。- '
env|E=
VAR:VAL' (set environment variable)
これは VAR という名前の環境変数の値を VAL に するよう指示します。ここでVAL には、正規表現の後方参照 として展開される$N
と%N
を書くことが できます。このフラグを複数使って、複数の変数を定義することも できます。この変数は多くの場合、通常後から XSSI(<!--#echo var="VAR"-->
を通して)または CGI(たとえば$ENV{'VAR'}
)のように、参照されます。さらに、 RewriteCond パターン%{ENV:VAR}
を通して参照することも できます。これを使って URL からの情報を切り取って記憶します。
注意:サーバ単位の設定ファイルの中では、 パターンは完全な URL に適用されることを忘れないで ください。しかしながら、ディレクトリ単位の設定ファイル の中では、パターンマッチングのためにディレクトリ単位の接頭辞 (これは特定のディレクトリでは常に同じものです!)が自動的に 取り除かれ、置換が終わった後に自動的に付加 されます。この機構は、さまざまな種類の書き換え操作に おいて欠くことのできないものです。なぜなら、この接頭辞のスキップ が行なわれないと、常に存在するとは限らない親ディレクトリとの マッチングを行なわなければならなくなるからです。 ひとつ例外があります:置換文字列が ``
http://
'' で始まっている場合、ディレクトリ接頭辞は付加されず 、外部リダイレクトまたは(Pフラグが 使われていれば!)プロキシ処理が強制的に行なわれます。
注意:ディレクトリ単位の設定ファイル における書き換えエンジンを有効にする場合、これらのファイルに `` RewriteEngine On
'' をセットし、かつ ``Options FollowSymLinks
'' を有効に しなければなりません。あなたのところの管理者がユーザの ディレクトリのFollowSymLinks
をオーバーライド を禁止していた場合、書き換えエンジンを使うことはできません。 この制限が必要なのは、セキュリティ関連の理由によります。以下に有効な置換の組合せと、それらの意味を示します:
リクエスト ``
GET /somepath/pathinfo
'' が行なわれた場合の、
サーバ単位の設定(httpd.conf
)の内部:
与えられたルール 置換結果 ---------------------------------------------- ---------------------------------- ^/somepath(.*) otherpath$1 無効なのでサポートしない ^/somepath(.*) otherpath$1 [R] 無効なのでサポートしない ^/somepath(.*) otherpath$1 [P] 無効なのでサポートしない ---------------------------------------------- ---------------------------------- ^/somepath(.*) /otherpath$1 /otherpath/pathinfo ^/somepath(.*) /otherpath$1 [R] 外部リダイレクション経由で http://thishost/otherpath/pathinfo ^/somepath(.*) /otherpath$1 [P] 無意味なのでサポートしない ---------------------------------------------- ---------------------------------- ^/somepath(.*) http://thishost/otherpath$1 /otherpath/pathinfo ^/somepath(.*) http://thishost/otherpath$1 [R] 外部リダイレクション経由で http://thishost/otherpath/pathinfo ^/somepath(.*) http://thishost/otherpath$1 [P] 無意味なのでサポートしない ---------------------------------------------- ---------------------------------- ^/somepath(.*) http://otherhost/otherpath$1 外部リダイレクション経由で http://otherhost/otherpath/pathinfo ^/somepath(.*) http://otherhost/otherpath$1 [R] 外部リダイレクション経由で http://otherhost/otherpath/pathinfo ([R] フラグは冗長) ^/somepath(.*) http://otherhost/otherpath$1 [P] 内部プロキシ経由で http://otherhost/otherpath/pathinfoリクエスト ``
GET /somepath/localpath/pathinfo
'' が行なわれた場合の、
/somepath
に関するディレクトリ単位の設定の内部:
(たとえば、/physical/path/to/somepath
ディレクトリにあって、
RewriteBase /somepath
の記述がある.htaccess
ファイル):
与えられたルール 置換結果 ---------------------------------------------- ---------------------------------- ^localpath(.*) otherpath$1 /somepath/otherpath/pathinfo ^localpath(.*) otherpath$1 [R] 外部リダイレクション経由で http://thishost/somepath/otherpath/pathinfo ^localpath(.*) otherpath$1 [P] 無意味なのでサポートしない ---------------------------------------------- ---------------------------------- ^localpath(.*) /otherpath$1 /otherpath/pathinfo ^localpath(.*) /otherpath$1 [R] 外部リダイレクション経由で http://thishost/otherpath/pathinfo ^localpath(.*) /otherpath$1 [P] 無意味なのでサポートしない ---------------------------------------------- ---------------------------------- ^localpath(.*) http://thishost/otherpath$1 /otherpath/pathinfo ^localpath(.*) http://thishost/otherpath$1 [R] 外部リダイレクション経由で http://thishost/otherpath/pathinfo ^localpath(.*) http://thishost/otherpath$1 [P] 無意味なのでサポートしない ---------------------------------------------- ---------------------------------- ^localpath(.*) http://otherhost/otherpath$1 外部リダイレクション経由で http://otherhost/otherpath/pathinfo ^localpath(.*) http://otherhost/otherpath$1 [R] 外部リダイレクション経由で http://otherhost/otherpath/pathinfo ([R] フラグは冗長) ^localpath(.*) http://otherhost/otherpath$1 [P] 内部プロキシ経由で http://otherhost/otherpath/pathinfo例:
ここでは、という書式の URL を/
Language/~
Realname/.../
Fileに書き換えたいものとします。/u/
Username/.../
File.
Language前述のマップファイルを
/path/to/file/map.txt
という名前でセーブしておきます。その後、Apache サーバ設定 ファイルに以下の行を追加するだけです:RewriteLog /path/to/file/rewrite.log RewriteMap real-to-user txt:/path/to/file/map.txt RewriteRule ^/([^/]+)/~([^/]+)/(.*)$ /u/${real-to-user:$2|nobody}/$3.$1
その他の情報
環境変数
このモジュールは、SCRIPT_URL
とSCRIPT_URI
という2つの(非標準の)CGI/SSI 環境変数を設定します。これらの中には 現在のリソースへの論理的な Web ビューが入っています。一方、 標準の CGI/SSI 変数であるSCRIPT_NAME
とSCRIPT_FILENAME
には、物理的なシステムビューが 入っています。注意:これらの変数の中には、最初にリクエストを受けた時点 すなわち、書き換えが行なわれる前の URI/URL が保持 されています。URL 書き換え処理は、論理的な URL を物理的なパス名に 書き換えるために使われることが多いため、この点は重要です。
例:
SCRIPT_NAME=/sw/lib/w3s/tree/global/u/rse/.www/index.html SCRIPT_FILENAME=/u/rse/.www/index.html SCRIPT_URL=/u/rse/ SCRIPT_URI=http://en1.engelschall.com/u/rse/
実践的な解決法
この文書以外にも、URL Rewriting Guide という文書があります。この中には、URL ベースの問題について、実践的な解決法が集められています。 ここで実際に役立つルールセットや mod_rewrite に関する追加情報を 見ることができるでしょう。