(リクエストの処理の流れ)
書き散らかしているだけで、分かりやすくはできていないのだが、一通り見ておきたい。
ここまでのリクエストの処理結果がOKかそうでないかで分岐している。
この唯一の目的は、(transfer-encodingのような)レスポンスボディまわりのラッパーに対してプロトコル終了情報を通知することだ、とコメントにある。
ap_discard_request_body()はリクエストボディを読み込む(読み捨てる)。
通常、既に読み込んでいるはずだ。
end_output_stream()では、bucket brigadeを作成、
EOSメタデータバケットを作成し、bucket brigadeの末尾に追加する。
bucket brigadeをrequest_recのoutput_filtersに引き渡す処理が行われる。
出力フィルタでは、EOSメタデータバケットを受け取ると各種の終了処理が行われる。
CHUNK出力フィルタ(データをchunkedエンコーディングするフィルタ)では確かに、終了を示すchunkを作成している。
ErrorDocumentの指定にも対応する。
ここでは取り上げない。
つまり、リクエスト処理の終了を準備していることになる。
EORメタデータバケットを作成し、出力フィルタチェーンに引き渡す。
EORバケットが破棄されるタイミングで、アクセスログへの出力が実行され、requestメモリプールが解放される。
bucket brigade bbを作成
EORメタデータバケットを作成
書き散らかしているだけで、分かりやすくはできていないのだが、一通り見ておきたい。
(httpd-2.4.9/modules/http/http_request.c)
272 void ap_process_async_request(request_rec *r)
273 {
:
ここまでのリクエストの処理結果が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); 354 }
(6)ap_finalize_request_protocol
レスポンスの送信完了時に呼び出される。この唯一の目的は、(transfer-encodingのような)レスポンスボディまわりのラッパーに対してプロトコル終了情報を通知することだ、とコメントにある。
(httpd-2.4.9/server/protocol.c) 1228 /* finalize_request_protocol is called at completion of sending the 1229 * response. Its sole purpose is to send the terminating protocol 1230 * information for any wrappers around the response message body 1231 * (i.e., transfer encodings). It should have been named finalize_response. 1232 */ 1233 AP_DECLARE(void) ap_finalize_request_protocol(request_rec *r) 1234 { 1235 (void) ap_discard_request_body(r);
ap_discard_request_body()はリクエストボディを読み込む(読み捨てる)。
通常、既に読み込んでいるはずだ。
1236
1237 /* tell the filter chain there is no more content coming */
1238 if (!r->eos_sent) {
1239 end_output_stream(r);
end_output_stream()では、bucket brigadeを作成、
EOSメタデータバケットを作成し、bucket brigadeの末尾に追加する。
bucket brigadeをrequest_recのoutput_filtersに引き渡す処理が行われる。
出力フィルタでは、EOSメタデータバケットを受け取ると各種の終了処理が行われる。
CHUNK出力フィルタ(データをchunkedエンコーディングするフィルタ)では確かに、終了を示すchunkを作成している。
1240 } 1241 }
(7)ap_die
ap_die関数は、エラーレスポンスを返す。ErrorDocumentの指定にも対応する。
ここでは取り上げない。
(8)ap_process_request_after_handler
ここはこれまで何度か名前を出した EOR メタデータバケットの追加処理が行われている。つまり、リクエスト処理の終了を準備していることになる。
242 AP_DECLARE(void) ap_process_request_after_handler(request_rec *r)
243 {
244 apr_bucket_brigade *bb;
245 apr_bucket *b;
246 conn_rec *c = r->connection;
247
248 /* Send an EOR bucket through the output filter chain. When
249 * this bucket is destroyed, the request will be logged and
250 * its pool will be freed
251 */
EORメタデータバケットを作成し、出力フィルタチェーンに引き渡す。
EORバケットが破棄されるタイミングで、アクセスログへの出力が実行され、requestメモリプールが解放される。
252 bb = apr_brigade_create(r->connection->pool, r->connection->bucket_alloc);
bucket brigade bbを作成
253 b = ap_bucket_eor_create(r->connection->bucket_alloc, r);
EORメタデータバケットを作成
254 APR_BRIGADE_INSERT_HEAD(bb, b);
EORメタデータバケットを brigadeの先頭に挿入。
この時点ではbucket brigade bbにはEORバケットだけが含まれている。
255 256 ap_pass_brigade(r->connection->output_filters, bb);
その bucket brigade bb を出力フィルタに引き渡す。
この出力フィルタは、r->output_filtersではなく、conn_recに登録されている出力フィルタに直接、引き渡す。
コネクションフィルタによる処理だけ行うということだ。
プロトコルフィルタ以上の階層(request_recに登録されている階層)の処理は終わっているということだろう。
ただし、この処理タイミングでEORバケットが破棄されている(処理されている)とは限らない。
257 258 /* From here onward, it is no longer safe to reference r 259 * or r->pool, because r->pool may have been destroyed 260 * already by the EOR bucket's cleanup function. 261 */
EORバケットが処理済みであれば、requestメモリプールが解放されているため、
request_rec情報は無効になっている。
request_rec情報 *rは使ってはいけないことになる。
262
263 if (c->cs)
264 c->cs->state = CONN_STATE_WRITE_COMPLETION;
ここで、コネクションの状態情報がCONN_STATE_WRITE_COMPLETIONにセットされる。
265 check_pipeline(c);
処理待ちの読み込みデータがないかを確認している。
読込可能なデータがあった場合、conn_rec情報 *cのdata_in_input_filters変数に1がセットされる。
266 AP_PROCESS_REQUEST_RETURN((uintptr_t)r, r->uri, r->status);
DTrace関連のマクロと考えているが、詳細はよく分からない。
267 if (ap_extended_status) { 268 ap_time_process_request(c->sbh, STOP_PREQUEST); 269 } 270 }
ここまで。
0 件のコメント:
コメントを投稿