コンテンツにスキップ
2.x保守ブランチのドキュメントです。最新リリースタグは v2.7.2。v2.7.3 の変更は未リリースです。導入例の対象バージョンを確認してください。開発中の3.xは、3.xのドキュメントを読んでください。

Overview

2.xのドキュメントは、リリースノートを除いて英語で載せています。このページにも日本語訳はありません。

ngx_mruby enables you to run mruby scripts on nginx. For example, you can implement:

See use cases page for more examples. The scripts can be invoked at any of nginx HTTP phases. See nginx phases doc for more details of the phases.

ngx_mruby provides 2 modules. One is HTTP module for HTTP, the other is Stream module for TCP/UDP stream. See HTTP module directives and Stream module directive section for more details.

Here is a simple example of a content handler for HTTP.

location /hello {
mruby_content_handler /path/to/hello.rb;
}
Nginx.echo "Hello World"
$ curl http://127.0.0.1/hello
Hello World

‘mruby_content_handler’ is a directive to specify a mruby script file that is invoked at NGX_HTTP_CONTENT_PHASE to generate the response. You will get ‘Hello World’ as a HTTP response body if you access ‘/hello’ endpoint.

‘Nginx.echo’ is a method to creates a response body. ngx_mruby provides classes for accessing or manipulating nginx internal data structures. See classes for ngx_mruby for more information.

By default, mruby script is compiled whenever it is invoked. You can enable compiled code cache with ‘cache’ argument for performance.

location /hello {
mruby_content_handler /path/to/hello.rb cache;
}

You can write mruby code in nginx.conf instead of creating a script file. The compiled code is cached.

location /hello {
mruby_content_handler_code '
Nginx.echo "Hello World"
';
}

You can set nginx variable by a mruby script. The following example set a value returned from ‘proxy.rb’ to the variable ‘$backend’.

location /proxy {
mruby_set $backend /path/to/proxy.rb;
}

Also you can enable caching, or write inline mruby code as same as other directives.

location /proxy {
mruby_set $backend /path/to/proxy.rb cache;
}
location /proxy {
mruby_set_code $backend '
backends = [
"test1.example.com",
"test2.example.com",
"test3.example.com",
]
backends[rand(backends.length)]
';
}

ngx_mruby provides hooks invoked on several nginx initialization phases as below. See nginx Core Modules doc for more about initialization phases.

http {
mruby_init /path/to/init.rb;
mruby_init_worker /path/to/init_worker.rb;
mruby_exit_worker /path/to/exit_worker.rb;
server {
location / {
mruby_content_handler /path/to/handler.rb;
}
}
}

You can run a ruby script file directly without location definition. In the following example, the script is exposed at http://127.0.0.1/YOUR_MRUBY_SCRIPT.rb

location ~ \.rb$ {
mruby_add_handler on;
}

TODO

  • Add missing directives
    • mruby_server_context_handler_code
    • mruby_cache
  • Add examples
Syntax: mruby_init /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: http
Phase: initialize master process
Syntax: mruby_init_code 'YOUR MRUBY CODE HERE';
Default: -
Context: http
Phase: initialize master process

‘mruby_init’ and ‘mruby_init_code’ are called at initialized time in the context of the master process.

mruby_init_worker and mruby_init_worker_code

Section titled “mruby_init_worker and mruby_init_worker_code”
Syntax: mruby_init_worker /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: http
Phase: initialize worker process
Syntax: mruby_init_worker_code 'YOUR MRUBY CODE HERE';
Default: -
Context: http
Phase: initialize worker process

After initializing nginx master process, it creates worker processes. ‘mruby_init_worker’ and ‘mruby_init_worker_code’ are called when worker processes are created.

The code runs outside any request. Nginx.log writes to nginx’s error log here (since 2.7.1; 2.7.0 raised a RuntimeError). Request-scoped methods such as Nginx::Request, Nginx::Var and Nginx.rputs raise a RuntimeError here (since 2.7.1; in 2.7.0 they crashed the worker). See Nginx.errlogger for what code outside a request can call.

