Change a response body
A body filter runs while nginx sends a response, whichever handler or
upstream produced it. With
mruby_output_body_filter,
a Ruby script reads the body through Nginx::Filter#body and replaces it
with Nginx::Filter#body=. A header filter
(mruby_output_header_filter) runs before it and can change the response
headers.
The sample
Section titled “The sample”The location sends a text file from disk. The header filter sets the
content type to text/html, and the body filter escapes &, < and >
and wraps the text in an HTML page.
server { listen 18167;
# A text file from disk, sent as an HTML page. location = /notes { alias html/guide_notes.txt; mruby_output_header_filter_code 'Nginx::Request.new.content_type = "text/html"'; mruby_output_body_filter build/nginx/html/guide_body_filter.rb; }}f = Nginx::Filter.newtext = f.body.gsub("&", "&").gsub("<", "<").gsub(">", ">")f.body = "<!doctype html>\n<title>notes</title>\n<pre>\n#{text}</pre>\n"GET /notes HTTP/1.1Host: 127.0.0.1:18167Connection: closeHTTP/1.1 200 OKContent-Type: text/html
<!doctype html><title>notes</title><pre>Notes from disk.The filter escapes <b> and &.</pre>On every CI run, the case test/t/cases/guides.rb sends this request and compares the status line, the headers shown on this page and the whole body. The five files last changed on 2026-10-29 in commit 32219e53.
What to keep in mind
Section titled “What to keep in mind”- The body filter reads a response of known length, such as a file from
disk, as one buffer. nginx passes a response without
Content-Lengthon without the filter reading it (Nginx::Filter ). - ngx_mruby sends the length of the new body in
Content-Length. - The use case “Output filter converting Markdown to HTML” of Use cases converts Markdown in the same place, with the gem mruby-discount.