Mruby API documentation for ngx_mruby
2.xのドキュメントは、リリースノートを除いて英語で載せています。このページにも日本語訳はありません。
This is the mruby API documentation for ngx_mruby.
ngx_mruby provides mruby APIs to access and manipulate nginx internal data structure.
You can use these classes and methods in handlers like mruby_content_handler_code.
Available APIs depend on your build configuration. See Configuring mrbgems and Build options for the build configuration.
TODO: Sort. I don’t think alphabetical order is easy to read.
ngx_mruby HTTP module
Section titled “ngx_mruby HTTP module”The ngx_mruby HTTP module is a nginx module to extend the HTTP server by mruby and the core of ngx_mruby.
Notice: ngx_mruby_mrblib is a required mrbgem and a part of The HTTP module. The classes and methods provided by ngx_mruby_mrblib are documented here.
- Kernel Module
- Nginx Class
- Nginx::
SSL Class - Nginx::
Request Class - Nginx::
Server Class - Nginx::
Connection Class - Nginx::
Var Class - Nginx::
Headers_in Class - Nginx::
Headers_out Class - Nginx::
Filter Class - Nginx::
Upstream Class - Nginx::
Async Class - Nginx::
Async:: HTTP Class
ngx_mruby stream module
Section titled “ngx_mruby stream module”The ngx_mruby stream module is an optional nginx module to handle TCP and UDP stream.
rack-based-api mrbgem
Section titled “rack-based-api mrbgem”The rack-based-api mrbgem is an optional bundled mrbgem. It provides RACK (Ruby Webserver Interface) compatible APIs to make development and testing easier.
auto-ssl mrbgem
Section titled “auto-ssl mrbgem”The auto-ssl mrbgem is an optional bundled mrbgem to support Automatic Certificate Management Environment (ACME) protocol client. You can easily get SSL certificates from Let’s Encrypt.
Nginx::SSL::ACME::Client speaks ACMEv1, which Let’s Encrypt fully turned off on 1 June 2021 (End of Life Plan for ACMEv1), so it gets no certificate from Let’s Encrypt. The helpers for the dehydrated ACME client (Nginx::SSL::ACME::Dehydrated) do not use it.
It is still in early development phase. See script files in mrbgems/auto-ssl/mrblib for APIs.
Add classes and methods reference.
Section titled “Add classes and methods reference.”built-in mrbgems
Section titled “built-in mrbgems”You can use the following classes with default build configuration.
- Cache Class
- Dir class
- Digest Class
- ENV class
- JSON Class
- Mutex class
- OnigRegexp Class and Regexp Engine
- Process Class
- Redis Class
- SecureRandom Class
- Userdata Class
- Uname Class
- Vedis Class
The Redis class was left out of the default build in 2.7.1 and is in it again since 2.7.2 (see “Redis is in the default build again” in the 2.7.2 release notes).
You can also use classes embedded by default.gembox and full-core.gembox.
Kernel Module
Section titled “Kernel Module”ngx_mruby HTTP module adds two methods to Kernel module. These methods are called without a receiver.
Both are provided to write portable code for mod_mruby.
Module Methods
Section titled “Module Methods”get_server_class -> class_object
Section titled “get_server_class -> class_object”Returns server software class Nginx.
Server = get_server_class
Server.echo "hello world" # Nginx.echo is calledserver_name -> string
Section titled “server_name -> string”Returns server software name NGINX as a string.
if server_name == "NGINX" Server = Nginxelsif server_name == "Apache" Server = ApacheendNginx Class
Section titled “Nginx Class”Class Methods
Section titled “Class Methods”Nginx.rputs(string)
Section titled “Nginx.rputs(string)”Puts response text.
If a post-read, server rewrite, rewrite, access or content handler raises an exception afterwards, the request gets 500 and the text is not sent, unless the response was already started, for example by the location that Nginx.redirect ran.
Since 2.7.1 this also holds for a handler that raises before it waits in Nginx::Async; in 2.7.0 such a handler sent the text with status 200.
In an mruby_set* handler, a log handler or an output filter, the text is not sent after an exception either, and the request goes on as after an exception without output: Content-Length does not count the text (since 2.7.1).
For an mruby_set* handler this holds when the code raises before it waits in Nginx::Async. When it raises after Nginx::Async.sleep, the request gets 500; when it raises after Nginx::Async::HTTP.sub_request, nginx has already gone on with the content phase without waiting for the variable, so the 500 is not sent and the client gets no response, as described under Nginx::return instead of raise.
Nginx.rputs "hello ngx_mruby world!"An argument that is not a String is converted with to_s, so Nginx.rputs nil
writes nothing, as print nil does in CRuby. A content handler that writes
nothing and sets no status answers 500 (see
Nginx.return).
Nginx.echo(string)
Section titled “Nginx.echo(string)”Puts response text with a newline.
Like Nginx.rputs, the text is not sent when the handler raises an exception afterwards (since 2.7.1).
Nginx.echo "hello ngx_mruby world!"is equal to
Nginx.rputs "hello ngx_mruby world!\n"Nginx.return(nginx_status_code)
Section titled “Nginx.return(nginx_status_code)”Returns nginx status code to send back HTTP status to the client or control nginx request processing flow. The status code consists of nginx internal status and HTTP status.
Nginx.return Nginx::HTTP_SERVICE_UNAVAILABLE # returns HTTP status 503A content handler that ends without output answers 500 with nginx’s error
page, unless it set a status that nginx answers by itself:
Nginx::HTTP_CREATED, Nginx::HTTP_NO_CONTENT (204 without a body) or a
status from 300 up. This covers Nginx::HTTP_OK and the other 2xx statuses
as well as a handler that sets no status. error.log gets a line at the error
level that ends with response body is empty. return NGX_HTTP_INTERNAL_SERVER_ERROR.
To answer with an empty body, use Nginx::HTTP_NO_CONTENT:
location /empty { mruby_content_handler_code 'Nginx.return Nginx::HTTP_NO_CONTENT'; # 204 without a body}A content handler on the main request that writes output with Nginx.rputs
or Nginx.echo and then calls Nginx.return (or Nginx.send_header,
Nginx.status_code=) answers as follows, also after
Nginx::Async::HTTP.sub_request resumed it:
Nginx::HTTP_OK, or another status below 300 other thanNginx::HTTP_CREATEDandNginx::HTTP_NO_CONTENT: the output, with that status andContent-Lengthof the output, like nginx’s ownreturn 202 "text";without itsContent-Type. A status below 200 goes out the same way, although HTTP does not allow a final response with it.Nginx.return 0sets no status, and the output gets 200. Since 2.7.2; in 2.7.1 these statuses, other than 200, left the client without a response.Nginx::HTTP_CREATED,Nginx::HTTP_NO_CONTENTor a status from 300 up: nginx’s own response for that status, without the output.
A status set before the first Nginx.rputs or Nginx.echo does not apply to
the output: the response is 200.
location /accepted { mruby_content_handler_code ' Nginx.rputs "queued" Nginx.return Nginx::HTTP_ACCEPTED # 202 with the body "queued" ';}In a subrequest (Nginx::Async::HTTP.sub_request, an SSI include,
auth_request), only Nginx::HTTP_OK without output answers 500. A content
handler that writes nothing there and sets no status or another status below
300 ends the subrequest without a response body, and the parent request
answers. After output, a status other than Nginx::HTTP_OK ends the
subrequest without a response body as well.
Don’t confuse Nginx.return method with mruby’s return statement.
ngx_mruby v2 supports return statement in handler code as below.
It just returns from the handler.
location /foo { mruby_content_handler_code ' Nginx.rputs "foo" # generates HTTP body "foo" Nginx.return Nginx::HTTP_OK # returns HTTP status 200 return if true # returns from this handler Nginx.rputs "bar" # not reached ';}In 2.x, a return inside a block or inside the body of for at the top
level of handler code does not return from the handler: mruby 3.3.0, which
2.x bundles, raises LocalJumpError (unexpected return) there, and
error.log records it as mrb_run failed. The handler then fails as after any
other exception: a rewrite or content handler answers 500, and the output
that the code wrote before the return is not sent (2.7.0 sent it with 200;
see Nginx.rputs). Calling Nginx.return there does not
end the code either: it sets the status, and the code after the block still
runs. To end the handler from a block, leave the block with break and
return at the top level of the code, or put the code in a method (or in a
lambda, ->() do ... end.call) and call it, so that the return returns
from the method or the lambda:
location /foo_break { mruby_content_handler_code ' done = false ["foo"].each do |body| Nginx.rputs body # generates HTTP body "foo" Nginx.return Nginx::HTTP_OK # returns HTTP status 200 done = true break # leaves the block end return if done # returns from this handler Nginx.rputs "bar" # not reached ';}
location /foo_method { mruby_content_handler_code ' def foo ["foo"].each do |body| Nginx.rputs body # generates HTTP body "foo" Nginx.return Nginx::HTTP_OK # returns HTTP status 200 return # returns from the method foo end Nginx.rputs "bar" # not reached end foo ';}ngx_mruby 3.0.0 handles such a return as the end of the handler code; see
the entry “A return inside a block or a for body of handler code ends the
code” in
docs/releases/v3.0.0.md
on next.
Nginx.send_header(nginx_status_code)
Section titled “Nginx.send_header(nginx_status_code)”Alias for Nginx.return
Nginx.status_code=(nginx_status_code)
Section titled “Nginx.status_code=(nginx_status_code)”Alias for Nginx.return
Nginx.errlogger(log_level, string)
Section titled “Nginx.errlogger(log_level, string)”Sends an error to the log file via ngx_
Nginx.errlogger Nginx::LOG_ERR, "ngx_mruby error!"You will see an error message in error.log as below.
2014/03/03 00:07:09 [error] 37667#0: *2 ngx_mruby error!, client: 192.168.12.9, server: localhost, request: "GET /log-test HTTP/1.1", host: "192.168.12.9:8001"The code of mruby_init*, mruby_init_worker*, mruby_exit_worker*, mruby_ssl_handshake_handler* and mruby_server_context_handler_code runs outside a request.
There the method writes the message to nginx’s error log, without the client and request part (since 2.7.1; 2.7.0 raised a RuntimeError when the process had not handled a request yet, and otherwise wrote through the last request that the process had handled).
Code outside a request can also call Nginx.module_name, Nginx.module_version, Nginx.nginx_version, Nginx.server_version, Nginx.configure, Nginx.remove_global_variable and server_name, use the constants, and use classes that do not depend on a request, such as Userdata.
Since 2.7.1 the request-scoped methods raise a RuntimeError (this method can only be used while processing a request) there: the methods of Nginx::Request, Nginx::Var, Nginx::Headers_in, Nginx::Headers_out, Nginx::Connection, Nginx::Server, Nginx::Filter, Nginx::Upstream and Nginx::Async, and Nginx.rputs, Nginx.echo, Nginx.return, Nginx.send_header, Nginx.status_code= and Nginx.redirect.
In 2.7.0 they crashed the process when it had not handled a request yet, and otherwise returned or changed data of the last request that the process had handled.
Nginx::Server#add_listener works only in mruby_server_context_handler_code, and Nginx::SSL only in mruby_ssl_handshake_handler*.
Nginx.log(log_level, string)
Section titled “Nginx.log(log_level, string)”Alias for Nginx.errlogger.
Outside a request it writes to nginx’s error log, as described under Nginx.errlogger (since 2.7.1).
Nginx.module_name -> string
Section titled “Nginx.module_name -> string”Returns module name ngx_mruby.
Nginx.echo Nginx.module_name #=> ngx_mrubyNginx.module_version -> string
Section titled “Nginx.module_version -> string”Returns ngx_mruby version as a string.
Nginx.echo Nginx.module_version #=> 0.0.1Nginx.nginx_version -> string
Section titled “Nginx.nginx_version -> string”Returns nginx version as a string.
Nginx.echo Nginx.nginx_version #=> 1.4.4Nginx.server_version -> string
Section titled “Nginx.server_version -> string”Returns server software version as a string. Alias for Nginx.nginx_version.
It’s provided to write portable code for mod_mruby.
Nginx.configure -> string
Section titled “Nginx.configure -> string”Returns nginx build configuration as a string. It’s same as output of nginx -V configure arguments.
Nginx.echo Nginx.configure #=> --add-module=/home/matsumoto_r/DEV/ngx_mruby \ # --add-module=/home/matsumoto_r/DEV/ngx_mruby/dependence/ngx_devel_kit \ # --prefix=/usr/local/nginx-1.4.4Nginx.redirect(url_or_internal_location, http_status=Nginx::HTTP_MOVED_TEMPORARILY)
Section titled “Nginx.redirect(url_or_internal_location, http_status=Nginx::HTTP_MOVED_TEMPORARILY)”Redirects to the URL or the internal location. It is designed to be used in the rewrite handlers.
The URL redirect returns HTTP status codes 3xx like 307 Temporary Redirect with Location header to the client.
Nginx.redirect "http://ngx.mruby.org/", Nginx::HTTP_MOVED_PERMANENTLYThe internal redirect never returns response to the client. The original request is internally forwarded to other location, then the location returns to a response to the client. See error_page and internal directives, and Creating NGINX Rewrite Rules for more about the internal redirect.
The internal redirect runs the handlers of the other location before the call returns.
When an mruby handler or filter of that location raises an exception, the exception ends that handler as it does without the redirect: the request gets 500 unless its response was already started.
The exception does not reach the code that called Nginx.redirect, which goes on after the call.
This holds since 2.7.3; up to 2.7.2 the exception reached the calling code, which could rescue it, and nginx did not finish the request.
location /secret-location { internal; mruby_content_handler_code ' r = Nginx::Request.new Nginx.echo "Returns from /secret-location." Nginx.return Nginx::HTTP_OK ';}
location /public-location { mruby_content_handler_code ' Nginx.redirect "/secret-location" ';}Nginx.remove_global_variable
Section titled “Nginx.remove_global_variable”Removes a mruby’s global variable.
$a = 1Nginx.echo global_variables #=> [:$stdout, :$$, :$/, :$stdin, :$?, :$a, :$stderr, :$1, :$2, :$3, :$4, :$5, :$6, :$7, :$8, :$9]Nginx.remove_global_variable :$aNginx.echo global_variables #=> [:$stdout, :$$, :$/, :$stdin, :$?, :$stderr, :$1, :$2, :$3, :$4, :$5, :$6, :$7, :$8, :$9]Constants
Section titled “Constants”Constants for log levels
Section titled “Constants for log levels”Log levels for Nginx.errlogger that mirror nginx error log levels.
See nginx log levels and
core/ngx_log.h.
| Name | Description |
|---|---|
| Nginx:: |
Defined in core/ngx_log.h, but it’s never used |
| Nginx:: |
Emergency error log level |
| Nginx:: |
Alert error log level |
| Nginx:: |
Critical error log level |
| Nginx:: |
Error log level |
| Nginx:: |
Warning log level |
| Nginx:: |
Notice log level |
| Nginx:: |
Information log level |
| Nginx:: |
Debug log level |
Constants for HTTP status
Section titled “Constants for HTTP status”HTTP status and internal nginx status for Nginx.return.
See nginx HTTP Return Codes for the HTTP statuses.
The statuses from Nginx::OK (0) to Nginx::ABORT (-6) are internally used to control nginx processing flow.
They are defined in core/ngx_core.h.
| Name | Value |
|---|---|
| Nginx:: |
0 |
| Nginx:: |
-1 |
| Nginx:: |
-2 |
| Nginx:: |
-3 |
| Nginx:: |
-4 |
| Nginx:: |
-5 |
| Nginx:: |
-6 |
| Nginx:: |
100 |
| Nginx:: |
101 |
| Nginx:: |
102 |
| Nginx:: |
200 |
| Nginx:: |
201 |
| Nginx:: |
202 |
| Nginx:: |
204 |
| Nginx:: |
206 |
| Nginx:: |
300 |
| Nginx:: |
301 |
| Nginx:: |
302 |
| Nginx:: |
303 |
| Nginx:: |
304 |
| Nginx:: |
307 |
| Nginx:: |
400 |
| Nginx:: |
401 |
| Nginx:: |
403 |
| Nginx:: |
404 |
| Nginx:: |
405 |
| Nginx:: |
408 |
| Nginx:: |
409 |
| Nginx:: |
411 |
| Nginx:: |
412 |
| Nginx:: |
413 |
| Nginx:: |
414 |
| Nginx:: |
415 |
| Nginx:: |
416 |
| Nginx:: |
429 |
| Nginx:: |
444 |
| Nginx:: |
494 |
| Nginx:: |
494 |
| Nginx:: |
495 |
| Nginx:: |
496 |
| Nginx:: |
497 |
| Nginx:: |
499 |
| Nginx:: |
500 |
| Nginx:: |
501 |
| Nginx:: |
502 |
| Nginx:: |
503 |
| Nginx:: |
504 |
| Nginx:: |
507 |
Nginx::SSL Class
Section titled “Nginx::SSL Class”Nginx::RuntimeError when they are called anywhere else, for example in mruby_content_handler_code; in 2.7.0 such a call could crash the worker or return meaningless values.
A handshake whose code sets no certificate, also one whose code does not call Nginx::SSL.new, uses the server’s ssl_certificate and ssl_certificate_key (since 2.7.1; in 2.7.0 a handshake whose code did not call Nginx::SSL.new could get the certificate that an earlier handshake on the same worker had set, or fail).
Instance Methods
Section titled “Instance Methods”Nginx::SSL#servername -> string
Section titled “Nginx::SSL#servername -> string”Returns the SNI server name from the client. The client chooses this name, Treat it as untrusted input (see Trust boundary): look it up in a table of known names, and do not build a path from it.
http { mruby_init_code ' CERT_DIRS = { "example.com" => "/etc/nginx/certs/example.com", "www.example.com" => "/etc/nginx/certs/www.example.com", } ';
server { listen 443 ssl; ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate_key /etc/nginx/certs/default.key;
mruby_ssl_handshake_handler_code ' ssl = Nginx::SSL.new dir = CERT_DIRS[ssl.servername] if dir ssl.certificate = "#{dir}/cert.pem" ssl.certificate_key = "#{dir}/key.pem" end '; }}The lookup is exact: the name is compared as the client sent it, including its case. A name that is not in CERT_DIRS, also an empty name from a client that sends none, keeps the certificate of ssl_certificate and ssl_certificate_key.
Nginx::SSL#certificate=(string)
Section titled “Nginx::SSL#certificate=(string)”Sets the certificate file path used for the connection. The worker reads the file during the handshake. Take the path from a table, not from the server name.
mruby_ssl_handshake_handler_code ' ssl = Nginx::SSL.new dir = CERT_DIRS[ssl.servername] if dir ssl.certificate = "#{dir}/cert.pem" ssl.certificate_key = "#{dir}/key.pem" end';CERT_DIRS is the table of the example under servername.
Nginx::SSL#certificate_key=(string)
Section titled “Nginx::SSL#certificate_key=(string)”Sets the certificate key file path used for the connection.
Set it together with certificate=; the handshake changes the certificate only when both are set.
Take the path from a table, not from the server name.
mruby_ssl_handshake_handler_code ' ssl = Nginx::SSL.new dir = CERT_DIRS[ssl.servername] if dir ssl.certificate = "#{dir}/cert.pem" ssl.certificate_key = "#{dir}/key.pem" end';CERT_DIRS is the table of the example under servername.
Nginx::SSL#certificate_data=(string)
Section titled “Nginx::SSL#certificate_data=(string)”Sets the certificate data used for the connection, as a string in PEM format (the certificate, then its chain).
Read the files once in the init code, so that the handshake does not read a file, and look the data up by server name.
The init code runs once, so a certificate that changes on disk reaches the handshake after nginx -s reload.
http { mruby_init_code ' CERT_DATA = {} ["example.com", "www.example.com"].each do |name| CERT_DATA[name] = [ File.read("/etc/nginx/certs/#{name}/cert.pem"), File.read("/etc/nginx/certs/#{name}/key.pem"), ] end ';
server { listen 443 ssl; ssl_certificate /etc/nginx/certs/default.crt; ssl_certificate_key /etc/nginx/certs/default.key;
mruby_ssl_handshake_handler_code ' ssl = Nginx::SSL.new data = CERT_DATA[ssl.servername] if data ssl.certificate_data = data[0] ssl.certificate_key_data = data[1] end '; }}Nginx::SSL#certificate_key_data=(string)
Section titled “Nginx::SSL#certificate_key_data=(string)”Sets the certificate key data used for the connection, as a string in PEM format.
Set it together with certificate_data=; the handshake changes the certificate by data only when both are set, and then it does not use the paths.
mruby_ssl_handshake_handler_code ' ssl = Nginx::SSL.new data = CERT_DATA[ssl.servername] if data ssl.certificate_data = data[0] ssl.certificate_key_data = data[1] end';CERT_DATA is the table of the example under certificate_data=.
Nginx::SSL.errlogger(log_level, string)
Section titled “Nginx::SSL.errlogger(log_level, string)”Sends an error to the log file via ngx_
Nginx::SSL.errlogger Nginx::LOG_ERR, "ngx_mruby error!"Nginx::SSL.log(log_level, string)
Section titled “Nginx::SSL.log(log_level, string)”Alias for Nginx::
Nginx::SSL#local_port -> integer
Section titled “Nginx::SSL#local_port -> integer”Returns the port number used for the connection.
mruby_ssl_handshake_handler_code ' ssl = Nginx::SSL.new Userdata.new.ssl_local_port = ssl.local_port';
location /local_port { mruby_content_handler_code "Nginx.rputs Userdata.new.ssl_local_port.to_s";}Nginx::SSL#tls_version -> string
Section titled “Nginx::SSL#tls_version -> string”Returns the name of the protocol like TLSv1.3 used for the connection.
This is a wrapper for SSL_get_version(). See SSL_
mruby_ssl_handshake_handler_code ' ssl = Nginx::SSL.new Userdata.new.ssl_tls_version = ssl.tls_version';
location /tls_version { mruby_content_handler_code "Nginx.rputs Userdata.new.ssl_tls_version.to_s";}Nginx::Request Class
Section titled “Nginx::Request Class”Instance Methods
Section titled “Instance Methods”Nginx::Request#scheme -> string
Section titled “Nginx::Request#scheme -> string”Returns the scheme name of the requested URL.
# curl https://127.0.0.1/
r = Nginx::Request.newr.scheme #=> httpsNginx::Request#content_type=(string)
Section titled “Nginx::Request#content_type=(string)”Set the content type to the response.
Notice: Unlike the name suggests, Nginx::Request#content_type=() and Nginx::Request#content_type() handle HTTP response, not request.
location /foo { mruby_content_handler_code ' r = Nginx::Request.new r.content_type = "text/plain" Nginx.rputs "This is a plain text" ';}% curl -v http://127.0.0.1:58080/foo
[snip]
< HTTP/1.1 200 OK< Date: Thu, 29 Nov 2018 07:55:22 GMT< Content-Type: text/plain< Content-Length: 20< Connection: keep-alive< hoge: fuga< Server: global_ngx_mruby<* Connection #0 to host 127.0.0.1 left intactThis is a plain textNginx::Request#content_type -> string
Section titled “Nginx::Request#content_type -> string”Returns the content type of the response.
r = Nginx::Request.newr.content_type = "text/plain"
# Do some other things
Nginx.echo r.content_type #=> text/plainNginx::Request#request_line -> string
Section titled “Nginx::Request#request_line -> string”Returns the HTTP request line.
# curl http://127.0.0.1/hello?a=1
r = Nginx::Request.newNginx.echo r.request_line #=> GET /hello?a=1 HTTP/1.1Nginx::Request#request_line=(string)
Section titled “Nginx::Request#request_line=(string)”Sets the string to the HTTP request line.
r = Nginx::Request.newNginx.echo r.request_line = 'GET /hello?a=1&b=1 HTTP/1.1'Nginx::Request#sub_request? -> true or false
Section titled “Nginx::Request#sub_request? -> true or false”Return true if the request is a sub request.
nginx provides a mechanism to internally send a sub request when received a request. See Authentication Based on Subrequest Result for how it works.
r = Nginx::Request.new
# location / { mruby_content_handler /path/to/hook.rb; }Nginx.echo r.sub_request?.to_s #=> "false"Nginx::Request#uri -> string
Section titled “Nginx::Request#uri -> string”Returns an URI without the query parameters in the HTTP request line.
# curl http://127.0.0.1/hello?a=1
r = Nginx::Request.newNginx.echo r.uri #=> /helloNginx::Request#uri=(string)
Section titled “Nginx::Request#uri=(string)”Set the string to uri.
r = Nginx::Request.newNginx.echo r.uri = "/foo"Nginx::Request#unparsed_uri -> string
Section titled “Nginx::Request#unparsed_uri -> string”Returns an URI in the original HTTP request line.
# curl http://127.0.0.1/hello?a=1
r = Nginx::Request.newNginx.echo r.unparsed_uri #=> /hello?a=1Nginx::Request#unparsed_uri=(string)
Section titled “Nginx::Request#unparsed_uri=(string)”Sets the string to unparsed_uri.
r = Nginx::Request.newNginx.echo r.unparsed_uri = "/hello?a=1"Nginx::Request#method -> string
Section titled “Nginx::Request#method -> string”Returns the HTTP method of the request as a string like GET.
# curl http://127.0.0.1/hello?a=1
r = Nginx::Request.newNginx.echo r.method #=> GETNginx::Request#method=(string)
Section titled “Nginx::Request#method=(string)”Sets the string to method.
r = Nginx::Request.newNginx.echo r.method = "POST"Nginx::Request#protocol -> string
Section titled “Nginx::Request#protocol -> string”Returns the request protocol of the request like HTTP/1.1.
# curl http://127.0.0.1/hello?a=1
r = Nginx::Request.newNginx.echo r.protocol #=> HTTP/1.1Nginx::Request#protocol=(string)
Section titled “Nginx::Request#protocol=(string)”Sets the string to the request protocol
# curl http://127.0.0.1/hello?a=1
r = Nginx::Request.newNginx.echo r.protocol = "HTTP/1.0"Nginx::Request#args -> string
Section titled “Nginx::Request#args -> string”Returns the URL query parameters.
See Nginx::
# curl http://127.0.0.1/hello?a=1&b=2
r = Nginx::Request.newNginx.echo r.args #=> a=1&b=2Nginx::Request#args=(string)
Section titled “Nginx::Request#args=(string)”Sets the string to args.
r = Nginx::Request.newNginx.echo r.args "a=10&b=20"Nginx::var -> var
Section titled “Nginx::var -> var”Returns a Var instance of the request.
See Nginx::
r = Nginx::Request.newv = r.varv.exist? "foo" #=> falseNginx::Request#headers_in -> headers_in
Section titled “Nginx::Request#headers_in -> headers_in”Returns a Headers_in instance of the request.
See Nginx::
r = Nginx::Request.newin = r.headers_inin.["User-Agent"] #=> curl/7.52.1Nginx::Request#headers_out -> headers_out
Section titled “Nginx::Request#headers_out -> headers_out”Returns a Headers_out instance of the request.
See Nginx::
r = Nginx::Request.newout = r.headers_outout.["X-NGX-MRUBY-INTERACTION-ID"] = Uuid.uuidNginx::Request#hostname -> string
Section titled “Nginx::Request#hostname -> string”Returns the host name. It’s same as nginx variable $host.
Therefore, the order of precedence is: host name in the request line,
host name in Host HTTP request header, or server name defined in nginx.conf.
# curl http://127.0.0.1:8001/hello?a=1
r = Nginx::Request.newNginx.echo r.hostname #=> "127.0.0.1"Nginx::Request#authority -> string
Section titled “Nginx::Request#authority -> string”Returns authority without userinfo.
# curl -v http://127.0.0.1:8001/hello?a=1
r = Nginx::Request.newNginx.echo r.authority #=> "127.0.0.1:8001"Nginx::Request#filename -> string
Section titled “Nginx::Request#filename -> string”Returns the requested filename. It’s same as nginx variable $request_filename.
# curl -v http://127.0.0.1/hello?a=1
r = Nginx::Request.newNginx.echo r.filename #=> /usr/local/nginx-1.4.4/html/helloNginx::Request#user -> string
Section titled “Nginx::Request#user -> string”Returns the user name of the Basic authentication.
# curl http://127.0.0.1/hello?a=1 -u matsumoto_r
r = Nginx::Request.newNginx.echo r.user #=> matsumoto_rNginx::Request#read_body -> integer
Section titled “Nginx::Request#read_body -> integer”Does nothing and always returns Nginx::
Nginx::Request#get_body -> string
Section titled “Nginx::Request#get_body -> string”Returns the request body as a string.
Notice: If you want to use the the method, you must use mruby_enable_read_request_body directive in nginx.conf to force reading the request body as below.
location /foo { mruby_enable_read_request_body on; # Force reading the request body mruby_access_handler_code ' req = Nginx::Request.new body = req.get_body # Get the body Nginx.log Nginx::LOG_ERR, "body:#{body}" Userdata.new.req_body = body # Set the body to Userdata used in the content handler '; mruby_content_handler_code ' Nginx.rputs Userdata.new.req_body ';}Nginx::Request#body -> string
Section titled “Nginx::Request#body -> string”Alias for Nginx::
Nginx::Request#document_root -> string
Section titled “Nginx::Request#document_root -> string”Returns the document root directory. It is configured by root directive.
See the ngx_
r = Nginx::Request.newr.document_root #=> /usr/local/nginx-1.4.4Nginx::Request#uri_args -> hash
Section titled “Nginx::Request#uri_args -> hash”Returns the URL query parameters as a hash.
# curl http://127.0.0.1/hello?a=1&b=2
r = Nginx::Request.newNginx.echo r.uri_args #=> {"a" => "1", "b" => "2"}Nginx::Request#uri_args=(hash)
Section titled “Nginx::Request#uri_args=(hash)”Set the hash to uri_args.
r = Nginx::Request.newr.uri_args = {"a" => "10", "b" => "20"}Nginx::Request#post_args -> hash
Section titled “Nginx::Request#post_args -> hash”Returns the request body as a hash.
The method assume the content type is application/x-www-form-urlencoded.
# curl http://127.0.0.1/hello?a=1&b=2
r = Nginx::Request.newNginx.echo r.uri_args #=> {"a" => "1", "b" => "2"}Return value examples of the URL related methods
Section titled “Return value examples of the URL related methods”Here is the return value examples of the above URL related methods. if you send a HTTP/1.1 GET request to https://user:pass@api.example.com:8080/foo?a=1&b=2, you will get the following values.
| Method | Return Value |
|---|---|
| scheme | https |
| request_line | GET /foo?a=1&b=2 HTTP/1.1 |
| uri | /foo |
| unparsed_uri | /foo?a=1&b=2 |
| method | GET |
| protocol | HTTP/1.1 |
| args | foo?a=1&b=2 |
| hostname | api.example.com |
| authority | api.example.com:8080 |
| filename | /path/to/document/root/foo |
| user | user |
| uri_args | {“a” => “1”, “b” => “2”} |
| document_root | /path/to/document |
Nginx::Server Class
Section titled “Nginx::Server Class”Instance Methods
Section titled “Instance Methods”Nginx::Server#add_listener(hash)
Section titled “Nginx::Server#add_listener(hash)”Create a listener on the specified IP address and the port in the hash.
The method works only in mruby_server_context_handler_code, while nginx reads the configuration.
Anywhere else, for example in a request handler, it raises a RuntimeError (add_listener can only be used in mruby_server_context_handler_code, since 2.7.1).
s = Nginx::Server.news.add_listener({address: "127.0.0.1:58101"})s.add_listener({address: "58102"})s.add_listener({address: "58103", ssl: true})Here is an example to create multiple listeners on port 20001 to 30000.
http { server { mruby_server_context_handler_code ' s = Nginx::Server.new (20001..30000).each { |port| s.add_listener({address: port.to_s}) } ';
location /mruby { mruby_content_handler_code ' Nginx.rputs "Hello on port #{Nginx::Connection.new.local_port}" '; } }}Nginx::Server#document_root
Section titled “Nginx::Server#document_root”Returns the document root directory.
# curl http://127.0.0.1:8001/hello?a=1
s = Nginx::Server.newNginx.echo s.document_root # => /usr/local/nginx-1.4.4/htmlNginx::Server#realpath_root
Section titled “Nginx::Server#realpath_root”Returns the document root directory with symlinks resolved to real paths.
It’s same as nginx variable $realpath_root.
# curl http://127.0.0.1:8001/hello?a=1
s = Nginx::Server.newNginx.echo s.realpath_root # => /usr/local/nginx-1.4.4/htmlNginx::Server#path
Section titled “Nginx::Server#path”Alias for Nginx::
Nginx::Connection Class
Section titled “Nginx::Connection Class”Instance Methods
Section titled “Instance Methods”Nginx::Connection#remote_ip
Section titled “Nginx::Connection#remote_ip”Returns the client IP address. It’s same as nginx variable $remote_addr.
# curl http://192.168.0.2:8001/hello?a=1 on 192.168.0.1
c = Nginx::Connection.newNginx.echo c.remote_ip # => 192.168.0.1Nginx::Connection#remote_port
Section titled “Nginx::Connection#remote_port”Return the client port number. It’s same as nginx variable $remote_port.
# curl http://192.168.0.2:8001/hello?a=1 on 192.168.0.1
c = Nginx::Connection.newNginx.echo c.remote_port # => 54430Nginx::Connection#local_ip
Section titled “Nginx::Connection#local_ip”Returns the IP address that accepts the request. It’s same as nginx variable $server_addr.
# curl http://192.168.0.2:8001/hello?a=1 on 192.168.0.1
c = Nginx::Connection.newNginx.echo c.local_ip # => 192.168.0.2Nginx::Connection#local_port
Section titled “Nginx::Connection#local_port”Returns the port number that accepts the request. It’s same as nginx variable $server_port.
# curl http://192.168.0.2:8001/hello?a=1 on 192.168.0.1
c = Nginx::Connection.newNginx.echo c.local_port # => 8001Nginx::Var Class
Section titled “Nginx::Var Class”nginx supports embedded variables such as $http_host.
You can get or set the variables via Var class.
See Embedded Variables for
variables supported by the ngx_http_core_module.
You can use Var instance as below.
v = Nginx::Var.newNginx.echo "$http_host core variable is #{v.http_host}"v.http_host = "192.168.0.1"Nginx.echo "$http_host is overridden to #{v.http_host}"Also you can use your own variable.
Notice: You must use set or mruby_set_code directive to define the variable within the accessible context in nginx.conf. You can NOT add a new variable from mruby code.
location /foo { set $backend_user = "foo" mruby_set_code $auth ' r = Nginx::Request.new backend_user = r.var.backend_user backend_pass = lookup_pass_for(user) 'Basic ' + Base64.encode(backend_user + ':' + backend_pass) '; proxy_set_header Authorization $auth; proxy_pass http://backend.example.com;}Instance Methods
Section titled “Instance Methods”Nginx::Var#method_missing(symbol [, *args]) -> result
Section titled “Nginx::Var#method_missing(symbol [, *args]) -> result”It is designed for providing accessor to nginx variable.
The method is called when Nginx::Var#VARNAME or Nginx::Var#VARNAME= is evaluated.
Set the 2nd arg to the variable if the symbol ends with =. Otherwise, returns the value.
The variable is looked up by the name in lowercase. Since 2.7.2, a name that is empty or made only of = raises NoMethodError, and a setter called without a value raises ArgumentError and leaves the variable as it was.
Nginx::Var#set(name, value)
Section titled “Nginx::Var#set(name, value)”Set the value to the nginx variable.
name is looked up in lowercase. Since 2.7.2, set does not change the String or Symbol passed as name.
v = Nginx::Request.new.varv.set "backend", "http://192.168.0.9/" # Set "http://192.168.0.9/" to $backendNginx::Var#.exist? -> true or false
Section titled “Nginx::Var#.exist? -> true or false”Returns true if the variable is defined.
If backend variable is not defined in nginx.conf, you will get false.
v = Nginx::Request.new.varv.exist? "backend" # => falseNginx::Headers_in Class
Section titled “Nginx::Headers_in Class”Headers_in class stores HTTP request headers.
The name comes from ngx_
Instance Methods
Section titled “Instance Methods”Nginx::Headers_in#[](string) -> string
Section titled “Nginx::Headers_in#[](string) -> string”Returns the value of the http request header.
hin = Nginx::Headers_in.newNginx.rputs hin["User-Agent"] #=> curl/7.29.0Nginx::Headers_in#[]=(string, string)
Section titled “Nginx::Headers_in#[]=(string, string)”Sets the value to the http request header.
hin = Nginx::Headers_in.newNginx.rputs hin["User-Agent"] #=> curl/7.29.0
hin["User-Agent"] = "test-agent"Nginx.rputs hin["User-Agent"] #=> test-agentNginx::Headers_in#all -> hash
Section titled “Nginx::Headers_in#all -> hash”Returns the all http request headers.
hin = Nginx::Headers_in.new
hin.all.keys.each do |k| Nginx.echo "#{k}: #{hin[k]}"end$ curl http://127.0.0.1:8001/hello#Host: 127.0.0.1:8001#User-Agent: curl/7.29.0#Accept: */*Nginx::Headers_in#delete(string)
Section titled “Nginx::Headers_in#delete(string)”Delete the field from the http request headers.
hin = Nginx::Headers_in.newhin["X-Remove-Header"] = "to be deleted!"hin.delete("X-Remove-Header")Nginx.rputs hin["X-Remove-Header"] #=> nilNginx::Headers_out Class
Section titled “Nginx::Headers_out Class”Headers_out class stores HTTP response headers.
The name comes from ngx_
Instance Methods
Section titled “Instance Methods”Nginx::Headers_out#[](string) -> string
Section titled “Nginx::Headers_out#[](string) -> string”Returns the value of the http response header.
hout = Nginx::Headers_out.newhout["X-NGX-MRUBY"] = "support"Nginx.rputs hout["X-NGX-MRUBY"] #=> supportNginx::Headers_out#[]=(string, string)
Section titled “Nginx::Headers_out#[]=(string, string)”Sets the value to the http response header.
hout = Nginx::Headers_out.newhout["X-NGX-MRUBY"] = "support"Nginx.rputs hout["X-NGX-MRUBY"] #=> supportNginx::Headers_out#all -> hash
Section titled “Nginx::Headers_out#all -> hash”Returns the all http response headers.
hout = Nginx::Headers_out.new
hout["X-NGX-MRUBY"] = "support"hout.all.keys.each do |k| Nginx.echo "#{k}: #{hout[k]}"end$ curl -v http://192.168.12.9:8001/hello?a=1#X-NGX-MRUBY: supportNginx::Headers_out#delete(string)
Section titled “Nginx::Headers_out#delete(string)”Delete the field from the http response headers.
hout = Nginx::Headers_out.newhout["X-Remove-Header"] = "to be deleted!"hout.delete("X-Remove-Header")Nginx.rputs hout["X-Remove-Header"] #=> nilNginx::Filter Class
Section titled “Nginx::Filter Class”Nginx::Nginx::Filter#body returns an empty string: in a content handler, as before, and in a header filter (since 2.7.1).
Outside an output body filter, Nginx::Filter#body= and #output raise a RuntimeError (since 2.7.1).
Notice: You can NOT use Nginx.rputs and Nginx.echo in the output header and body handlers
(mruby_output_header_filter, mruby_output_body_filter and their _code forms).
Here is an example how it works.
location /foo { return 200 hello;}
location /bar { mruby_output_header_filter_code ' Nginx::Request.new.headers_out["X-Filter"] = "on" '; mruby_output_body_filter_code ' f = Nginx::Filter.new f.body = f.body.upcase '; return 200 hello;}$ curl -v http://127.0.0.1:59090/foo
[snip]
< HTTP/1.1 200 OK< Server: nginx/1.15.7< Date: Wed, 05 Dec 2018 06:27:19 GMT< Content-Type: text/plain< Content-Length: 5< Connection: keep-alive<* Connection #0 to host 127.0.0.1 left intacthello$ curl -v http://127.0.0.1:59090/bar
[snip]
< HTTP/1.1 200 OK< Server: nginx/1.15.7< Date: Wed, 05 Dec 2018 06:27:24 GMT< Content-Type: text/plain< Content-Length: 5< Connection: keep-alive< X-Filter: on<* Connection #0 to host 127.0.0.1 left intactHELLOInstance Methods
Section titled “Instance Methods”Nginx::Filter#body -> string
Section titled “Nginx::Filter#body -> string”Returns the response body.
In a header filter, which runs before the body has been read, it returns an empty string (since 2.7.1; 2.7.0 returned a string as long as Content-Length whose bytes were not the body, or raised an ArgumentError when the length was unknown or 10 MB or more).
To learn the length there, read Nginx::Var.new.sent_http_content_length.
f = Nginx::Filter.newresponse = f.body.upcaseNginx::Filter#body=(string)
Section titled “Nginx::Filter#body=(string)”Sets the string to the response body.
The response is sent with exactly this 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.
It can only be used in an output body filter; anywhere else it raises a RuntimeError (since 2.7.1).
f = Nginx::Filter.newf.body = "The original body is removed"Nginx::Filter#output
Section titled “Nginx::Filter#output”Alias for Nginx::Filter#body=.
Nginx::Upstream Class
Section titled “Nginx::Upstream Class”You can access upstream configuration via Nginx::
http { upstream my_upstream { server 127.0.0.1:80; } server { location /foo { mruby_rewrite_handler_code ' u = Nginx::Upstream.new "my_upstream" u.server = "127.0.0.1:58081" # Change 'server' to 127.0.0.1:58081 from 127.0.0.1:80 Nginx.return Nginx::DECLINED '; proxy_pass http://my_upstream; } }}Instance Methods
Section titled “Instance Methods”Nginx::Upstream#new(string) -> upstream
Section titled “Nginx::Upstream#new(string) -> upstream”Creates and returns an Upstream instance.
The string is the whole name of an upstream {} block, compared case-insensitively as nginx compares upstream names. The method raises RuntimeError when no upstream has that name, and TypeError when the argument is not a String. Up to 2.7.2 the method compared only the length of the argument, so it also found the first upstream whose name started with it, and it did not check the class of the argument.
u = Nginx::Upstream.new "YOUR_UPSTREAM_NAME"Nginx::Upstream#keepalive_cache -> integer
Section titled “Nginx::Upstream#keepalive_cache -> integer”Returns the keepalive cache of the upstream.
u = Nginx::Upstream.new "YOUR_UPSTREAM_NAME"n = u.keepalive_cacheNginx::Upstream#keepalive_cache=(integer)
Section titled “Nginx::Upstream#keepalive_cache=(integer)”Sets the keepalive cache of the upstream.
u = Nginx::Upstream.new "YOUR_UPSTREAM_NAME"u.keepalive_cache = 0Nginx::Upstream#server -> string
Section titled “Nginx::Upstream#server -> string”Returns the server of the upstream.
u = Nginx::Upstream.new "YOUR_UPSTREAM_NAME"Nginx.echo u.server #=> 127.0.0.1:80Nginx::Upstream#server=(string)
Section titled “Nginx::Upstream#server=(string)”Sets the string to the server of the upstream.
The servers of the upstream block that are not backup must have one address in all: Nginx::Upstream.new raises RuntimeError for more, for example for two server lines, or for one whose host name nginx resolved to two addresses. backup servers are not counted, and the method does not change them. The new server is that peer’s for every later request that the worker sends to the upstream, not only for the current request, until the worker exits or the configuration is reloaded; each worker keeps its own. An upstream with a zone is not supported: since 2.7.3 the method raises RuntimeError for one and leaves its server. Up to 2.7.2 it changed the server, and the change was not valid in the other workers (see “Not changed by this release” of the Nginx::Upstream#server= entry in the 2.7.2 release notes).
The string is an address and a port, read as nginx reads the address of a server directive: an IPv6 address goes in brackets, and unix: with a path names a UNIX-domain socket. The port is 80 when the string has none. A host name is resolved when the method is called, with the system resolver, and its first address is used; the worker serves no other client while it waits (see “What the operator’s code is responsible for” in the documentation), so give an IP address. The method raises TypeError when the argument is not a String (since 2.7.3), ArgumentError when the string is empty or 256 bytes or longer, and RuntimeError when nginx cannot read or resolve it; the server stays as it was then.
u = Nginx::Upstream.new "YOUR_UPSTREAM_NAME"s = u.server #=> 127.0.0.1:80u.server = "127.0.0.1:8080" #=> 127.0.0.1:8080Nginx::Async Class
Section titled “Nginx::Async Class”Instance Methods
Section titled “Instance Methods”Nginx::Async#sleep(msec)
Section titled “Nginx::Async#sleep(msec)”Sleeps in non-blocking way.
It’s currently supported in the set, rewrite, access and content handlers.
In a content handler (mruby_content_handler*) nginx waits for the handler since 2.7.3: the code after the sleep runs, and the request gets the response that the handler writes or the status that it returns. Up to 2.7.2 the request ended at the sleep without a response (see “Known limitations” in the 2.7.1 release notes).
A content handler that runs in the location that Nginx.redirect runs from Ruby code still ends the request at the sleep, because the handler that called Nginx.redirect goes on after the call and may answer the request itself.
After the sleep, Nginx::Async::HTTP.sub_request raises a RuntimeError in a content handler.
In a log handler (mruby_log_handler, mruby_log_handler_code) and in the
output filters (mruby_output_header_filter*, mruby_output_body_filter*),
nginx cannot resume a handler that waits, so it raises a RuntimeError (since 2.7.1; in 2.7.0 a sleep in a log handler could crash the worker, and a sleep in a filter stopped the filter there and sent the response unfiltered).
If the handler raises an exception after the call returns, the request gets 500 and the output of Nginx.rputs is not sent, unless the response was already started, for example by the location that Nginx.redirect ran.
Then the 500 is not sent either.
This holds since 2.7.1; in 2.7.0 the client got no response, the output of Nginx.rputs with status 200, or the status that the handler had set before the exception.
Nginx::Async.sleep 3000 # Sleep 3000 millisecNginx::Async::HTTP Class
Section titled “Nginx::Async::HTTP Class”Instance Methods
Section titled “Instance Methods”Nginx::Async::HTTP#sub_request(location, string_or_hash=nil)
Section titled “Nginx::Async::HTTP#sub_request(location, string_or_hash=nil)”Sends a sub request in non-blocking way.
It’s currently supported in the set, rewrite and access handlers.
In a content handler that has waited in Nginx::Async.sleep, it raises a RuntimeError (since 2.7.3), because nginx would not finish the request after the subrequest.
Like Nginx::Async.sleep, it raises a RuntimeError in a log handler and in
the output filters (since 2.7.1; 2.7.0 started the subrequest there).
If the handler raises an exception after the call returns, the request gets 500 and the output of Nginx.rputs is not sent, unless the response was already started, for example by the location that Nginx.redirect ran.
Then the 500 is not sent either.
This holds since 2.7.1, as for Nginx::Async.sleep.
Nginx::Async::HTTP.sub_request "/example", "q1=foo&q2=bar" # Send a sub request with the parameters
res = Nginx::Async::HTTP.last_response # Get the response of the sub request
Nginx.rputs res.body #=> "hello world"Nginx.rputs res.headers #=> {"Date" => "Thu, 29 Nov 2018 07:55:22 GMT", ...}Nginx.rputs res.status #=> 200You can pass a hash instead of the string.
TODO: do we really need Utils.encode_parameters? It is called in sub_request().
Also is the following comment in test/conf/nginx.conf still true?
“# BUG?: using Nginx::
Nginx::Async::HTTP.sub_request "/example", Nginx::Utils.encode_parameters({q1: "foo", q2: "bar"})Nginx::Async::last_response -> http_response
Section titled “Nginx::Async::last_response -> http_response”Returns the response of the last sub request.
See Nginx::
Nginx::Async::HTTP::Response Class
Section titled “Nginx::Async::HTTP::Response Class”Response class returned from Nginx::
Instance Methods
Section titled “Instance Methods”Nginx::Async::HTTP::Response#body -> string
Section titled “Nginx::Async::HTTP::Response#body -> string”Returns the response body of the last sub request.
See Nginx::
Nginx::Async::HTTP::Response#headers -> hash
Section titled “Nginx::Async::HTTP::Response#headers -> hash”Returns the response headers of the last sub request.
See Nginx::
Nginx::Async::HTTP::Response#status -> integer
Section titled “Nginx::Async::HTTP::Response#status -> integer”Returns the HTTP response status of the last sub request.
See Nginx::
RACK Compatible API
Section titled “RACK Compatible API”rack-based-api mrbgem provides RACK compatible APIs. You can write mruby code in the RACK way as below.
location /hello { mruby_content_handler_code ' proc = Proc.new do |env| [200, {"Content-Type" => "text/plain"}, ["hello ngx_mruby world!"]] end run proc ';}Kernel Module Methods
Section titled “Kernel Module Methods”rack-based-api mrbgem adds run method to Kernel module. It takes care everything.
run(obj)
Section titled “run(obj)”Send a call message to the obj.
The obj must respond to call. It takes one argument, the environment.
It must return an array that contains the status, the headers and the body.
See The RACK specification for more details.
class MyApp def call(env) status = 200 headers = {"Content-Type" => "text/plain", "X-NGX-MRUBY-INTERACTION-ID" => Uuid.uuid} body = ["Got a request from " + env["REMOTE_ADDR"]] [status, headers, body] endendrun MyApp.newNginx::Stream class
Section titled “Nginx::Stream class”TODO: cleanup and add descriptions.
example
Section titled “example”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; }}Class Methods
Section titled “Class Methods”Nginx::Stream.add_listener
Section titled “Nginx::Stream.add_listener”Create a listener on the specified IP address and the port in the hash.
Nginx::Stream.add_listener({address: "127.0.0.1:12350"})Nginx::Stream.add_listener({address: "12351"})See Nginx::
The method works only in mruby_stream_server_context_code, while nginx reads the configuration.
Anywhere else, for example in mruby_stream_code or mruby_stream_init_worker_code, it raises a RuntimeError (since 2.7.1).
Nginx::Stream.errlogger(log_level, string)
Section titled “Nginx::Stream.errlogger(log_level, string)”Nginx::Stream.errlogger Nginx::Stream::LOG_NOTICE, "logging something"Nginx::Stream.log(log_level, string)
Section titled “Nginx::Stream.log(log_level, string)”Alias for Nginx::Stream.errlogger.
Nginx::Stream.module_name -> string
Section titled “Nginx::Stream.module_name -> string”Returns the module name ngx_mruby-stream-module.
Nginx::Stream.module_name #=> "ngx_mruby-stream-module"Constants
Section titled “Constants”Constants for log levels
Section titled “Constants for log levels”Log levels for Nginx::Stream.errlogger that mirror nginx error log levels.
See Constants for log levels in the Nginx Class documentation for more details.
| Name | Description |
|---|---|
| Nginx:: |
Defined in core/ngx_log.h, but it’s never used |
| Nginx:: |
Emergency error log level |
| Nginx:: |
Alert error log level |
| Nginx:: |
Critical error log level |
| Nginx:: |
Error log level |
| Nginx:: |
Warning log level |
| Nginx:: |
Notice log level |
| Nginx:: |
Information log level |
| Nginx:: |
Debug log level |
Constants for status
Section titled “Constants for status”Return status for Nginx::Stream::Connection.stream_status.
| Name | Value |
|---|---|
| Nginx:: |
0 |
| Nginx:: |
-1 |
| Nginx:: |
-2 |
| Nginx:: |
-3 |
| Nginx:: |
-4 |
| Nginx:: |
-5 |
| Nginx:: |
-6 |
Nginx::Stream::Connection class
Section titled “Nginx::Stream::Connection class”- example
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; }}Nginx::Stream::Connection#new
Section titled “Nginx::Stream::Connection#new”get the upstream configuration via upstream name
As for Nginx::Upstream.new, the string is the whole name of an upstream {} block of the stream {} block, compared case-insensitively; the method raises RuntimeError when no upstream has that name, and TypeError when the argument is not a String (since 2.7.3; up to 2.7.2 it also found an upstream whose name started with the argument).
# == nginx.conf ==# upstream dynamic_server0 {# server 127.0.0.1:58080;# }c = Nginx::Stream::Connection.new "dynamic_server0"Nginx::Stream::Connection#upstream_server
Section titled “Nginx::Stream::Connection#upstream_server”# == nginx.conf ==# upstream dynamic_server0 {# server 127.0.0.1:58080;# }c = Nginx::Stream::Connection.new "dynamic_server0"c.upstream_server #=> "127.0.0.1:58080"Nginx::Stream::Connection#upstream_server=
Section titled “Nginx::Stream::Connection#upstream_server=”Sets the server of the upstream that Nginx::Stream::Connection.new named. As for Nginx::Upstream#server=, the servers of the upstream block that are not backup must have one address in all, and backup servers are not changed. The new server is that peer’s for every later session that the worker sends to the upstream, until the worker exits or the configuration is reloaded; each worker keeps its own. An upstream with a zone is not supported: since 2.7.3 the method raises RuntimeError for one and leaves its server.
The string is an IP address and a port, such as 127.0.0.1:12345 or [::1]:12345, or unix: with a path; host names are not resolved and raise. A string without a port is accepted, and the port is then 0. The method raises TypeError when the argument is not a String (since 2.7.3), and RuntimeError when the string is empty or 256 bytes or longer, or when nginx cannot read it as an address; the server stays as it was then.
# == nginx.conf ==# upstream dynamic_server0 {# server 127.0.0.1:58080;# }c = Nginx::Stream::Connection.new "dynamic_server0"c.upstream_server #=> "127.0.0.1:58080"c.upstream_server = "192.168.0.3:54321"Nginx::Stream::Connection.stream_status
Section titled “Nginx::Stream::Connection.stream_status”get the current stream status
if Nginx::Stream::Connection.remote_ip == "127.0.0.1" current_status = Nginx::Stream::Connection.stream_status #=> Nginx::Stream::DECLINEDendNginx::Stream::Connection.stream_status=
Section titled “Nginx::Stream::Connection.stream_status=”if Nginx::Stream::Connection.remote_ip == "127.0.0.1" current_status = Nginx::Stream::Connection.stream_status #=> Nginx::Stream::DECLINED Nginx::Stream::Connection.stream_status = Nginx::Stream::ABORT Nginx::Stream.log Nginx::Stream::LOG_NOTICE, ¥ "current status=#{(current_status == Nginx::Stream::DECLINED) ? "NGX_DECLINED" : current_status} but deny from #{Nginx::Stream::Connection.remote_ip} return NGX_ABORT"endNginx::Stream::Connection.remote_ip
Section titled “Nginx::Stream::Connection.remote_ip”if Nginx::Stream::Connection.remote_ip == "127.0.0.1" # something access controlend- access control example
stream { server { listen 12347; mruby_stream_code ' if Nginx::Stream::Connection.remote_ip == "127.0.0.1" current_status = Nginx::Stream::Connection.stream_status Nginx::Stream::Connection.stream_status = Nginx::Stream::ABORT Nginx::Stream.log Nginx::Stream::LOG_NOTICE, "current status=#{(current_status == Nginx::Stream::DECLINED) ? "NGX_DECLINED" : current_status} but deny from #{Nginx::Stream::Connection.remote_ip} return NGX_ABORT" end '; proxy_pass dynamic_server1; }}Nginx::Stream::Connection.{remote_port,local_ip,local_addr,local_port,local_ip_port}
Section titled “Nginx::Stream::Connection.{remote_port,local_ip,local_addr,local_port,local_ip_port}”server { listen 127.0.0.1:12348; mruby_stream_code ' Nginx::Stream.log Nginx::Stream::LOG_NOTICE, "local is #{Nginx::Stream::Connection.local_ip}:#{Nginx::Stream::Connection.local_port} remote_port is #{Nginx::Stream::Connection.remote_ip}:#{Nginx::Stream::Connection.remote_port}" if Nginx::Stream::Connection.local_port != 12348 && Nginx::Stream::Connection.local_ip != "127.0.0.1" Nginx::Stream::Connection.stream_status = Nginx::Stream::ABORT end '; proxy_pass static_server0;}
server { listen 127.0.0.1:12349; mruby_stream_code ' Nginx::Stream.log Nginx::Stream::LOG_NOTICE, "local_ip_port is #{Nginx::Stream::Connection.local_ip_port}" if Nginx::Stream::Connection.local_ip_port != "127.0.0.1:12349" Nginx::Stream::Connection.stream_status = Nginx::Stream::ABORT end '; proxy_pass static_server0;}Nginx::Stream::Async Class
Section titled “Nginx::Stream::Async Class”Method
Section titled “Method”Nginx::Stream::Async#sleep
Section titled “Nginx::Stream::Async#sleep”Do non-blocking sleep. It works in the code of mruby_stream and mruby_stream_code, which runs in the access phase of the stream session.
After the sleep, the session goes on as it does when the code does not sleep, by the result of the code: the next handler for Nginx::Stream::DECLINED (the default of Nginx::Stream::Connection.stream_status), the next phase for Nginx::Stream::OK, the wait of the session for Nginx::Stream::DONE and Nginx::Stream::AGAIN, and the end of the session for Nginx::Stream::ABORT or another status, and for an exception, which error.log records.
This holds since 2.7.3; up to 2.7.2 a session whose code raised or set a status other than Nginx::Stream::DECLINED after the sleep was neither ended nor continued, and an exception after the sleep also aborted the next session.
# sleep 3000 millisecNginx::Stream::Async.sleep 3000