mruby_exit_worker and mruby_exit_worker_code

Section titled “mruby_exit_worker and mruby_exit_worker_code”
Syntax: mruby_exit_worker /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: http
Phase: exit worker process
Syntax: mruby_exit_worker_code 'YOUR MRUBY CODE HERE';
Default: -
Context: http
Phase: exit worker process

‘mruby_exit_worker’ and ‘mruby_exit_worker_code’ are called when a worker process is shutdown or terminated.

The code runs outside any request. Nginx.log writes to nginx’s error log here (since 2.7.1). Request-scoped methods such as Nginx::Request, Nginx::Var and Nginx.rputs raise a RuntimeError here (since 2.7.1; in 2.7.0 they used the last request that the worker had handled, or crashed the worker when it had handled none). See Nginx.errlogger for what code outside a request can call.

mruby_ssl_handshake_handler and mruby_ssl_handshake_handler_code

Section titled “mruby_ssl_handshake_handler and mruby_ssl_handshake_handler_code”
Syntax: mruby_ssl_handshake_handler /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: server
Phase: SSL handshake
Syntax: mruby_ssl_handshake_handler_code 'YOUR MRUBY CODE HERE';
Default: -
Context: server
Phase: SSL handshake

‘mruby_ssl_handshake_handler’ and ‘mruby_ssl_handshake_handler_code’ are called when SSL handshake is started. Both are enabled only if ngx_mruby is compiled with OpenSSL.

The code runs for a TLS connection, before any request on it, and uses Nginx::SSL to read the server name and to set the certificate. Nginx::SSL.log writes to the log of the connection, and Nginx.log writes to nginx’s error log (since 2.7.1). Request-scoped methods such as Nginx::Request, Nginx::Var and Nginx.rputs raise a RuntimeError here (since 2.7.1; in 2.7.0 they used the last request that the worker had handled, or crashed the worker when it had handled none). See Nginx.errlogger for what code outside a request can call.

Syntax: mruby_add_handler on | off;
Default: off
Context: server, location
Phase: initialize master process

When set to the value on, mruby scripts are added as handlers. You can run the script files directly without endpoint definition.

mruby_post_read_handler and mruby_post_read_handler_code

Section titled “mruby_post_read_handler and mruby_post_read_handler_code”
Syntax: mruby_post_read_handler /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: server
Phase: NGX_HTTP_POST_READ_PHASE
Syntax: mruby_post_read_handler_code 'YOUR MRUBY CODE HERE';
Default: -
Context: server
Phase: NGX_HTTP_POST_READ_PHASE

‘mruby_post_read_handler’ and ‘mruby_post_read_handler_code’ are called at NGX_HTTP_POST_READ_PHASE. It is first phase of HTTP request handling.

mruby_server_rewrite_handler, mruby_server_rewrite_handler_code, mruby_rewrite_handler and mruby_rewrite_handler_code

Section titled “mruby_server_rewrite_handler, mruby_server_rewrite_handler_code, mruby_rewrite_handler and mruby_rewrite_handler_code”
Syntax: mruby_server_rewrite_handler /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: server, location
Phase: NGX_HTTP_SERVER_REWRITE_PHASE
Syntax: mruby_server_rewrite_handler_code 'YOUR MRUBY CODE HERE';
Default: -
Context: server, location
Phase: NGX_HTTP_SERVER_REWRITE_PHASE
Syntax: mruby_rewrite_handler /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: server, location
Phase: NGX_HTTP_REWRITE_PHASE
Syntax: mruby_rewrite_handler_code 'YOUR MRUBY CODE HERE';
Default: -
Context: server, location
Phase: NGX_HTTP_REWRITE_PHASE

The rewrite handlers are mainly used for URL rewrite. ‘mruby_server_rewrite_handler’ and ‘mruby_server_rewrite_handler_code’ are used in a server block (and outside a location). ‘mruby_rewrite_handler’ and ‘mruby_rewrite_handler_code’ are used in a location block.

TODO: I’m not sure if the above contexts are correct.

mruby_access_handler and mruby_access_handler_code

