Ruby classes and methods
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.
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”ngx_mruby 3.0.0 does not have the auto-ssl mrbgem (Nginx::SSL::ACME::Client
and Nginx::SSL::ACME::Dehydrated). The
documentation of 2.x describes it, and
The auto-ssl mrbgem and NGX_MRUBY_AUTO_SSL are removed
says why it was removed and what to use instead.
Add classes and methods reference.
Section titled “Add classes and methods reference.”built-in mrbgems
Section titled “built-in mrbgems”The default build adds the classes of the mrbgems that Default mrbgems in the build reference lists, with the class of each gem and a link to the repository that documents it.
Dir comes from the mruby core gem mruby-dir
(mruby/mrbgems/mruby-dir). ngx_mruby 2.x took it from
iij/mruby-dir, which the core gem started from; every method of that gem
stays. The differences:
- Reading or closing a closed
DirraisesIOErrorinstead ofRuntimeError. Dir.openwith a block no longer raises when the block closed theDir.Dir.foreachwith a block closes theDirthat it opened.DirincludesEnumerable, and hasDir.children,Dir.empty?andDir#each_child. With the bundled mruby 4.0.0,Dir.childrenandDir#each_childleave out.and.., as in CRuby. (With mruby 3.3.0 they were aliases ofDir.entriesandDir#eachand included them.)
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 the classes of the mruby core gems that NGX_MRUBY_CORE_GEMS in
build_config.rb lists (the gems in mruby/mrbgems
of that name). Core gems in the install
guide says which core gems of mruby 4.0.0 are in the list, which are left
out and why. The changes that mruby 4.0.0 brings to scripts are listed
under Behavior changes: read before upgrading
in the release notes of v3.0.0, and
Migrating from ngx_mruby 2.x to 3.0.0 has the
steps for finding and changing the scripts that they affect.
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 200 with an empty body (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 as nginx’s return 200;
does: with the status it set, 200 when it set none, Content-Length: 0 and an
empty body, and nginx keeps a keep-alive connection for the next request. It
sends no Content-Type, as the answers with output do not; nginx’s
return 200; sends the one of default_type. A
request body that no handler read is discarded before the empty answer, as
before an answer with output. This
covers Nginx::HTTP_OK and the other statuses from 200 to 299 that nginx does
not answer by itself (for example Nginx::HTTP_ACCEPTED), a handler that
writes nothing or only "" or nil with Nginx.rputs, and a handler that only
sets response headers. A HEAD request gets the same header, and the output
filters of the location run on the empty response. After a HEAD request to a
location with an mruby output body filter, nginx sends the header and closes
the connection instead of keeping it, as it does there for a handler with
output. nginx answers
Nginx::HTTP_CREATED, Nginx::HTTP_NO_CONTENT (204 without a body) and the
statuses from 300 up by itself, for example with its error page. A status below
200 without output answers 500 with nginx’s error page, and error.log gets a
line at the error level that ends with
response body is empty. return NGX_HTTP_INTERNAL_SERVER_ERROR.
location /empty { mruby_content_handler_code 'Nginx.return Nginx::HTTP_OK'; # 200 with Content-Length: 0}In the other handlers, for example a rewrite or an access handler,
Nginx::HTTP_OK without output answers 500 with nginx’s error page and logs
that line. In the content handler of a subrequest
(Nginx::Async::HTTP.sub_request, an SSI include, auth_request),
Nginx::HTTP_OK without output sets the status of the subrequest to 500 and
logs that line too. A content handler of a subrequest that writes nothing and
sets no status or another status below 300 ends the subrequest without a
response body, and the parent request answers.
On the 2.x line, a content handler that ends without output and with no status or a status from 200 to 299 that nginx does not answer by itself answers 500 instead (see docs/releases/v3.0.0.md).
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 the content handler of a subrequest, a status other than Nginx::HTTP_OK
set after output ends the subrequest without a response body, and the parent
request answers.
Don’t confuse Nginx.return method with mruby’s return statement.
ngx_mruby supports return statement in handler code as below.
It just returns from the handler. Since 3.0.0 this holds also for a return
inside a block or the body of for at the top level of the code: the code
after it does not run, and the response is the one that the code set before
it (see the release notes of 3.0.0).
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). On both versions, calling
Nginx.return in a block does not end the code: it sets the status, and the
code after the block still runs. To end the handler from a block in code
that runs on 2.x as well as on 3.0.0, 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 ';}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.newheaders = r.headers_inheaders["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.newheaders = r.headers_outheaders["X-Request-Id"] = r.var.request_idNginx::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 ' + [backend_user + ':' + backend_pass].pack('m0') '; 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.
Since 3.0.0, the first v.NAME or v.NAME = value of a name in a worker process also defines the accessor as a method of Nginx::Var, and the later accesses of that name in the worker call the method instead of method_missing. The method reads and writes the variable as method_missing does: the same values, nil for a name that is not a variable, the same exceptions and the same lines in error.log. A worker defines:
- a getter and a setter for each declared variable that scripts use: the variables of nginx and its modules, and the ones that
setdeclares; - a getter for the first 16 names of prefix variables that scripts use, the variables whose names start with a prefix that nginx defines, such as
arg_,http_,cookie_andupstream_http_. Any suffix makes such a name, so a worker keeps at most 16 of them.
Only a name in lowercase gets a method: the name has to be made of a to z, 0 to 9 and _ (with = at the end for a setter). v.Request_Method reads $request_method through method_missing and defines nothing. No method is defined for a name that is not a variable, for a setter of a prefix variable, for an instance of a subclass of Nginx::Var, when Nginx::Var is frozen, or when Nginx::Var or one of its ancestors already has a method of that name.
The defined methods show in introspection: after the first v.request_method in a worker, v.respond_to?(:request_method) returns true and Nginx::Var.instance_methods(false) lists request_method. What they show depends on the requests that the worker has served, so two workers can answer differently. To tell whether a variable exists, use Nginx::Var#exist?. Once the method exists, a method of the same name that a script defines later on Object or Kernel, for example with a def at the top level of handler code, no longer hides the variable from v.NAME.
Nginx::Connection#remote_ip, #remote_port, #local_ip and #local_port, Nginx::Server#document_root, #realpath_root and #path, and Nginx::Request#hostname, #authority, #filename, #user and #get_body read their variables from nginx directly. Since 3.0.0, a method that a script defines on Nginx::Var does not change what they return.
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, call Nginx::Var.new.sent_http_content_length, which reads the variable.
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"An empty String sends the response with Content-Length: 0 and no body, and
so does a body filter that leaves the body of a response without a body
empty. The 2.x line closes the connection without a response there (see
docs/releases/v3.0.0.md).
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 trust boundary), 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”The values of the session status that Nginx::Stream::Connection.stream_status returns and .stream_status= sets.
| 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