2015年1月26日月曜日

input/output filter: ローカルファイルを返す場合の構成

最小限の機能によるリクエスト処理として、/index.htmlにアクセスした場合にリクエストとレスポンスがたどる入出力フィルタの構成をみる。

(1)フィルタ構成の確認

ここではgdbでリクエスト処理を追って確認した。
(他にいい方法があるだろうか)

入力フィルタの確認のため、ap_get_brigadeにbreakpointを設定する。

(gdb) break ap_get_brigade
Breakpoint 1 at 0x4320b0: file util_filter.c, line 552.

出力フィルタの確認のため、ap_pass_brigadeにもbreakpointを設定する。

(gdb) break ap_pass_brigade
Breakpoint 2 at 0x4320d0: file util_filter.c, line 567.

省力化のため、backtraceと、フィルタ情報を出力して処理を継続するマクロを用意しておいた。

(gdb) define pinfo
Type commands for definition of "pinfo".
End with a line saying just "end".
>bt
>print *next->frec
>conti
>end

そして、curlコマンドで/index.htmlへのリクエストを発行した。

(1.1) read_request_line

  • リクエスト行の読み込み処理
  • 入力フィルタ
    • CORE_INフィルタ(COREモジュール)
      • AP_MODE_GETLINEモード
      • APR_BLOCK_READ読込モード