Section titled “mruby_access_handler and mruby_access_handler_code”
Syntax: mruby_access_handler /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: server, location
Phase: NGX_HTTP_ACCESS_PHASE
Syntax: mruby_access_handler_code 'YOUR MRUBY CODE HERE';
Default: -
Context: server, location
Phase: NGX_HTTP_ACCESS_PHASE

‘mruby_access_handler’ and ‘mruby_access_handler_code’ are basically for authentication and authorization.

mruby_content_handler and mruby_content_handler_code

Section titled “mruby_content_handler and mruby_content_handler_code”
Syntax: mruby_content_handler /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: server, location
Phase: NGX_HTTP_CONTENT_PHASE
Syntax: mruby_content_handler_code 'YOUR MRUBY CODE HERE';
Default: -
Context: server, location
Phase: NGX_HTTP_CONTENT_PHASE

mruby_content_handler and mruby_content_handler_code are normally used for generating a HTTP response.

mruby_log_handler and mruby_log_handler_code

Section titled “mruby_log_handler and mruby_log_handler_code”
Syntax: mruby_log_handler /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: server, location
Phase: NGX_HTTP_LOG_PHASE
Syntax: mruby_log_handler_code 'YOUR MRUBY CODE HERE';
Default: -
Context: server, location
Phase: NGX_HTTP_LOG_PHASE

‘mruby_log_handler’ and ‘mruby_log_handler_code’ are called at the end of request processing for logging.

Syntax: mruby_set $VARNAME /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: server, location
Phase: NGX_HTTP_SERVER_REWRITE_PHASE, NGX_HTTP_REWRITE_PHASE
Syntax: mruby_set_code $VARNAME 'YOUR MRUBY CODE HERE';
Default: -
Context: server, location
Phase: NGX_HTTP_SERVER_REWRITE_PHASE, NGX_HTTP_REWRITE_PHASE

‘mruby_set’ and ‘mruby_set_code’ are called at one of the rewrite phases to set a nginx variable.

If the code raises an exception before it waits in Nginx::Async.sleep or Nginx::Async::HTTP.sub_request, ngx_mruby logs it, the variable is set to an empty string (as when the code returns nil), also when an earlier directive of the location gave it a value, and the request goes on. Text that the code wrote with Nginx.rputs or Nginx.echo before the exception is not sent and does not count in the Content-Length of the response. If the code raises after such a call returned, the request gets 500 and the output of Nginx.rputs is not sent, as described under Nginx::Async#sleep.

mruby_output_body_filter, mruby_output_body_filter_code, mruby_output_header_filter and mruby_output_header_filter_code

Section titled “mruby_output_body_filter, mruby_output_body_filter_code, mruby_output_header_filter and mruby_output_header_filter_code”
Syntax: mruby_output_body_filter /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: server, location
Phase:
Syntax: mruby_output_body_filter_code 'YOUR MRUBY CODE HERE';
Default: -
Context: server, location
Phase:
Syntax: mruby_output_header_filter /PATH/TO/YOUR/MRUBY/SCRIPT.rb [cache];
Default: -
Context: server, location
Phase:
Syntax: mruby_output_header_filter_code 'YOUR MRUBY CODE HERE';
Default: -
Context: server, location
Phase:

The filters are used for processing a response. The header filters are for HTTP header, the body filters are for HTTP body.

A body filter reads the response body with Nginx::Filter#body and can replace it with Nginx::Filter#body= (or #output). The response then has exactly that body, and Content-Length is its length. Since 2.7.1 this also holds when the body was written with Nginx.rputs or Nginx.echo; in 2.7.0 such a response kept the length that Nginx.rputs had produced, so a replacement body of another length was cut or padded.

A header filter runs before the body has been read. There Nginx::Filter#body returns an empty string and Nginx::Filter#body= raises a RuntimeError (both since 2.7.1).

Nginx::Async.sleep and Nginx::Async::HTTP.sub_request raise a RuntimeError in both kinds of filter (since 2.7.1), because nginx cannot resume a filter that waits.

