諸事情で(早くこの諸事情を公表できるようにがんばる系)、Apacheの拡張の書き方や mod_mruby の設計思想、実装について知りたくなった。
ちまちまと読んでいく。もともと社内のNotionに雑にメモしていこうと思ったが、フィードバックも欲しいので晒していく。またこのブログにシリーズものが増えたのですあった...。
まずモジュールの定義全体。
https://github.com/matsumotory/mod_mruby/blob/master/src/mod_mruby.c#L918-L928
#ifdef __APACHE24__ AP_DECLARE_MODULE(mruby) = { #else module AP_MODULE_DECLARE_DATA mruby_module = { #endif STANDARD20_MODULE_STUFF, mod_mruby_create_dir_config, /* dir config creater */ NULL, /* dir merger */ mod_mruby_create_config, /* server config */ NULL, /* merge server config */ mod_mruby_cmds, /* command apr_table_t */ register_hooks /* register hooks */ };
ちなみにこれが何を意味するかはここに詳しい。
抜粋すると
module AP_MODULE_DECLARE_DATA example_module = { STANDARD20_MODULE_STUFF, create_dir_conf, /* Per-directory configuration handler */ merge_dir_conf, /* Merge handler for per-directory configurations */ create_svr_conf, /* Per-server configuration handler */ merge_svr_conf, /* Merge handler for per-server configurations */ directives, /* Any directives we may have for httpd */ register_hooks /* Our hook registering function */ };
ディレクトリ単位の設定、サーバ単位の設定などがあるらしい。コメントはわかるようなわからないようなだが、読み進めていけばわかりそう。
merge_*
が何をどうマージするのかピンとこなかったが、mod_mrubyでは利用していなそうなので一旦次へ...。
で、mod_mruby_create_dir_config
, mod_mruby_create_config
, は mruby_*conf_t
を生成して返す。
ここに並んでいるフックポイントが実質apacheに存在する全てのフックポイントだと思われる。
mruby_dir_config_t *dir_conf = (mruby_dir_config_t *)apr_pcalloc(p, sizeof(*dir_conf)); // inline core in httpd.conf dir_conf->mod_mruby_handler_inline_code = NULL; dir_conf->mod_mruby_handler_first_inline_code = NULL; dir_conf->mod_mruby_handler_middle_inline_code = NULL; dir_conf->mod_mruby_handler_last_inline_code = NULL; dir_conf->mod_mruby_post_read_request_first_inline_code = NULL; dir_conf->mod_mruby_post_read_request_middle_inline_code = NULL; dir_conf->mod_mruby_post_read_request_last_inline_code = NULL; dir_conf->mod_mruby_translate_name_first_inline_code = NULL; dir_conf->mod_mruby_translate_name_middle_inline_code = NULL; dir_conf->mod_mruby_translate_name_last_inline_code = NULL; dir_conf->mod_mruby_map_to_storage_first_inline_code = NULL; dir_conf->mod_mruby_map_to_storage_middle_inline_code = NULL; dir_conf->mod_mruby_map_to_storage_last_inline_code = NULL;
とか
mruby_config_t *conf = (mruby_config_t *)apr_pcalloc(p, sizeof(mruby_config_t)); conf->mod_mruby_child_init_first_code = NULL; conf->mod_mruby_child_init_middle_code = NULL; conf->mod_mruby_child_init_last_code = NULL; conf->mod_mruby_post_config_first_code = NULL; conf->mod_mruby_post_config_middle_code = NULL; conf->mod_mruby_post_config_last_code = NULL; conf->mod_mruby_quick_handler_first_code = NULL; conf->mod_mruby_quick_handler_middle_code = NULL; conf->mod_mruby_quick_handler_last_code = NULL; conf->mod_mruby_insert_filter_first_code = NULL; conf->mod_mruby_insert_filter_middle_code = NULL; conf->mod_mruby_insert_filter_last_code = NULL;
ちなみにdir_configの方では構造体をアロケートするしかできないが、configの方はサーバ単位の設定なのでサーバ構造体 server_rec *server
に触れられる。ということでmrb_stateを初めて作成しているのはmod_mruby_create_config
のタイミングである。
mrb_state *mrb = ap_mrb_create_mrb_state(); ap_mrb_set_mrb_state(server->process->pconf, mrb);
server->process->pconf
というところから後続のコードでも取り出している。
ap_mrb_create_mrb_state
のコードはmrubyコアで見かけるようなこういうやつで、
static mrb_state *ap_mrb_create_mrb_state() { TRACER; mrb_state *mrb = mrb_open(); ap_mruby_class_init(mrb); return mrb; }
ap_mruby_class_init
からそのほかの ap_mruby_*_init
を読んでmod_mruby固有のクラスなどを定義している。
こんな感じでふわっとやってく。
次は(あるのかな?)
mod_mruby_cmds
register_hooks
がやっていることを眺める。