Apache HTTP サーバ バージョン 2.5

このドキュメントでは、mod_rewrite と URL マッチングの
技術的な詳細について説明します。
Apache HTTP Server は、いくつかのフェーズでリクエストを処理します。 各フェーズでは、リクエストライフサイクルのその部分を処理するために 1 つ以上のモジュールが呼び出される可能性があります。フェーズには、 URL からファイル名への変換、認証、認可、コンテンツ、ロギングなどが 含まれます。(これは完全なリストではありません。)
mod_rewrite は、URL の書き換え方法に影響を与えるために、
これらのフェーズ (しばしば「フック」と呼ばれます) のうち 2 つで
動作します。
まず、URL からファイル名への変換フックを使用します。これは
HTTP リクエストが読み取られた後、認可が開始される前に発生します。
次に、Fixup フックを使用します。これは認可フェーズの後、
ディレクトリ単位の設定ファイル (.htaccess ファイル)
が読み取られた後、コンテンツハンドラが呼び出される前です。
リクエストが到着し、対応するサーバまたはバーチャルホストが
決定された後、書き換えエンジンはサーバ単位の設定に含まれる
mod_rewrite ディレクティブの処理を開始します。
(つまり、メインサーバ設定ファイルと
<Virtualhost>
セクション内のディレクティブです。) これは URL からファイル名への
変換フェーズで発生します。
数ステップ後、最終的なデータディレクトリが見つかると、
ディレクトリ単位の設定ディレクティブ (.htaccess
ファイルと <Directory> ブロック) が適用されます。
これは Fixup フェーズで発生します。
これらの各ケースで、mod_rewrite は
REQUEST_URI を新しい URL またはファイル名に
書き換えます。
ディレクトリ単位のコンテキスト (つまり .htaccess
ファイルと Directory ブロック内) では、URL が既に
ファイル名に変換された後にこれらのルールが適用されます。このため、
mod_rewrite が最初に RewriteRule ディレクティブと比較する
URL パスは、変換されたファイル名のフルファイルシステムパスから、
現在のディレクトリのパス (末尾のスラッシュを含む) を先頭から
削除したものになります。
例として: ルールが /var/www/foo/.htaccess にあり、 /foo/bar/baz へのリクエストが処理されている場合、^bar/baz$ のような 式がマッチします。
ディレクトリ単位のコンテキストで置換が行われた場合、新しい URL で
新しい内部サブリクエストが発行され、リクエストフェーズの処理が
再開されます。置換が相対パスの場合、RewriteBase ディレクティブが
置換の前に付加する URL パスプレフィックスを決定します。
ディレクトリ単位のコンテキストでは、ループを避けるために、
最終的に (将来のディレクトリ単位の書き換え処理の「ラウンド」で)
置換を行わないルールを作成するよう注意する必要があります。
(この問題の詳細については
RewriteLooping
を参照してください。)
ディレクトリ単位のコンテキストでの URL のさらなる操作のため、 そのコンテキストでは書き換えルールを異なるように作成するよう 注意する必要があります。特に、先頭のディレクトリパスが書き換えルールが 認識する URL から削除されることを忘れないでください。詳細については 以下の例を参照してください。
| ルールの場所 | ルール |
|---|---|
| VirtualHost セクション | RewriteRule "^/images/(.+)\.jpg" "/images/$1.gif" |
| ドキュメントルートの .htaccess ファイル | RewriteRule "^images/(.+)\.jpg" "images/$1.gif" |
| images ディレクトリの .htaccess ファイル | RewriteRule "^(.+)\.jpg" "$1.gif" |
mod_rewrite がさまざまなコンテキストで URL をどのように
操作するかについてさらに詳しくは、書き換え中に作成される
ログエントリを
参照してください。
これら 2 つの API フェーズで mod_rewrite がトリガー
されると、設定構造体 (サーバ単位のコンテキストではスタートアップ時に
作成されたもの、ディレクトリ単位のコンテキストでは Apache カーネルの
ディレクトリウォーク中に作成されたもの) から設定済みのルールセットを
読み取ります。次に、含まれるルールセット (1 つ以上のルールとその
条件のセット) を使用して URL 書き換えエンジンが起動されます。
URL 書き換えエンジン自体の動作は、両方の設定コンテキストで
まったく同じです。最終結果の処理のみが異なります。
ルールセット内のルールの順序は重要です。書き換えエンジンは
特殊な (あまり直感的ではない) 順序でルールを処理するためです。
ルールは次のとおりです: 書き換えエンジンはルールセットをルールごとに
(RewriteRule
ディレクティブ) ループし、特定のルールがマッチすると、対応する
条件 (RewriteCond ディレクティブ) をオプションで
ループします。歴史的な理由により、条件が先に記述されるため、
制御フローは少し冗長になります。詳細は図 1 を参照してください。

図 1: 書き換えルールセットを通る制御フロー
まず、URL が各ルールの Pattern に対してマッチされます。
マッチしない場合、mod_rewrite はそのルールの処理を
直ちに停止し、次のルールに進みます。Pattern がマッチすると、
mod_rewrite は対応するルール条件 (設定内の RewriteRule の
直前に記述される RewriteCond ディレクティブ) を探します。
条件がない場合、URL を Substitution 文字列から構築された
新しい値で置換し、ルールループを続行します。条件が存在する場合、
記述された順序で処理する内部ループを開始します。条件のロジックは
異なります: 現在の URL に対してパターンをマッチさせるのではなく、
まず変数の展開、バックリファレンス、マップ検索等を行って
TestString 文字列を作成し、それに対して
CondPattern をマッチさせようとします。パターンがマッチしない
場合、条件のセット全体と対応するルールが失敗します。パターンが
マッチすると、次の条件が処理され、条件がなくなるまで続きます。
すべての条件がマッチした場合、URL の Substitution による
置換の処理が続行されます。