Breakpoint 1, ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac00baa8, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
552         if (next) {
(gdb) pinfo
#0  ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac00baa8, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
#1  0x0000000000435ef2 in ap_rgetline_core (s=0x7fa9ac00a9e0, n=8192, read=0x7fa9ba00cd10, r=0x7fa9ac00a9b0, fold=0, bb=0x7fa9ac00baa8) at protocol.c:229
#2  0x0000000000436d1e in read_request_line (conn=0x7fa9b400dbe0) at protocol.c:590
#3  ap_read_request (conn=0x7fa9b400dbe0) at protocol.c:956
#4  0x000000000045cff9 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:135
#5  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#6  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#7  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#8  worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#9  0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$37 = {name = 0x1370420 "core_in", filter_func = {out_func = 0x446790 , in_func = 0x446790 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}

(1.2) ap_get_mime_headers_core(1)

  • リクエストヘッダ行読み込み処理。
    • 1行ごとの処理なので、ヘッダ行の数だけ処理が行われる。
  • 入力フィルタ:
    • CORE_INフィルタ(COREモジュール)
      • AP_MODE_GETLINE
      • APR_BLOCK_READ

Breakpoint 1, ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac00baa8, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
552         if (next) {
(gdb)
#0  ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac00baa8, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
#1  0x0000000000435ef2 in ap_rgetline_core (s=0x7fa9ba00cc98, n=8192, read=0x7fa9ba00cc90, r=0x7fa9ac00a9b0, fold=0, bb=0x7fa9ac00baa8) at protocol.c:229
#2  0x00000000004362e7 in ap_get_mime_headers_core (r=0x7fa9ac00a9b0, bb=0x7fa9ac00baa8) at protocol.c:713
#3  0x000000000043738b in ap_read_request (conn=0x7fa9b400dbe0) at protocol.c:1002
#4  0x000000000045cff9 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:135
#5  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#6  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#7  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#8  worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#9  0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$38 = {name = 0x1370420 "core_in", filter_func = {out_func = 0x446790 , in_func = 0x446790 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}

(1.3) ap_get_mime_headers_core(2)

  • リクエストヘッダ行読み込み処理。
    • 1行ごとの処理なので、ヘッダ行の数だけ処理が行われる。
  • 入力フィルタ:
    • CORE_INフィルタ(COREモジュール)
      • AP_MODE_GETLINE
      • APR_BLOCK_READ

Breakpoint 1, ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac00baa8, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
552         if (next) {
(gdb)
#0  ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac00baa8, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
#1  0x0000000000435ef2 in ap_rgetline_core (s=0x7fa9ba00cc98, n=8192, read=0x7fa9ba00cc90, r=0x7fa9ac00a9b0, fold=0, bb=0x7fa9ac00baa8) at protocol.c:229
#2  0x00000000004362e7 in ap_get_mime_headers_core (r=0x7fa9ac00a9b0, bb=0x7fa9ac00baa8) at protocol.c:713
#3  0x000000000043738b in ap_read_request (conn=0x7fa9b400dbe0) at protocol.c:1002
#4  0x000000000045cff9 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:135
#5  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#6  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#7  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#8  worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#9  0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$39 = {name = 0x1370420 "core_in", filter_func = {out_func = 0x446790 , in_func = 0x446790 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}

(1.4) ap_get_mime_headers_core(3)


  • リクエストヘッダ行読み込み処理。
    • 1行ごとの処理なので、ヘッダ行の数だけ処理が行われる。
  • 入力フィルタ:
    • CORE_INフィルタ(COREモジュール)
      • AP_MODE_GETLINE
      • APR_BLOCK_READ


Breakpoint 1, ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac00baa8, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
552         if (next) {
(gdb)
#0  ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac00baa8, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
#1  0x0000000000435ef2 in ap_rgetline_core (s=0x7fa9ba00cc98, n=8192, read=0x7fa9ba00cc90, r=0x7fa9ac00a9b0, fold=0, bb=0x7fa9ac00baa8) at protocol.c:229
#2  0x00000000004362e7 in ap_get_mime_headers_core (r=0x7fa9ac00a9b0, bb=0x7fa9ac00baa8) at protocol.c:713
#3  0x000000000043738b in ap_read_request (conn=0x7fa9b400dbe0) at protocol.c:1002
#4  0x000000000045cff9 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:135
#5  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#6  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#7  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#8  worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#9  0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$40 = {name = 0x1370420 "core_in", filter_func = {out_func = 0x446790 , in_func = 0x446790 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}

(1.5) ap_get_mime_headers_core(4)


  • リクエストヘッダ行読み込み処理。
    • 1行ごとの処理なので、ヘッダ行の数だけ処理が行われる。
    • 最後は空行になる。
  • 入力フィルタ:
    • CORE_INフィルタ(COREモジュール)
      • AP_MODE_GETLINE
      • APR_BLOCK_READ


Breakpoint 1, ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac00baa8, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
552         if (next) {
(gdb)
#0  ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac00baa8, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
#1  0x0000000000435ef2 in ap_rgetline_core (s=0x7fa9ba00cc98, n=8192, read=0x7fa9ba00cc90, r=0x7fa9ac00a9b0, fold=0, bb=0x7fa9ac00baa8) at protocol.c:229
#2  0x00000000004362e7 in ap_get_mime_headers_core (r=0x7fa9ac00a9b0, bb=0x7fa9ac00baa8) at protocol.c:713
#3  0x000000000043738b in ap_read_request (conn=0x7fa9b400dbe0) at protocol.c:1002
#4  0x000000000045cff9 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:135
#5  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#6  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#7  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#8  worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#9  0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$41 = {name = 0x1370420 "core_in", filter_func = {out_func = 0x446790 , in_func = 0x446790 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}

(1.6) default_handler: ap_discard_request_body


  • リクエストボディの読み捨て
  • 入力フィルタ:
    • HTTP_INフィルタ(HTTPモジュール)
      • AP_MODE_READBYTES
      • APR_BLOCK_READ


Breakpoint 1, ap_get_brigade (next=0x7fa9ac00bc48, bb=0x7fa9ac00c378, mode=AP_MODE_READBYTES, block=APR_BLOCK_READ, readbytes=8192) at util_filter.c:552
552         if (next) {
(gdb)
#0  ap_get_brigade (next=0x7fa9ac00bc48, bb=0x7fa9ac00c378, mode=AP_MODE_READBYTES, block=APR_BLOCK_READ, readbytes=8192) at util_filter.c:552
#1  0x00000000004616e0 in ap_discard_request_body (r=0x7fa9ac00a9b0) at http_filters.c:1418
#2  0x000000000043d915 in default_handler (r=0x7fa9ac00a9b0) at core.c:4277
#3  0x000000000044a1b0 in ap_run_handler (r=0x7fa9ac00a9b0) at config.c:170
#4  0x000000000044e33e in ap_invoke_handler (r=0x7fa9ac00a9b0) at config.c:439
#5  0x000000000046099a in ap_process_async_request (r=0x7fa9ac00a9b0) at http_request.c:317
#6  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#7  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#8  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#9  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#10 worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#11 0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#12 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$42 = {name = 0x1396b98 "http_in", filter_func = {out_func = 0x463410 , in_func = 0x463410 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_PROTOCOL, debug = 0, proto_flags = 0}

(1.7) default_handler


  • 出力フィルタ:
    • byterange出力フィルタ(HTTPモジュール)


Breakpoint 2, ap_pass_brigade (next=0x7fa9ac00ba08, bb=0x7fa9ac00c598) at util_filter.c:567
567         if (next) {
(gdb)
#0  ap_pass_brigade (next=0x7fa9ac00ba08, bb=0x7fa9ac00c598) at util_filter.c:567
#1  0x000000000043de27 in default_handler (r=0x7fa9ac00a9b0) at core.c:4369
#2  0x000000000044a1b0 in ap_run_handler (r=0x7fa9ac00a9b0) at config.c:170
#3  0x000000000044e33e in ap_invoke_handler (r=0x7fa9ac00a9b0) at config.c:439
#4  0x000000000046099a in ap_process_async_request (r=0x7fa9ac00a9b0) at http_request.c:317
#5  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#6  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#7  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#8  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#9  worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#10 0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#11 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$43 = {name = 0x1397878 "byterange", filter_func = {out_func = 0x464c80 , in_func = 0x464c80 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_PROTOCOL, debug = 0, proto_flags = 0}

(1.8) default_handler: ap_byterange_filter


  • 出力フィルタ:
    • content_length出力フィルタ(COREモジュール)


Breakpoint 2, ap_pass_brigade (next=0x7fa9ac00ba30, bb=0x7fa9ac00c598) at util_filter.c:567
567         if (next) {
(gdb)
#0  ap_pass_brigade (next=0x7fa9ac00ba30, bb=0x7fa9ac00c598) at util_filter.c:567
#1  0x0000000000464dc2 in ap_byterange_filter (f=0x7fa9ac00ba08, bb=0x7fa9ac00c598) at byterange_filter.c:496
#2  0x000000000043de27 in default_handler (r=0x7fa9ac00a9b0) at core.c:4369
#3  0x000000000044a1b0 in ap_run_handler (r=0x7fa9ac00a9b0) at config.c:170
#4  0x000000000044e33e in ap_invoke_handler (r=0x7fa9ac00a9b0) at config.c:439
#5  0x000000000046099a in ap_process_async_request (r=0x7fa9ac00a9b0) at http_request.c:317
#6  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#7  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#8  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#9  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#10 worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#11 0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#12 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$44 = {name = 0x1370740 "content_length", filter_func = {out_func = 0x437df0 , in_func = 0x437df0 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_PROTOCOL, debug = 0, proto_flags = 0}

(1.9) default_handler: ap_content_length_filter


  • 出力フィルタ:
    • http_header出力フィルタ(HTTPモジュール)


Breakpoint 2, ap_pass_brigade (next=0x7fa9ac00ba58, bb=0x7fa9ac00c598) at util_filter.c:567
567         if (next) {
(gdb)
#0  ap_pass_brigade (next=0x7fa9ac00ba58, bb=0x7fa9ac00c598) at util_filter.c:567
#1  0x0000000000437f7a in ap_content_length_filter (f=0x7fa9ac00ba30, b=0x7fa9ac00c598) at protocol.c:1421
#2  0x0000000000464dc2 in ap_byterange_filter (f=0x7fa9ac00ba08, bb=0x7fa9ac00c598) at byterange_filter.c:496
#3  0x000000000043de27 in default_handler (r=0x7fa9ac00a9b0) at core.c:4369
#4  0x000000000044a1b0 in ap_run_handler (r=0x7fa9ac00a9b0) at config.c:170
#5  0x000000000044e33e in ap_invoke_handler (r=0x7fa9ac00a9b0) at config.c:439
#6  0x000000000046099a in ap_process_async_request (r=0x7fa9ac00a9b0) at http_request.c:317
#7  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#8  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#9  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#10 0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#11 worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#12 0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#13 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$45 = {name = 0x1396e60 "http_header", filter_func = {out_func = 0x462450 , in_func = 0x462450 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_PROTOCOL, debug = 0, proto_flags = 0}

(1.10) default_handler: ap_http_header_filter


  • レスポンスヘッダ処理
  • 出力フィルタ:
    • http_outerror出力フィルタ(HTTPモジュール)


Breakpoint 2, ap_pass_brigade (next=0x7fa9ac00ba80, bb=0x7fa9ac00c690) at util_filter.c:567
567         if (next) {
(gdb)
#0  ap_pass_brigade (next=0x7fa9ac00ba80, bb=0x7fa9ac00c690) at util_filter.c:567
#1  0x000000000046270d in ap_http_header_filter (f=, b=) at http_filters.c:1356
#2  0x0000000000437f7a in ap_content_length_filter (f=0x7fa9ac00ba30, b=0x7fa9ac00c598) at protocol.c:1421
#3  0x0000000000464dc2 in ap_byterange_filter (f=0x7fa9ac00ba08, bb=0x7fa9ac00c598) at byterange_filter.c:496
#4  0x000000000043de27 in default_handler (r=0x7fa9ac00a9b0) at core.c:4369
#5  0x000000000044a1b0 in ap_run_handler (r=0x7fa9ac00a9b0) at config.c:170
#6  0x000000000044e33e in ap_invoke_handler (r=0x7fa9ac00a9b0) at config.c:439
#7  0x000000000046099a in ap_process_async_request (r=0x7fa9ac00a9b0) at http_request.c:317
#8  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#9  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#10 0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#11 0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#12 worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#13 0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#14 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$46 = {name = 0x1397550 "http_outerror", filter_func = {out_func = 0x460d10 , in_func = 0x460d10 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_PROTOCOL, debug = 0, proto_flags = 0}

(1.11) default_handler: ap_http_header_filter


  • レスポンスヘッダ処理
  • 出力フィルタ:
    • core出力フィルタ


Breakpoint 2, ap_pass_brigade (next=0x7fa9b400df48, bb=0x7fa9ac00c690) at util_filter.c:567
567         if (next) {
(gdb)
#0  ap_pass_brigade (next=0x7fa9b400df48, bb=0x7fa9ac00c690) at util_filter.c:567
#1  0x000000000046270d in ap_http_header_filter (f=, b=) at http_filters.c:1356
#2  0x0000000000437f7a in ap_content_length_filter (f=0x7fa9ac00ba30, b=0x7fa9ac00c598) at protocol.c:1421
#3  0x0000000000464dc2 in ap_byterange_filter (f=0x7fa9ac00ba08, bb=0x7fa9ac00c598) at byterange_filter.c:496
#4  0x000000000043de27 in default_handler (r=0x7fa9ac00a9b0) at core.c:4369
#5  0x000000000044a1b0 in ap_run_handler (r=0x7fa9ac00a9b0) at config.c:170
#6  0x000000000044e33e in ap_invoke_handler (r=0x7fa9ac00a9b0) at config.c:439
#7  0x000000000046099a in ap_process_async_request (r=0x7fa9ac00a9b0) at http_request.c:317
#8  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#9  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#10 0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#11 0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#12 worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#13 0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#14 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$47 = {name = 0x1370c78 "core", filter_func = {out_func = 0x445f90 , in_func = 0x445f90 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}

(1.12) default_handler: ap_http_header_filter


  • レスポンスボディ処理
  • 出力フィルタ:
    • http_outerror出力フィルタ(HTTPモジュール)


Breakpoint 2, ap_pass_brigade (next=0x7fa9ac00ba80, bb=0x7fa9ac00c598) at util_filter.c:567
567         if (next) {
(gdb)
#0  ap_pass_brigade (next=0x7fa9ac00ba80, bb=0x7fa9ac00c598) at util_filter.c:567
#1  0x00000000004624f3 in ap_http_header_filter (f=, b=) at http_filters.c:1379
#2  0x0000000000437f7a in ap_content_length_filter (f=0x7fa9ac00ba30, b=0x7fa9ac00c598) at protocol.c:1421
#3  0x0000000000464dc2 in ap_byterange_filter (f=0x7fa9ac00ba08, bb=0x7fa9ac00c598) at byterange_filter.c:496
#4  0x000000000043de27 in default_handler (r=0x7fa9ac00a9b0) at core.c:4369
#5  0x000000000044a1b0 in ap_run_handler (r=0x7fa9ac00a9b0) at config.c:170
#6  0x000000000044e33e in ap_invoke_handler (r=0x7fa9ac00a9b0) at config.c:439
#7  0x000000000046099a in ap_process_async_request (r=0x7fa9ac00a9b0) at http_request.c:317
#8  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#9  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#10 0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#11 0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#12 worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#13 0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#14 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$48 = {name = 0x1397550 "http_outerror", filter_func = {out_func = 0x460d10 , in_func = 0x460d10 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_PROTOCOL, debug = 0, proto_flags = 0}

(1.13) default_handler: ap_http_header_filter


  • レスポンスボディ処理
  • 出力フィルタ:
    • core出力フィルタ(COREモジュール)


Breakpoint 2, ap_pass_brigade (next=0x7fa9b400df48, bb=0x7fa9ac00c598) at util_filter.c:567
567         if (next) {
(gdb)
#0  ap_pass_brigade (next=0x7fa9b400df48, bb=0x7fa9ac00c598) at util_filter.c:567
#1  0x00000000004624f3 in ap_http_header_filter (f=, b=) at http_filters.c:1379
#2  0x0000000000437f7a in ap_content_length_filter (f=0x7fa9ac00ba30, b=0x7fa9ac00c598) at protocol.c:1421
#3  0x0000000000464dc2 in ap_byterange_filter (f=0x7fa9ac00ba08, bb=0x7fa9ac00c598) at byterange_filter.c:496
#4  0x000000000043de27 in default_handler (r=0x7fa9ac00a9b0) at core.c:4369
#5  0x000000000044a1b0 in ap_run_handler (r=0x7fa9ac00a9b0) at config.c:170
#6  0x000000000044e33e in ap_invoke_handler (r=0x7fa9ac00a9b0) at config.c:439
#7  0x000000000046099a in ap_process_async_request (r=0x7fa9ac00a9b0) at http_request.c:317
#8  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#9  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#10 0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#11 0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#12 worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#13 0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#14 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$49 = {name = 0x1370c78 "core", filter_func = {out_func = 0x445f90 , in_func = 0x445f90 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}

(1.14) ap_finalize_request_protocol


  • リクエストボディ読み捨て
  • 入力フィルタ:
    • http_inフィルタ
      • AP_MODE_READBYTES
      • APR_BLOCK_READ


Breakpoint 1, ap_get_brigade (next=0x7fa9ac00bc48, bb=0x7fa9ac00c838, mode=AP_MODE_READBYTES, block=APR_BLOCK_READ, readbytes=8192) at util_filter.c:552
552         if (next) {
(gdb)
#0  ap_get_brigade (next=0x7fa9ac00bc48, bb=0x7fa9ac00c838, mode=AP_MODE_READBYTES, block=APR_BLOCK_READ, readbytes=8192) at util_filter.c:552
#1  0x00000000004616e0 in ap_discard_request_body (r=0x7fa9ac00a9b0) at http_filters.c:1418
#2  0x0000000000435879 in ap_finalize_request_protocol (r=0x7fa9ac00a9b0) at protocol.c:1235
#3  0x0000000000460808 in ap_process_async_request (r=0x7fa9ac00a9b0) at http_request.c:346
#4  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#5  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#6  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#7  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#8  worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#9  0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$50 = {name = 0x1396b98 "http_in", filter_func = {out_func = 0x463410 , in_func = 0x463410 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_PROTOCOL, debug = 0, proto_flags = 0}

(1.15) ap_process_request_after_handler


  • 出力フィルタ:
    • coreフィルタ


Breakpoint 2, ap_pass_brigade (next=0x7fa9b400df48, bb=0x7fa9b400e0b0) at util_filter.c:567
567         if (next) {
(gdb)
#0  ap_pass_brigade (next=0x7fa9b400df48, bb=0x7fa9b400e0b0) at util_filter.c:567
#1  0x000000000045fa8d in ap_process_request_after_handler (r=0x7fa9ac00a9b0) at http_request.c:256
#2  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#3  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#4  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#5  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#6  worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#7  0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#8  0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$51 = {name = 0x1370c78 "core", filter_func = {out_func = 0x445f90 , in_func = 0x445f90 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}

(1.16) ap_process_request_after_handler


  • 次リクエスト到着チェック
  • 入力フィルタ:
    • core_inフィルタ
      • AP_MODE_SPECULATIVEモード
      • APR_NONBLOCK_READ


Breakpoint 1, ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9b400e0f0, mode=AP_MODE_SPECULATIVE, block=APR_NONBLOCK_READ, readbytes=1) at util_filter.c:552
552         if (next) {
(gdb)
#0  ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9b400e0f0, mode=AP_MODE_SPECULATIVE, block=APR_NONBLOCK_READ, readbytes=1) at util_filter.c:552
#1  0x000000000045fad6 in check_pipeline (r=0x7fa9ac00a9b0) at http_request.c:225
#2  ap_process_request_after_handler (r=0x7fa9ac00a9b0) at http_request.c:265
#3  0x000000000045d070 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:143
#4  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#5  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#6  0x00007fa9baa557e1 in process_socket (thd=0x13c5fe0, dummy=) at event.c:970
#7  worker_thread (thd=0x13c5fe0, dummy=) at event.c:1815
#8  0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#9  0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$52 = {name = 0x1370420 "core_in", filter_func = {out_func = 0x446790 , in_func = 0x446790 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}

(1.17) read_request_line


  • リクエスト行読み込み処理
    • クライアントの終了を検知する
  • 入力フィルタ:
    • core_inフィルタ
      • AP_MODE_GETLINE
      • APR_BLOCK_READ


Breakpoint 1, ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac003a68, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
552         if (next) {
(gdb)
#0  ap_get_brigade (next=0x7fa9b400df20, bb=0x7fa9ac003a68, mode=AP_MODE_GETLINE, block=APR_BLOCK_READ, readbytes=0) at util_filter.c:552
#1  0x0000000000435ef2 in ap_rgetline_core (s=0x7fa9ac0029a0, n=8192, read=0x7fa9b3ffed10, r=0x7fa9ac002970, fold=0, bb=0x7fa9ac003a68) at protocol.c:229
#2  0x0000000000436d1e in read_request_line (conn=0x7fa9b400dbe0) at protocol.c:590
#3  ap_read_request (conn=0x7fa9b400dbe0) at protocol.c:956
#4  0x000000000045cff9 in ap_process_http_async_connection (c=0x7fa9b400dbe0) at http_core.c:135
#5  ap_process_http_connection (c=0x7fa9b400dbe0) at http_core.c:228
#6  0x0000000000454b60 in ap_run_process_connection (c=0x7fa9b400dbe0) at connection.c:41
#7  0x00007fa9baa557e1 in process_socket (thd=0x13c6070, dummy=) at event.c:970
#8  worker_thread (thd=0x13c6070, dummy=) at event.c:1815
#9  0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#10 0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$53 = {name = 0x1370420 "core_in", filter_func = {out_func = 0x446790 , in_func = 0x446790 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}

(1.18) ap_start_lingering_close


  • EOF後の処理
  • 出力フィルタ:
    • coreフィルタ


Breakpoint 2, ap_pass_brigade (next=0x7fa9b400df48, bb=0x7fa9b400e138) at util_filter.c:567
567         if (next) {
(gdb)
#0  ap_pass_brigade (next=0x7fa9b400df48, bb=0x7fa9b400e138) at util_filter.c:567
#1  0x0000000000454d38 in ap_start_lingering_close (c=0x7fa9b400dbe0) at connection.c:121
#2  0x00007fa9baa55541 in start_lingering_close_blocking (thd=0x13c6070, dummy=) at event.c:823
#3  process_socket (thd=0x13c6070, dummy=) at event.c:1025
#4  worker_thread (thd=0x13c6070, dummy=) at event.c:1815
#5  0x0000003f53e079d1 in start_thread () from /lib64/libpthread.so.0
#6  0x0000003f53ae8b6d in clone () from /lib64/libc.so.6

$54 = {name = 0x1370c78 "core", filter_func = {out_func = 0x445f90 , in_func = 0x445f90 }, filter_init_func = 0, next = 0x0, providers = 0x0, ftype = AP_FTYPE_NETWORK, debug = 0, proto_flags = 0}


(2)フィルタの追加処理の確認

もともとのCORE/CORE_INフィルタの設定箇所はすでに
リクエスト処理の流れ: process_socket に戻る で見たが、下記のpre_connectionフック関数で行われている。

(httpd-2.4.9/server/core.c)

   4637 static int core_pre_connection(conn_rec *c, void *csd)
   4638 {

   4676     ap_set_core_module_config(net->c->conn_config, csd);
   4677     ap_add_input_filter_handle(ap_core_input_filter_handle, net, NULL, net->c);


CORE入力フィルタの追加

   4678     ap_add_output_filter_handle(ap_core_output_filter_handle, net, NULL, net->c);

CORE出力フィルタの追加

   4679     return DONE;
   4680 }

そして、HTTPリクエストボディの処理に使われていたHTTP_IN入力フィルタは
HTTPリクエストヘッダ処理後に、ap_read_request()関数内で追加される。
リクエスト処理の流れ: ap_read_request  参照。

(httpd-2.4.9/server/protocol.c)

    895 request_rec *ap_read_request(conn_rec *conn)
    896 {
     :

   1098     /*
   1099      * Add the HTTP_IN filter here to ensure that ap_discard_request_body
   1100      * called by ap_die and by ap_send_error_response works correctly on
   1101      * status codes that do not cause the connection to be dropped and
   1102      * in situations where the connection should be kept alive.
   1103      */
   1104
   1105     ap_add_input_filter_handle(ap_http_input_filter_handle,
   1106                                NULL, r, r->connection);
   1107

次はHTTPコアモジュールが提供しているcreate_requestフック関数だ。
このフック関数を実行する処理 ap_run_create_request()は
リクエスト処理の流れ: ap_read_request で見た。
read_request_line()でリクエスト行を読み込む前に実行される。

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

    235 static int http_create_request(request_rec *r)
    236 {
    237     if (!r->main && !r->prev) {
    238         ap_add_output_filter_handle(ap_byterange_filter_handle,
    239                                     NULL, r, r->connection);

BYTERANGE出力フィルタの追加

    240         ap_add_output_filter_handle(ap_content_length_filter_handle,
    241                                     NULL, r, r->connection);

CONTENT_LENGTH出力フィルタの追加

    242         ap_add_output_filter_handle(ap_http_header_filter_handle,
    243                                     NULL, r, r->connection);

HTTP_HEADER出力フィルタの追加

    244         ap_add_output_filter_handle(ap_http_outerror_filter_handle,
    245                                     NULL, r, r->connection);

HTTP_OUTERROR出力フィルタの追加

    246     }
    247
    248     return OK;
    249 }


(3)フィルタの階層構成図

まとめると、次のような入出力フィルタがセットされていたことになる。


今回はここまで

4 件のコメント: