Apache HTTP サーバ バージョン 2.0
モジュールの Apache 1.3 から Apache 2.0 への移植
この文書は mod_mmap_static
モジュールを Apache 2.0 用に移植した時に
学んだ経験をもとに書いた、最初の手引き書です。まだまだ完全じゃないし、
ひょっとすると間違っている部分もあるかもしれませんが、
取っ掛りにはなるでしょう。
簡単な変更点
クリーンナップ ルーチン
クリーンナップルーチンは apr_status_t
型である必要があります。
そして、apr_status_t 型の値を返さなくてはなりません。
クリーンナップ中のエラーを通知する必要がなければ、返り値は普通、
ARP_SUCCESS
です。たとえエラーを通知したとしても、
すべてのコードがその通知をチェックしたり、
エラーに応じた動作をするわけではないことに気をつけてください。
初期化ルーチン
初期化ルーチンは処理全体から見てしっくりくるような意味を表すように、
名前が変更されました。ですから、mmap_init
から mmap_post_config
のようにちょっと変更されました。
渡される引数は大幅に変更され、次のようになりました。
apr_pool_t *p
apr_pool_t *plog
apr_pool_t *ptemp
server_rec *s
データ型
データ型のほとんどは APR に移されました。つまり、 いくつかの名前が前述のように変更されています。 施すべき変更点の簡単な一覧を以下に示します。
pool
becomesapr_pool_t
table
becomesapr_table_t
もっと厄介な変更点…
フックの登録
新しいアーキテクチャでは作成した関数を呼び出すのに
一連のフックを使用します。このフックは、新しい関数
static void register_hooks(void)
を使って登録するよう、
モジュールに書き足さなくてはなりません。
この関数は、なにをすべきか一旦理解してしまえば、
十分にわかりやすいものです。
リクエストの処理のあるステージで呼び出さなくてはならない
関数は登録する必要があります。ハンドラは登録する必要はありません。
関数を登録できるフェーズはたくさんあります。
それぞれのフェーズで、関数を呼び出す相対的な順番は、
かなりの程度制御できます。
以下は、mod_mmap_static
に追加したコードです:
static void register_hooks(void) { static const char * const aszPre[]={ "http_core.c",NULL }; ap_hook_post_config(mmap_post_config,NULL,NULL,HOOK_MIDDLE); ap_hook_translate_name(mmap_static_xlat,aszPre,NULL,HOOK_LAST); };
ここでは呼びだすべき二つの関数を登録しています。一つは
post_config
ステージ用 (ほとんどすべてのモジュール
はこれが必要です) で、もう一つは translate_name
フェーズ用です。
それぞれの関数は名前は違うけれども形式は同じであることに注意してください。
それでは、形式はどのようになっているでしょうか?
ap_hook_phase_name(function_name,
predecessors, successors, position);
三つの位置が定義されています…
HOOK_FIRST
HOOK_MIDDLE
HOOK_LAST
位置を定義するには、上記の「位置」を指定し、 修飾子である「先行」と「後行」で手を加えます。 「先行」「後行」は、呼ばれるべき関数のリストです。 「先行」は関数の実行前に呼ばれるもので、 「後行」は実行後に呼ばれるものです。
mod_mmap_static
の場合、post_config
ステージでは必要ありませんが、
mmap_static_xlat
が core モジュールが名前の変換を実行した後に
呼ばれなければなりません。
そこで aszPre を使って HOOK_LAST
の修飾子を定義しています。
モジュールの定義
モジュールの定義を作成する際に注意しなければならない ステージの数は激減しています。古い定義は次のようになっていました。
module MODULE_VAR_EXPORT module_name_module = { STANDARD_MODULE_STUFF, /* initializer */ /* dir config creater */ /* dir merger --- default is to override */ /* server config */ /* merge server config */ /* command handlers */ /* handlers */ /* filename translation */ /* check_user_id */ /* check auth */ /* check access */ /* type_checker */ /* fixups */ /* logger */ /* header parser */ /* child_init */ /* child_exit */ /* post read-request */ };
新しい構造体はとってもシンプルです…
module MODULE_VAR_EXPORT module_name_module = { STANDARD20_MODULE_STUFF, /* create per-directory config structures */ /* merge per-directory config structures */ /* create per-server config structures */ /* merge per-server config structures */ /* command handlers */ /* handlers */ /* register hooks */ };
このうちのいくつかは古いものから新しいものに直接読み替えられるもので、 いくつかはそうではありません。どうすればいいのかを要約してみます。
直接読み替えられるステージ:
/* ディレクトリ設定作成関数 */
/* ディレクトリ毎設定構造体作成 */
/* サーバ設定作成関数 */
/* サーバ毎設定構造体作成 */
/* ディレクトリ設定マージ関数 */
/* ディレクトリ毎設定構造体マージ */
/* サーバ設定マージ関数 */
/* サーバ毎設定構造体作成マージ */
/* コマンド・テーブル */
/* コマンド apr_table_t */
/* ハンドラ */
/* ハンドラ */
古い関数の残りのものはフックとして登録されるべきです。 現時点で次のようなフック・ステージが定義されています…
ap_hook_post_config
- (以前の
_init
ルーチンが登録されるべき場所です) ap_hook_http_method
- (リクエストから HTTP メソッドを取得します (互換用))
ap_hook_open_logs
- (特定のログのオープン)
ap_hook_auth_checker
- (リソースが権限を必要とするかどうかの確認)
ap_hook_access_checker
- (モジュール固有の制約の確認)
ap_hook_check_user_id
- (ユーザ ID とパスワードの確認)
ap_hook_default_port
- (サーバのデフォルト・ポートの取得)
ap_hook_pre_connection
- (処理の直前に必要なことを実行。ただし accept 直後に呼ばれる)
ap_hook_process_connection
- (プロトコルの処理)
ap_hook_child_init
- (子プロセル起動直後)
ap_hook_create_request
- (??)
ap_hook_fixups
- (応答内容の生成を変更するラスト・チャンス)
ap_hook_handler
- (応答内容の生成)
ap_hook_header_parser
- (モジュールにヘッダの照会をさせる。ほとんどのモジュールでは使われません。post_read_request を使います)
ap_hook_insert_filter
- (フィルタ・チェインにフィルタを挿入)
ap_hook_log_transaction
- (リクエストについての情報を記録する)
ap_hook_optional_fn_retrieve
- (オプションとして登録された関数の取得)
ap_hook_post_read_request
- (リクエストを読みこんだ後、他のフェーズの前に呼ばれる)
ap_hook_quick_handler
- リクエストの処理が始まる前に呼ばれる。キャッシュモジュールが 使用している
ap_hook_translate_name
- (URI をファイル名に変換する)
ap_hook_type_checker
- (文書型の決定と設定。あるいはその片方)