apache2系のmodule開発

1.3系については、通称パンダ本に結構書いてあるので、情報量が少なめの2系モジュールに関する開発について。

基本は、1.3系と違い、2系はhook関数というものを作ってそれをモジュールから登録し、apacheコアにhookさせて、登録した関数を実行させるという流れ。

モジュールというのは、結局のところ「apacheコアが呼び出すhook関数を登録するためにある」といってもいいくらいかな。

流れとしては、以下のようにhook関数を登録して、

static void register_hooks(apr_pool_t *p)
{
    ap_hook_access_checker(lalimit_access_checker, NULL, NULL, APR_HOOK_MIDDLE);
}


それを以下のようにモジュールとして、apacheに登録し、apacheが関数を呼び出してほしいタイミングでよんでもらえるようにする。

module AP_MODULE_DECLARE_DATA lalimit_module = {
    STANDARD20_MODULE_STUFF,
    lalimit_create_dir_config,  /* create per-dir  config structures */
    NULL,                       /* merge  per-dir config structures */
    NULL,                       /* create  per-server config structures */
    NULL,                       /* merge  per-server config structures */
    lalimit_cmds,               /* table of config file commands */
    register_hooks              /* register hooks */
};

されに、confで使用したいディレクティブを新たに設定したい場合は、「table of config file commands」の項目に設定したいディレクティブの設定を保持した構造体を定義する。

static const command_rec lalimit_cmds[] = {
    AP_INIT_TAKE1(
        "LAlimit",
        (void *)set_lalimit,
        NULL,
        ACCESS_CONF,
        "Set return 503 over setting Load Average."),
    {NULL}
};

これらが、apacheにフックしたい関数を登録するための、簡単な例である。

上記の流れをもう一度まとめると、

モジュールに登録した関数から、「create per-dir config structures」にあたる関数”lalimit_create_dir_config”によって、ディレクティブが設定されているかを調査する。

そこで、「command_rec」で設定した新たなディレクティブ(上の例では”LAlimit”)が見つかった場合は、そのためのconfigを保持するための領域を確保する。

領域確保後、「table of config file commands」に登録されている構造体”lalimit_cmds”からディレクティブ”LAlimit”が記述されていた場合、”set_lalimit”にパラメータ解析をしてもらう。

“set_lalimit”では「lalimit_create_dir_config」で確保されたconfigの領域に、”LAlimit”で記述されたパラメータの解析結果を保存していく。

これらの処理は、apache起動時に実行される。

そして、実際にapacheに対してrequestがあったときは、「register hooks」で登録している関数”register_hooks”内で設定された関数”lalimit_access_checker”がapacheコアによってhookされ、処理が実行される。

そのときに参照されるconfigは関数”lalimit_create_dir_config”で作成された雛形に、関数”set_lalimit”で解析し保存されたconfigである。

以上が、モジュール開発の基本であり、apacheとmoduleの関係である。