Syntax: mruby_enable_read_request_body on | off;
Default: off
Context: server, location
Phase: initialize master process

When set to the value on, ngx_mruby reads a HTTP request body before calling mruby code.

Due to nginx event driven nature, a request body is not always read when invoking a handler like mruby_content_handler. The directive force to read the request body.

When the body is not complete yet, a post-read, server rewrite, rewrite, access or content handler runs once nginx has read the rest of it, and the request then goes on with the later phases, also with a phase handler that waits for a subrequest, such as auth_request. If the client closes the connection or client_body_timeout expires first, nginx ends the request and the handler does not run; after client_body_timeout nginx closes the connection without a response, and the access log records status 408. Before 2.7.1, a server rewrite, rewrite or content handler whose body was not complete never ran, and the client got no response; after a post-read or access handler had waited for the body, a later phase handler that waits for a subrequest, such as auth_request, was not resumed.

mruby_set and mruby_set_code handlers, log handlers and header and body filters cannot wait for the rest of the body, because nginx goes on as soon as they return. They see the body only when it is complete before they run: when an earlier handler or module has read it, or, for HTTP/1.x with a Content-Length header, when the whole body is in the buffer that nginx read the request headers into (client_header_buffer_size, or a buffer of large_client_header_buffers when the headers needed one). A chunked body, an HTTP/2 or HTTP/3 body, and a body of which only a part is in that buffer count as not complete, even when the rest has already arrived. Otherwise they run without the body (Nginx::Request#body returns nil), and ngx_mruby logs that at the info level. A body that a post-read, server rewrite, rewrite, access or content handler is still waiting for does not count as complete either: when nginx ends that read without the rest of the body (the client closes the connection, client_body_timeout expires, or nginx answers 400 or 413 to the body), a log handler or a filter that runs afterwards runs at once, without waiting for the rest, and the waiting handler does not run. Nginx::Request#body then returns the part of the body that nginx had read before it ended the read, or nil when that part did not fit in client_body_buffer_size and nginx had written it to a temporary file. A later handler that can wait, or a module such as proxy_pass, still reads the whole body. To give these handlers the whole body, read it first in a handler that can wait and runs before them, such as a server-level mruby_post_read_handler_code. Before 2.7.1, such a handler did not run its code when the body was not complete, and the body read that it had started ran the phases of the request again when it completed (since 2.7.1 it runs at once, without waiting for the rest of the body, as described above).

Syntax: mruby_upstream_keepalive connections;
Default: -
Context: upstream
Phase: initialize master process

Activates the cache for connections to upstream servers. It’s same as ngx_http_upstream_module’s keepalive.

TODO: describe the difference between keepalive and mruby_upstream_keepalive.

ngx_mruby also supports TCP/UDP stream. The stream module directives are similar to The HTTP module directives. Here are examples of the stream module directives.

server {
mruby_stream /path/to/stream.rb;
}
stream {
upstream dynamic_server0 {
server 127.0.0.1:58080;
}
server {
listen 12346;
mruby_stream_code '
c = Nginx::Stream::Connection.new "dynamic_server0"
c.upstream_server = "192.168.0.3:54321"
Nginx::Stream.log Nginx::Stream::LOG_NOTICE, "dynamic_server0 was changed to 192.168.0.3:54321"
';
proxy_pass dynamic_server0;
}
}
stream {
upstream dynamic_server0 {
server 127.0.0.1:58080;
}
mruby_stream_init_code '
Userdata.new.new_upstream = "127.0.0.1:58081"
';
mruby_stream_init_worker_code '
p "ngx_mruby: STREAM: mruby_stream_init_worker_code"
';
mruby_stream_exit_worker_code '
p "ngx_mruby: STREAM: mruby_stream_exit_worker_code"
';
server {
listen 12346;
mruby_stream_code '
c = Nginx::Stream::Connection.new "dynamic_server0"
c.upstream_server = Userdata.new.new_upstream
';
proxy_pass dynamic_server0;
}

TODO

  • Add descriptions to the above examples
  • Add directive references like HTTP module