---
title: "フィルタ"
language: "ja"
documentation_version: "3.x"
channel: "development"
release_context: null
source_revision: "10297d1e28653321d6996609fc53718d3b7c8278"
working_tree_clean: true
source_path: "docs/ja/concepts/filters.md"
source_sha256: "d16dfc402e96da14e62dc4919afa46b6451bc74b1de040ff494b287d9351372b"
source_at_revision: true
source_url: "https://github.com/matsumotory/ngx_mruby/blob/10297d1e28653321d6996609fc53718d3b7c8278/docs/ja/concepts/filters.md"
html_url: "https://ngx.mruby.org/ja/concepts/filters/"
markdown_url: "https://ngx.mruby.org/markdown/ja/concepts/filters.md"
last_updated: "2026-10-29"
---

# フィルタ

nginxは、レスポンスのヘッダとボディを2つのフィルタチェーンに通して送ります。レスポンスを作ったのがどのハンドラでも、upstreamでも同じです。ngx_mrubyは、それぞれのチェーンにフィルタを1つずつ加えます。ヘッダに対してRubyを実行するのは`mruby_output_header_filter`とその`_code`の形で、ボディに対して実行するのは`mruby_output_body_filter`とその`_code`の形です。設定に2つのディレクティブのどちらかがあると、ngx_mrubyはヘッダフィルタを加えます。ボディフィルタは、設定にボディフィルタのディレクティブがあるときに加えます。

nginxが呼ぶ順にヘッダフィルタとボディフィルタを並べ、ngx_mrubyのフィルタと、それぞれが受け取るものを示します。

図のラベル（順序は接続を表しません）:

- h-header: ヘッダフィルタ
- hn: nginxのnot modifiedのヘッダフィルタ
- hm: `mruby_output_header_filter`：ステータスとヘッダを受け取る。ボディフィルタがあると、ヘッダはその後まで待つ
- ho: nginxのほかのモジュールのヘッダフィルタ
- hw: nginxがヘッダを書き出す
- h-body: ボディフィルタ
- bn: nginxのrangeとcopyのボディフィルタ
- bm: `mruby_output_body_filter`：`Content-Length`のあるボディ全体を受け取る。ほかのボディは読まれずに通る
- bo: nginxのほかのモジュールのボディフィルタ
- bw: nginxのwriteフィルタがボディを送る

Source: ngx_mruby 0c72e3970 (2026-10-19)

- `src/http/ngx_http_mruby_module.c`: 591-595, 1676-1677, 1955-1965, 2041-2054, 2085-2122, 2135-2154
- `config.in`: 48-69
- nginx 1.31.6, `auto/modules`: 165-187, 386-427, 1494-1495
- nginx 1.31.6, `auto/module`: 23-30

- nginxは、各チェーンのフィルタを先頭から順に呼びます。ngx_mrubyのフィルタは、nginxのnot modifiedのヘッダフィルタと、rangeとcopyのボディフィルタの後に動きます。また、`gzip`やchunkedのフィルタのような、nginxのほかのモジュールのフィルタより先に動きます。そのため、ngx_mrubyのフィルタは、nginxが圧縮したりチャンクに分けたりする前のレスポンスを受け取ります。nginxは、`auto/modules`に並んだモジュールの順にチェーンを組みます。その順では、ngx_mrubyはnginx自身のフィルタのモジュールの後、copy、range body、not modified、sliceの各フィルタの前にあります。チェーンを組むとき、nginxは各フィルタを、それより前に並んだフィルタの手前に入れます。sliceのフィルタは、`--with-http_slice_module`を付けたビルドにだけあります。
- ヘッダフィルタは、`Nginx::Request`と`Nginx::Headers_out`でステータスとヘッダを読み、書き換えます。ヘッダフィルタはボディを読む前に動くので、そこでは`Nginx::Filter#body`は空の文字列を返します。
- ボディフィルタの処理には、レスポンスの長さが要ります。`Content-Length`のあるレスポンスでは、ngx_mrubyはボディ全体を1つのバッファに集め、そのボディを`Nginx::Filter#body`に入れてスクリプトを1回実行します。そして、ngx_mrubyは、スクリプトが`Nginx::Filter#body=`に入れたものを送ります。upstreamのチャンク形式のレスポンスのような、`Content-Length`の無いレスポンスは、読まれずにフィルタを通ります。ngx_mrubyは、そのことを`notice`のレベルでログに書きます。
- locationにボディフィルタがあると、ngx_mrubyは、ボディフィルタが動き終わるまでヘッダを送らずに待ちます。こうして、`Content-Length`を新しいボディの長さにします。
- どちらのフィルタでも待てません。フィルタの中では、`Nginx::Async.sleep`と`Nginx::Async::HTTP.sub_request`は`RuntimeError`を起こし、`Nginx.rputs`と`Nginx.echo`は使えません。

ガイドの[レスポンスのボディを変える](/ja/guides/body-filter/)には、CIが実行する両方のフィルタのサンプルがあります。フィルタの構文は、[ディレクティブのリファレンス](/ja/reference/directives/#mruby_output_body_filter-mruby_output_body_filter_code-mruby_output_header_filter-and-mruby_output_header_filter_code)にあります。
