Apache HTTP サーバ バージョン 2.5

このドキュメントは mod_rewrite
リファレンスドキュメントを補足するものです。
RewriteMap ディレクティブの使用方法を
説明し、さまざまな RewriteMap
タイプの例を提供します。
はじめに
int: 内部関数
txt: プレーンテキストマップ
rnd: ランダム化プレーンテキスト
dbm: DBM ハッシュファイル
prg: 外部書き換えプログラム
dbd または fastdbd: SQL クエリ
まとめ
RewriteMap ディレクティブは、
RewriteRule または
RewriteCond ディレクティブの
コンテキストで呼び出せる外部関数を定義し、正規表現だけでは実行が
複雑すぎたり特殊すぎたりする書き換えを行います。この検索のソースは、
以下のセクションに記載されているタイプのいずれかで、
RewriteMap リファレンス
ドキュメントに列挙されています。
RewriteMap
ディレクティブの構文は以下の通りです:
RewriteMap MapName MapType:MapSource
MapName は、 マップに割り当てる任意の名前で、後のディレクティブで使用します。 引数は以下の構文でマップに渡されます:
${ MapName : LookupKey
}
${ MapName :
LookupKey | DefaultValue }
このような構文が出現すると、マップ MapName が参照され、 キー LookupKey が検索されます。キーが見つかった場合、 マップ関数の構文は SubstValue で置換されます。キーが 見つからなかった場合は、DefaultValue で置換されるか、 DefaultValue が指定されていない場合は空文字列で 置換されます。
例えば、RewriteMap を
以下のように定義できます:
RewriteMap examplemap "txt:/path/to/file/map.txt"
その後、このマップを RewriteRule
で以下のように使用できます:
RewriteRule "^/ex/(.*)" "${examplemap:$1}"
マップで何も見つからなかった場合に備えて、デフォルト値を指定 できます:
RewriteRule "^/ex/(.*)" "${examplemap:$1|/not_found.html}"
RewriteMap ディレクティブは
<Directory> セクションや
.htaccess ファイルでは使用できません。マップはサーバまたは
バーチャルホストのコンテキストで宣言する必要があります。作成したマップは、
それらのスコープ内の RewriteRule
および RewriteCond
ディレクティブで使用できます。それらのスコープでマップを
宣言することはできません。
以下のセクションでは、使用可能なさまざまな MapType を 説明し、それぞれの例を示します。
MapType に int を使用すると、MapSource は利用可能な
内部 RewriteMap 関数の
いずれかになります。モジュール作成者は、
ap_register_rewrite_mapfunc API を使用して追加の内部
関数を登録できます。
デフォルトで提供される関数は以下の通りです:
これらの関数のいずれかを使用するには、int 関数を参照する
RewriteMap を作成し、
RewriteRule で使用します:
URI をすべて小文字のバージョンにリダイレクト
RewriteMap lc int:tolower
RewriteRule "(.*)" "${lc:$1}" [R]
ここで提供されている例は説明目的のみであり、推奨ではありません。
URL を大文字小文字を区別しないようにしたい場合は、代わりに
mod_speling の使用を検討してください。
MapType に txt を使用すると、MapSource はプレーンテキストの
マッピングファイルへのファイルシステムパスで、1 行に 1 つのスペース区切りの
キー/値ペアが含まれます。オプションで、'#' 文字で始まるコメント行を
含めることができます。
有効なテキスト書き換えマップファイルの構文は以下の通りです:
# コメント行
MatchingKey SubstValue
MatchingKey SubstValue # コメント
RewriteMap が呼び出されると、
引数が各行の最初の引数から検索され、見つかった場合は置換値が
返されます。
例えば、マップファイルを使用して製品名を製品 ID に変換し、 覚えやすい URL を実現するには、以下のレシピを使用できます:
製品から ID への設定
RewriteMap product2id "txt:/etc/apache2/productmap.txt"
RewriteRule "^/product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]
ここでは、prods.php スクリプトが
id=NOTFOUND という引数を受け取った場合の処理を
理解していると仮定しています (検索マップで製品が見つからなかった場合)。
ファイル /etc/apache2/productmap.txt には
以下が含まれます:
##
## productmap.txt - 製品から ID へのマップファイル
##
television 993
stereo 198
fishingrod 043
basketball 418
telephone 328
したがって、http://example.com/product/television が
リクエストされると、RewriteRule
が適用され、リクエストは内部的に /prods.php?id=993
にマッピングされます。
.htaccess ファイルで使用する場合は、
何かにマッチするように書き換えパターンから先頭のスラッシュを
削除する必要があります:
RewriteRule "^product/(.*)" "/prods.php?id=${product2id:$1|NOTFOUND}" [PT]
検索されたキーは、マップファイルの mtime (変更時刻) が
変更されるか、httpd サーバが再起動されるまで httpd にキャッシュ
されます。これにより、多くのリクエストで呼び出されるマップの
パフォーマンスが向上します。
MapType に rnd を使用すると、MapSource はプレーンテキストの
マッピングファイルへのファイルシステムパスで、各行にはキーと
| で区切られた 1 つ以上の値が含まれます。キーが
マッチすると、これらの値の 1 つがランダムに選択されます。
例えば、以下のマップファイルとディレクティブを使用して、 リバースプロキシ経由で複数のバックエンドサーバ間のランダムな ロードバランシングを提供できます。画像は 'static' プール内の サーバの 1 つに送信され、それ以外は 'dynamic' プールの 1 つに 送信されます。
##
## map.txt -- 書き換えマップ
##
static www1|www2|www3|www4
dynamic www5|www6
設定ディレクティブ
RewriteMap servers "rnd:/path/to/file/map.txt"
RewriteRule "^/(.*\.(png|gif|jpg))" "http://${servers:static}/$1" [NC,P,L]
RewriteRule "^/(.*)" "http://${servers:dynamic}/$1" [P,L]
画像がリクエストされ、最初のルールがマッチすると、
RewriteMap はマップファイルで
文字列 static を検索し、指定されたホスト名の 1 つを
ランダムに返します。それが RewriteRule
のターゲットで使用されます。
サーバの 1 つがより多く選択されるようにしたい場合 (例えば、サーバの 1 つがより多くのメモリを持ち、より多くの リクエストを処理できる場合)、マップファイルにそのサーバを 複数回記述してください。
static www1|www1|www2|www3|www4
MapType に dbm を使用すると、MapSource はマッピングで
使用されるキー/値ペアを含む DBM データベースファイルへの
ファイルシステムパスです。これは txt マップと
まったく同じように動作しますが、DBM はインデックス化されており
テキストファイルはそうではないため、はるかに高速です。これにより、
目的のキーへのアクセスが高速になります。
特定の dbm タイプをオプションで指定できます:
RewriteMap examplemap "dbm=sdbm:/etc/apache/mapfile.dbm"
タイプは sdbm、gdbm、ndbm、
または db です。
ただし、Apache HTTP Server に付属の httxt2dbm ユーティリティを
使用することを推奨します。httpd 自体のビルド時に使用されたものと
マッチする正しい DBM ライブラリを使用するためです。
dbm ファイルを作成するには、まず txt セクションで
説明されているテキストマップファイルを作成し、次に
httxt2dbm を実行します:
$ httxt2dbm -i mapfile.txt -o mapfile.map
その後、RewriteMap
ディレクティブで結果のファイルを参照できます:
RewriteMap mapname "dbm:/etc/apache/mapfile.map"
dbm タイプによっては、共通のベース名で複数のファイルが生成される
ことがあることに注意してください。例えば、mapfile.map.dir
と mapfile.map.pag という 2 つのファイルが存在する
場合があります。これは正常であり、RewriteMap
ディレクティブではベース名 mapfile.map のみを使用
してください。
検索されたキーは、マップファイルの mtime (変更時刻) が
変更されるか、httpd サーバが再起動されるまで httpd にキャッシュ
されます。これにより、多くのリクエストで呼び出されるマップの
パフォーマンスが向上します。
MapType に prg を使用すると、MapSource はマッピング動作を
提供する実行可能プログラムへのファイルシステムパスです。これは
コンパイル済みバイナリファイル、または Python や Perl などの
インタプリタ言語のプログラムです。
このプログラムは Apache HTTP Server の起動時に一度起動され、
STDIN と STDOUT を通じて書き換えエンジンと
通信します。各マップ関数の検索では、キーがプログラムの
STDIN に書き込まれ、その後に改行文字が続きます。
プログラムは STDIN から 1 行 (改行を含む) を読み取り、
応答を改行で終わる 1 行として STDOUT に書き込む
必要があります。キーに改行文字が含まれることはありません。
改行を含むキーが検出された場合、検索は失敗します。
対応する検索値がない場合、マッププログラムは 4 文字の
文字列 "NULL" を返して、これを示す必要があります。
この比較は大文字小文字を区別しないため、"null"、"Null" 等も
検索失敗として扱われます。その結果、マッピングプログラムが
リテラル文字列 "NULL" をマップされた値として返すことは
できません。
プログラムの STDERR は httpd 親プロセスから
継承されるため、プログラムが STDERR に書き込む内容は
httpd 自体のエラー出力 (通常は ErrorLog) と同じ場所に記録されます。
外部書き換えプログラムは、RewriteEngine が on に
設定されていないコンテキストで定義されている場合は起動されません。
デフォルトでは、外部書き換えプログラムは httpd を起動した
ユーザ:グループとして実行されます。これは UNIX システムでは
RewriteMap の 3 番目の
引数として username:groupname 形式でユーザ名と
グループ名を渡すことで変更できます。
この機能は rewrite-map ミューテックスを使用しており、
プログラムとの信頼性のある通信に必要です。ミューテックスの
メカニズムとロックファイルは Mutex
ディレクティブで設定できます。
リクエスト URI 内のすべてのダッシュをアンダースコアに置き換える シンプルな例を以下に示します。
書き換え設定
RewriteMap d2u "prg:/www/bin/dash2under.py" apache:apache
RewriteRule "-" "${d2u:%{REQUEST_URI}}"
dash2under.py
#!/usr/bin/env python3
import sys
for line in sys.stdin:
print(line.strip().replace('-', '_'), flush=True)
print() に flush=True を
渡すことでこれを行っています。バッファされた I/O は httpd が
出力を待つ原因となり、ハングします。SIGTERM が送信されます。3 秒以内に終了しない場合は
SIGKILL が送信されます。MapType に dbd または fastdbd を使用すると、
MapSource は単一の引数を取り、単一の値を返す SQL SELECT 文です。
この文を実行するために、mod_dbd を正しい
データベースを指すように設定する必要があります。
この MapType には 2 つの形式があります。
MapType に dbd を使用すると、各マップリクエストで
クエリが実行されますが、fastdbd を使用すると
データベース検索が内部的にキャッシュされます。したがって、
fastdbd はより効率的で高速ですが、サーバが
再起動されるまでデータベースの変更を検出しません。
クエリが複数の行を返す場合、結果セットからランダムな行が 使用されます。
RewriteMap myquery "fastdbd:SELECT destination FROM rewrite WHERE source = %s"
クエリ名は SQL プリペアドステートメントのラベルとして データベースドライバに渡されるため、データベースで必要な ルール (大文字小文字の区別など) に従う必要があります。
RewriteMap ディレクティブは
複数回使用できます。各マッピング関数に対して 1 つの
RewriteMap ディレクティブを
使用して書き換えマップファイルを宣言してください。
ディレクトリ単位のコンテキスト (.htaccess ファイルや
<Directory> ブロック)
ではマップを宣言できませんが、ディレクトリ単位の
コンテキストでこのマップを使用することは可能です。