2014年7月7日月曜日

handlerフック関数の実行処理

handlerフック関数の例の続きだ。

(1)ap_invoke_handler関数

フック関数は以下のap_run_handler()処理で実行される。

(httpd-2.4.9/server/config.c)
    385 AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r)
    386 {
     :
    401     ap_run_insert_filter(r);
ap_run_insert_filterもフック関数の実行処理だ。
基本的には、リクエスト処理に用いる入力フィルタや出力フィルタがセットアッ
プされる。

     :

    439     result = ap_run_handler(r);

ここでhandlerフック関数を実行する

     :
    465     return result == DECLINED ? HTTP_INTERNAL_SERVER_ERROR : result;
    466 }


(2)ap_process_async_request関数

これを行っている、ap_invoke_handler()関数は、内部リダイレクトの処理や、サブリクエストの処理などを含め数か所で呼ばれている。
そのうち、外部から受け取ったリクエストをそのまま処理するのは、次の箇所だった。
受信したリクエストの情報が引数のrequest_rec情報に保存されている。
この関数がリクエスト処理の本体だと言えそうだ。

(httpd-2.4.9/modules/http/http_request.c)

    272 void ap_process_async_request(request_rec *r)
    273 {
     :
    313     access_status = ap_run_quick_handler(r, 0);  /* Not a look-up request */
    314     if (access_status == DECLINED) {

ap_run_quick_hanlder()もフック関数の実行処理だ。
その戻り値がDECLINEDの場合にこのif文内の処理が行われる。
quick_handlerフック関数は、AP_IMPLEMENT_HOOK_RUN_FIRSTタイプなので、
handlerフック関数と同じだ。
フック関数の戻り値がDECLINE以外の場合に処理を終了する。
フック関数は処理を行うと、エラーステータスやOKを返す。このタイプでDECLINEDを
返すのは、次のフック関数に処理を継続させるためだ。
この戻り値がDECLINEDということは、登録されたフック関数はすべて実行されたが、
結局、エラーやOKを返すような処理は行われなかったことになる。
これが何を意味するかだが、例えば、特定の条件でキャッシュがヒットした場合には
ここの処理には入らない(キャッシュが返される)、というようなことだ。キャッ
シュについては、あとで少し細かく見たい。

    315         access_status = ap_process_request_internal(r);

この関数内で、アクセス権限チェックを含む、多くの処理が実行される。
フック関数の実行も、直接呼び出されるだけで以下のものがある。
* ap_run_post_perdir_config * ap_run_translate_name * ap_run_map_to_storage * ap_run_header_parser * ap_run_access_checker * ap_run_access_checker_ex * ap_run_check_user_id * ap_run_auth_checker * ap_run_type_checker * ap_run_fixups
このチェックに合格すると、OKが返される
316 if (access_status == OK) { 317 access_status = ap_invoke_handler(r); ap_invoke_handle()はap_process_request_internal()がOKを返した場合にのみ実行 される。 ここから、ap_run_handler()が実行された。 318 } 319 } : リクエストの処理結果はaccess_statusにセットされている。 結果に応じて(OKか否か)処理が振り分けられている。 345 if (access_status == OK) { 346 ap_finalize_request_protocol(r); 347 } 348 else { 349 r->status = HTTP_OK; 350 ap_die(access_status, r); 351 } 352 353 ap_process_request_after_handler(r); 最後のこの処理は、リクエスト処理1件分の終了処理だ。 EOR(END of Request)バケットを生成し、これを収めたbucket brigadeを出力フィル タにap_pass_brigadeする。 default_handler等リクエスト処理中は、bucket brigadeを引き渡す出力フィルタが request_recのoutput_filters だったが、ここでは、conn_recのoutput_filtersに なっていた。 354 }


これだけでは、ap_run_handler()がどういうタイミングで処理されるのか分からない。
そこで、このあと少し、リクエスト処理の流れを追ってみる。
その際には、再度、ap_process_async_request()やap_invoke_handler()の処理内容も確認したい。
行ったり来たりだが、リクエスト処理の流れを追いながらフック関数の呼出し位置を確認し、その後また、フック関数を幾つか確認するという作業に戻る予定とする。

0 件のコメント:

コメントを投稿