This commit is contained in:
agentzh (章亦春) 2011-08-15 14:09:07 +08:00
Родитель 94c51becfe
Коммит e6f3425f8f
3 изменённых файлов: 566 добавлений и 450 удалений

386
README
Просмотреть файл

@ -179,16 +179,19 @@ Description
integrates the powerful Lua threads (aka Lua coroutines) into the nginx integrates the powerful Lua threads (aka Lua coroutines) into the nginx
event model by means of nginx subrequests. event model by means of nginx subrequests.
Unlike Apache's mod_lua and Lighttpd's mod_magnet, Lua code written atop Unlike Apache's mod_lua
this module can be 100% non-blocking on network traffic as long as you (<http://httpd.apache.org/docs/2.3/mod/mod_lua.html>) and Lighttpd's
use the ngx.location.capture or ngx.location.capture_multi interfaces to mod_magnet (<http://redmine.lighttpd.net/wiki/1/Docs:ModMagnet>), Lua
let the nginx core do all your requests to mysql, postgresql, memcached, code written atop this module can be *100% non-blocking* on network
redis, upstream http web services, and etc etc etc (see ngx_drizzle traffic as long as you use the ngx.location.capture or
ngx.location.capture_multi interfaces to let the nginx core do all your
requests to mysql, postgresql, memcached, redis, upstream http web
services, and etc etc etc (see ngx_drizzle
(<http://github.com/chaoslawful/drizzle-nginx-module>), ngx_postgres (<http://github.com/chaoslawful/drizzle-nginx-module>), ngx_postgres
(<http://github.com/FRiCKLE/ngx_postgres/>), ngx_memc (<http://github.com/FRiCKLE/ngx_postgres/>), ngx_memc
(<http://wiki.nginx.org/NginxHttpMemcModule>), ngx_redis2 (<http://wiki.nginx.org/NginxHttpMemcModule>), ngx_redis2
(<http://github.com/agentzh/redis2-nginx-module>) and ngx_proxy modules (<http://github.com/agentzh/redis2-nginx-module>) and
for details). [[NginxHttpProxyModule]] modules for details).
The Lua interpreter instance is shared across all the requests in a The Lua interpreter instance is shared across all the requests in a
single nginx worker process. single nginx worker process.
@ -285,7 +288,7 @@ Directives
echo "sum = $sum, diff = $diff"; echo "sum = $sum, diff = $diff";
} }
This directive requires the ngx_devel_kit module. This directive requires the ngx_devel_kit (L<https://github.com/simpl/ngx_devel_kit>) module.
set_by_lua_file set_by_lua_file
syntax: *set_by_lua_file $res <path-to-lua-script> [$arg1 $arg2 ...]* syntax: *set_by_lua_file $res <path-to-lua-script> [$arg1 $arg2 ...]*
@ -301,7 +304,8 @@ Directives
You can disable the Lua code cache by setting "lua_code_cache off;" in You can disable the Lua code cache by setting "lua_code_cache off;" in
your nginx.conf. your nginx.conf.
This directive requires the ngx_devel_kit module. This directive requires the ngx_devel_kit
(<https://github.com/simpl/ngx_devel_kit>) module.
content_by_lua content_by_lua
syntax: *content_by_lua <lua-script-str>* syntax: *content_by_lua <lua-script-str>*
@ -414,13 +418,17 @@ Directives
"<lua-script-str>" for every request. The user code may call predefined "<lua-script-str>" for every request. The user code may call predefined
APIs to generate response content. APIs to generate response content.
This hook uses exactly the same mechamism as content_by_lua so all the This hook uses exactly the same mechanism as content_by_lua so all the
nginx APIs defined there are also available here. nginx APIs defined there are also available here.
Note that this handler always runs *after* the standard nginx access Note that this handler always runs *after* the standard
module ( http://wiki.nginx.org/NginxHttpAccessModule ). So the following [[NginxHttpAccessModule]]. So the following will work as expected:
will work as expected: location / { deny 192.168.1.1; allow
192.168.1.0/24; allow 10.1.1.0/16; deny all; location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
deny all;
access_by_lua ' access_by_lua '
local res = ngx.location.capture("/mysql", { ... }) local res = ngx.location.capture("/mysql", { ... })
@ -429,17 +437,22 @@ Directives
# proxy_pass/fastcgi_pass/... # proxy_pass/fastcgi_pass/...
} }
That is, if a client address appears in the blacklist, then
we don't have to bother sending a mysql query to do more That is, if a client address appears in the blacklist, then we don't
advanced authentication in L<access_by_lua|/"access_by_lua">. have to bother sending a MySQL query to do more advanced authentication
in access_by_lua.
It's worth mentioning that, the "ngx_auth_request" module can be It's worth mentioning that, the "ngx_auth_request" module can be
approximately implemented by access_by_lua. For example, location / { approximately implemented by access_by_lua. For example,
auth_request /auth;
location / {
auth_request /auth;
# proxy_pass/fastcgi_pass/postgres_pass/... # proxy_pass/fastcgi_pass/postgres_pass/...
} }
can be implemented in terms of C<ngx_lua> like this
can be implemented in terms of "ngx_lua" like this
location / { location / {
access_by_lua ' access_by_lua '
local res = ngx.location.capture("/auth") local res = ngx.location.capture("/auth")
@ -457,14 +470,16 @@ Directives
# proxy_pass/fastcgi_pass/postgres_pass/... # proxy_pass/fastcgi_pass/postgres_pass/...
} }
Just as any other access-phase handlers, L<access_by_lua|/"access_by_lua"> will NOT run in subrequests.
Just as any other access phase handlers, access_by_lua will *not* run in
subrequests.
Note that calling "ngx.exit(ngx.OK)" just returning from the current Note that calling "ngx.exit(ngx.OK)" just returning from the current
access_by_lua handler, and the nginx request processing control flow access_by_lua handler, and the nginx request processing control flow
will still continue to the content handler. To terminate the current will still continue to the content handler. To terminate the current
request from within the current access_by_lua handler, calling request from within the current access_by_lua handler, calling
"ngx.exit(status)" where status >= 200 (ngx.HTTP_OK) and status < 300 "ngx.exit(status)" where status >= 200 ("ngx.HTTP_OK") and status < 300
(ngx.HTTP_SPECIAL_RESPONSE) for successful quits and ("ngx.HTTP_SPECIAL_RESPONSE") for successful quits and
"ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)" or its friends for failures. "ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)" or its friends for failures.
content_by_lua_file content_by_lua_file
@ -484,8 +499,8 @@ Directives
When the Lua code cache is on (this is the default), the user code is When the Lua code cache is on (this is the default), the user code is
loaded once at the first request and cached. Nginx config must be loaded once at the first request and cached. Nginx config must be
reloaded if you modified the file and expected to see updated behavior. reloaded if you modified the file and expected to see updated behavior.
You can disable the Lua code cache by setting "lua_code_cache off;" in You can disable the Lua code cache by setting lua_code_cache "off" in
your nginx.conf. your "nginx.conf" file.
rewrite_by_lua_file rewrite_by_lua_file
syntax: *rewrite_by_lua_file <path-to-lua-script>* syntax: *rewrite_by_lua_file <path-to-lua-script>*
@ -504,8 +519,8 @@ Directives
When the Lua code cache is on (this is the default), the user code is When the Lua code cache is on (this is the default), the user code is
loaded once at the first request and cached. Nginx config must be loaded once at the first request and cached. Nginx config must be
reloaded if you modified the file and expected to see updated behavior. reloaded if you modified the file and expected to see updated behavior.
You can disable the Lua code cache by setting "lua_code_cache off;" in You can disable the Lua code cache by setting lua_code_cache "off" in
your nginx.conf. your "nginx.conf" file.
access_by_lua_file access_by_lua_file
syntax: *access_by_lua_file <path-to-lua-script>* syntax: *access_by_lua_file <path-to-lua-script>*
@ -524,8 +539,8 @@ Directives
When the Lua code cache is on (this is the default), the user code is When the Lua code cache is on (this is the default), the user code is
loaded once at the first request and cached. Nginx config must be loaded once at the first request and cached. Nginx config must be
reloaded if you modified the file and expected to see updated behavior. reloaded if you modified the file and expected to see updated behavior.
You can disable the Lua code cache by setting "lua_code_cache off;" in You can disable the Lua code cache by setting lua_code_cache "off" in
your nginx.conf. your "nginx.conf" file.
lua_need_request_body lua_need_request_body
syntax: *lua_need_request_body <on | off>* syntax: *lua_need_request_body <on | off>*
@ -541,12 +556,8 @@ Directives
content. content.
If you want to read the request body data from the $request_body If you want to read the request body data from the $request_body
variable, make sure that your have configured "client_body_buffer_size" variable, make sure that your have configured client_body_buffer_size to
to have exactly the same value as "client_max_body_size". See have exactly the same value as client_max_body_size.
http://wiki.nginx.org/HttpCoreModule#client_body_buffer_size
for more details.
If the current location defines rewrite_by_lua or rewrite_by_lua_file, If the current location defines rewrite_by_lua or rewrite_by_lua_file,
then the request body will be read just before the rewrite_by_lua or then the request body will be read just before the rewrite_by_lua or
@ -558,11 +569,19 @@ Directives
The same applies to access_by_lua and access_by_lua_file. The same applies to access_by_lua and access_by_lua_file.
Nginx API for Lua Nginx API for Lua
Input arguments ngx.arg
context: *set_by_lua** syntax: *val = ngx.arg[index]* context: *set_by_lua**
Index the input arguments to the set_by_lua* directives: value = Index the input arguments to the set_by_lua and set_by_lua_file
ngx.arg[n] Here's an example location /foo { set $a 32; set $b 56; directives:
value = ngx.arg[n]
Here's an example
location /foo {
set $a 32;
set $b 56;
set_by_lua $res set_by_lua $res
'return tonumber(ngx.arg[1]) + tonumber(ngx.arg[2])' 'return tonumber(ngx.arg[1]) + tonumber(ngx.arg[2])'
@ -570,6 +589,7 @@ Nginx API for Lua
echo $sum; echo $sum;
} }
that outputs 88, the sum of 32 and 56. that outputs 88, the sum of 32 and 56.
ngx.var.VARIABLE ngx.var.VARIABLE
@ -591,15 +611,22 @@ Nginx API for Lua
"ngx.var[3]", and etc. "ngx.var[3]", and etc.
Core constants Core constants
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** ngx.OK context: *rewrite_by_lua*, access_by_lua*, content_by_lua** ngx.OK (0)
ngx.DONE ngx.AGAIN ngx.ERROR They take the same values of "NGX_OK", ngx.ERROR (-1) ngx.AGAIN (-2) ngx.DONE (-4) They take the same values of
"NGX_AGAIN", "NGX_DONE", "NGX_ERROR", and etc. But now only ngx.exit "NGX_OK", "NGX_AGAIN", "NGX_DONE", "NGX_ERROR", and etc. But now only
only take two of these values, i.e., "NGX_OK" and "NGX_ERROR". ngx.exit only take two of these values, i.e., "NGX_OK" and "NGX_ERROR".
HTTP method constants HTTP method constants
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** value = context: *rewrite_by_lua*, access_by_lua*, content_by_lua**
ngx.HTTP_GET value = ngx.HTTP_HEAD value = ngx.HTTP_PUT value =
ngx.HTTP_POST value = ngx.HTTP_DELETE ngx.HTTP_GET
ngx.HTTP_HEAD
ngx.HTTP_PUT
ngx.HTTP_POST
ngx.HTTP_DELETE
These constants are usually used in ngx.location.catpure and
ngx.location.capture_multi method calls.
HTTP status constants HTTP status constants
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** value = context: *rewrite_by_lua*, access_by_lua*, content_by_lua** value =
@ -614,21 +641,22 @@ Nginx API for Lua
Nginx log level constants Nginx log level constants
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
log_level = ngx.STDERR log_level = ngx.EMERG log_level = ngx.ALERT ngx.STDERR ngx.EMERG ngx.ALERT ngx.CRIT ngx.ERR ngx.WARN ngx.NOTICE
log_level = ngx.CRIT log_level = ngx.ERR log_level = ngx.WARN log_level ngx.INFO ngx.DEBUG
= ngx.NOTICE log_level = ngx.INFO log_level = ngx.DEBUG
These constants are usually used by the ngx.log method.
print print
syntax: *print(...)* syntax: *print(...)*
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Emit args concatenated to "error.log", with log level "ngx.NOTICE" and Emit args concatenated to nginx's "error.log" file, with log level
prefix "lua print: ". "ngx.NOTICE" and prefix "lua print: ".
It's equivalent to ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...) Lua nil It's equivalent to ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...) Lua
arguments are accepted and result in literal "nil", and Lua booleans "nil" arguments are accepted and result in literal "nil", and Lua
result in "true" or "false". booleans result in "true" or "false".
ngx.ctx ngx.ctx
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** context: *rewrite_by_lua*, access_by_lua*, content_by_lua**
@ -690,7 +718,7 @@ Nginx API for Lua
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** context: *rewrite_by_lua*, access_by_lua*, content_by_lua**
Issue a synchronous but still non-blocking "nginx subrequest" using Issue a synchronous but still non-blocking *Nginx Subrequest* using
"uri". "uri".
Nginx subrequests provide a powerful way to make non-blocking internal Nginx subrequests provide a powerful way to make non-blocking internal
@ -742,7 +770,7 @@ Nginx API for Lua
The "args" option can specify extra url arguments, for instance, The "args" option can specify extra url arguments, for instance,
ngx.location.capture('/foo?a=1', { args = { b = 3, c = ':' } } ) is ngx.location.capture('/foo?a=1', { args = { b = 3, c = ':' } } ) is
equivalent to ngx.location.capture('/foo?a=1&b=3&c=%3a') that is, this equivalent to ngx.location.capture('/foo?a=1&b=3&c=%3a') that is, this
method will autmotically escape argument keys and values according to method will automatically escape argument keys and values according to
URI rules and concatenating them together into a complete query string. URI rules and concatenating them together into a complete query string.
Because it's all done in hand-written C, it should be faster than your Because it's all done in hand-written C, it should be faster than your
own Lua code. own Lua code.
@ -757,10 +785,8 @@ Nginx API for Lua
you're using the standard "ngx_proxy" module to serve your subrequests, you're using the standard "ngx_proxy" module to serve your subrequests,
then an "Accept-Encoding: gzip" header in your main request may result then an "Accept-Encoding: gzip" header in your main request may result
in gzip'd responses that your Lua code is not able to handle properly. in gzip'd responses that your Lua code is not able to handle properly.
So always set "proxy_pass_request_headers off" in your subrequest So always set proxy_pass_request_headers "off" in your subrequest
location to ignore the original request headers. See location to ignore the original request headers.
http://wiki.nginx.org/NginxHttpProxyModule#proxy_pass_request_headers
for more details.
ngx.location.capture_multi ngx.location.capture_multi
syntax: *res1, res2, ... = ngx.location.capture_multi({ {uri, options?}, syntax: *res1, res2, ... = ngx.location.capture_multi({ {uri, options?},
@ -818,9 +844,9 @@ Nginx API for Lua
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** context: *rewrite_by_lua*, access_by_lua*, content_by_lua**
Set/add/clear the current request's response headers. Underscores (_) in Set/add/clear the current request's response headers. Underscores ("_")
the header names will be replaced by dashes (-) and the header names in the header names will be replaced by dashes ("-") and the header
will be matched case-insentively. -- equivalent to names will be matched case-insentively. -- equivalent to
ngx.header["Content-Type"] = 'text/plain' ngx.header.content_type = ngx.header["Content-Type"] = 'text/plain' ngx.header.content_type =
'text/plain'; 'text/plain';
@ -833,17 +859,17 @@ Nginx API for Lua
in the response headers. Only array-like tables are accepted. in the response headers. Only array-like tables are accepted.
Note that, for those standard headers that only accepts a single value, Note that, for those standard headers that only accepts a single value,
like Content-Type, only the last element in the (array) table will take like "Content-Type", only the last element in the (array) table will
effect. So ngx.header.content_type = {'a', 'b'} is equivalent to take effect. So ngx.header.content_type = {'a', 'b'} is equivalent to
ngx.header.content_type = 'b' Setting a slot to nil effectively removes ngx.header.content_type = 'b' Setting a slot to "nil" effectively
it from the response headers: ngx.header["X-My-Header"] = nil; same does removes it from the response headers: ngx.header["X-My-Header"] = nil;
assigning an empty table: ngx.header["X-My-Header"] = {}; "ngx.header" same does assigning an empty table: ngx.header["X-My-Header"] = {};
is not a normal Lua table so you cannot iterate through it. "ngx.header" is not a normal Lua table so you cannot iterate through it.
For reading request headers, use the "ngx.req.get_headers()" function For reading request headers, use the ngx.req.get_headers function
instead. instead.
Reading values from ngx.header.HEADER is not implemented yet, and Reading values from "ngx.header.HEADER" is not implemented yet, and
usually you shouldn't need it. usually you shouldn't need it.
ngx.req.get_uri_args ngx.req.get_uri_args
@ -922,9 +948,7 @@ Nginx API for Lua
"ngx.req.get_headers()["Foo"]" will be a Lua (array) table like this: "ngx.req.get_headers()["Foo"]" will be a Lua (array) table like this:
{"foo", "bar", "baz"} Another way to read individual request headers is {"foo", "bar", "baz"} Another way to read individual request headers is
to use "ngx.var.http_HEADER", that is, nginx's standard $http_HEADER to use "ngx.var.http_HEADER", that is, nginx's standard $http_HEADER
variables: variables.
http://wiki.nginx.org/NginxHttpCoreModule#.24http_HEADER
ngx.req.set_header ngx.req.set_header
syntax: *ngx.req.set_header(header_name, header_value)* syntax: *ngx.req.set_header(header_name, header_value)*
@ -958,52 +982,79 @@ Nginx API for Lua
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** context: *rewrite_by_lua*, access_by_lua*, content_by_lua**
Does an internal redirect to uri with args. ngx.exec('/some-location'); Does an internal redirect to "uri" with "args".
ngx.exec('/some-location', 'a=3&b=5&c=6');
ngx.exec('/some-location?a=3&b=5', 'c=6'); Named locations are also ngx.exec('/some-location');
supported, but query strings are ignored. For example location /foo { ngx.exec('/some-location', 'a=3&b=5&c=6');
content_by_lua ' ngx.exec("@bar"); '; } ngx.exec('/some-location?a=3&b=5', 'c=6');
Named locations are also supported, but query strings are ignored. For
example,
location /foo {
content_by_lua '
ngx.exec("@bar");
';
}
location @bar { location @bar {
... ...
} }
Note that this is very different from L<ngx.redirect|/"ngx.redirect"> in that
it's just an internal redirect and no new HTTP traffic is involved. Note that this is very different from ngx.redirect in that it's just an
internal redirect and no new HTTP traffic is involved.
This method never returns. This method never returns.
This method MUST be called before "ngx.send_headers()" or explicit This method *must* be called before ngx.send_headers or explicit
response body outputs by either ngx.print or ngx.say. response body outputs by either ngx.print or ngx.say.
This method is very much like the "echo_exec" directive in the ngx_echo This method is very much like the echo_exec directive in
module. [[NginxHttpEchoModule]].
ngx.redirect ngx.redirect
syntax: *ngx.redirect(uri, status?)* syntax: *ngx.redirect(uri, status?)*
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** context: *rewrite_by_lua*, access_by_lua*, content_by_lua**
Issue an HTTP 301 or 302 redirection to "uri". Issue an "HTTP 301<code> or <code>302" redirection to "uri".
The optional "status" parameter specifies whether 301 or 302 to be used. The optional "status" parameter specifies whether 301 or 302 to be used.
It's 302 (ngx.HTTP_MOVED_TEMPORARILY) by default. It's 302 ("ngx.HTTP_MOVED_TEMPORARILY") by default.
Here's a small example: return ngx.redirect("/foo") which is equivalent Here's a small example:
to return ngx.redirect("http://localhost:1984/foo",
ngx.HTTP_MOVED_TEMPORARILY) assuming the current server name is
"localhost" and it's listening on the 1984 port.
This method MUST be called before "ngx.send_headers()" or explicit return ngx.redirect("/foo")
which is equivalent to
return ngx.redirect("http://localhost:1984/foo", ngx.HTTP_MOVED_TEMPORARILY)
assuming the current server name is "localhost" and it's listening on
the 1984 port.
This method *must* be called before ngx.send_headers or explicit
response body outputs by either ngx.print or ngx.say. response body outputs by either ngx.print or ngx.say.
This method never returns. This method never returns.
This method is very much like the "rewrite" directive with the This method is very much like the rewrite directive with the "redirect"
"redirect" modifier in the standard "ngx_rewrite" module, for example, modifier in the standard [[NginxHttpRewriteModule]], for example, this
this "nginx.conf" snippet rewrite ^ /foo redirect; # nginx config is "nginx.conf" snippet
equivalent to the following Lua code return ngx.redirect('/foo'); -- lua
code while rewrite ^ /foo permanent; # nginx config is equivalent to rewrite ^ /foo redirect; # nginx config
return ngx.redirect('/foo', ngx.HTTP_MOVED_PERMANENTLY) -- Lua code
is equivalent to the following Lua code
return ngx.redirect('/foo'); -- lua code
while
rewrite ^ /foo permanent; # nginx config
is equivalent to
return ngx.redirect('/foo', ngx.HTTP_MOVED_PERMANENTLY) -- Lua code
ngx.send_headers ngx.send_headers
syntax: *ngx.send_headers()* syntax: *ngx.send_headers()*
@ -1012,7 +1063,7 @@ Nginx API for Lua
Explicitly send out the response headers. Explicitly send out the response headers.
Usually you don't have to send headers yourself. ngx_lua will Usually you don't have to send headers yourself. "ngx_lua" will
automatically send out headers right before you output contents via automatically send out headers right before you output contents via
ngx.say or ngx.print. ngx.say or ngx.print.
@ -1024,16 +1075,28 @@ Nginx API for Lua
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** context: *rewrite_by_lua*, access_by_lua*, content_by_lua**
Emit args concatenated to the HTTP client (as response body). Emit arguments concatenated to the HTTP client (as response body). If
response headers have not been sent yet, this function will first send
the headers out, and then output the body data.
Lua nil value will result in outputing "nil", and Lua boolean values Lua "nil" value will result in outputing "nil", and Lua boolean values
will emit "true" or "false". will emit literal "true" or "false", accordingly.
Also, nested arrays of strings are also allowed. The elements in the Also, nested arrays of strings are also allowed. The elements in the
arrays will be sent one by one. For example local table = { "hello, ", arrays will be sent one by one. For example
{"world: ", true, " or ", false, {": ", nil}} } ngx.print(table) will
yield the output hello, world: true or false: nil Non-array table local table = {
arguments will cause a Lua exception to be thrown. "hello, ",
{"world: ", true, " or ", false,
{": ", nil}}
}
ngx.print(table)
will yield the output
hello, world: true or false: nil
Non-array table arguments will cause a Lua exception to be thrown.
ngx.say ngx.say
syntax: *ngx.say(...)* syntax: *ngx.say(...)*
@ -1047,32 +1110,36 @@ Nginx API for Lua
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Log args concatenated to error.log with the given logging level. Log arguments concatenated to error.log with the given logging level.
Lua nil arguments are accepted and result in literal "nil", and Lua Lua "nil" arguments are accepted and result in literal "nil", and Lua
booleans result in "true" or "false". booleans result in literal "true" or "false" outputs.
The "log_level" argument can take constants like "ngx.ERR" and
"ngx.WARN". Check out Nginx log level constants for details.
ngx.flush ngx.flush
syntax: *ngx.flush()* syntax: *ngx.flush()*
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** context: *rewrite_by_lua*, access_by_lua*, content_by_lua**
Force flushing the response outputs. Force flushing the response outputs. This operation has no effect in
HTTP 1.0 buffering output mode. See HTTP 1.0 support.
ngx.exit ngx.exit
syntax: *ngx.exit(status)* syntax: *ngx.exit(status)*
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** context: *rewrite_by_lua*, access_by_lua*, content_by_lua**
When status >= 200 (ngx.HTTP_OK), it will interrupt the execution of the When "status >= 200" ("ngx.HTTP_OK"), it will interrupt the execution of
current Lua thread and returns status code to nginx. the current Lua thread and returns status code to nginx.
When status == 0 (ngx.OK), it will quits the current phase handler (or When "status == 0" ("ngx.OK"), it will quits the current phase handler
content handler if content_by_lua* directives are used). (or content handler if content_by_lua directives are used).
The "status" argument can be "ngx.OK", "ngx.ERROR", The "status" argument can be "ngx.OK", "ngx.ERROR",
"ngx.HTTP_NOT_FOUND", "ngx.HTTP_MOVED_TEMPORARILY", or other HTTP status "ngx.HTTP_NOT_FOUND", "ngx.HTTP_MOVED_TEMPORARILY", or other HTTP status
numbers. constants.
ngx.eof ngx.eof
syntax: *ngx.eof()* syntax: *ngx.eof()*
@ -1093,7 +1160,7 @@ Nginx API for Lua
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Unescape "str" as a escaped URI component. Unescape "str" as an escaped URI component.
ngx.encode_base64 ngx.encode_base64
syntax: *newstr = ngx.encode_base64(str)* syntax: *newstr = ngx.encode_base64(str)*
@ -1115,7 +1182,7 @@ Nginx API for Lua
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Returns today's date (in the format "yyyy-mm-dd") from nginx cached time Returns today's date (in the format "yyyy-mm-dd") from nginx cached time
(no syscall involved unlike Lua's date library). . (no syscall involved unlike Lua's date library).
This is the local time. This is the local time.
@ -1134,7 +1201,8 @@ Nginx API for Lua
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Returns the current timestamp (in the format "yyyy-mm-dd hh:mm:ss") of Returns the current timestamp (in the format "yyyy-mm-dd hh:mm:ss") of
the nginx cached time (no syscall involved unlike Lua's date library). the nginx cached time (no syscall involved unlike Lua's os.date
(<http://www.lua.org/manual/5.1/manual.html#pdf-os.date>) function).
This is the local time. This is the local time.
@ -1144,7 +1212,8 @@ Nginx API for Lua
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Returns the current timestamp (in the format "yyyy-mm-dd hh:mm:ss") of Returns the current timestamp (in the format "yyyy-mm-dd hh:mm:ss") of
the nginx cached time (no syscall involved unlike Lua's date library). the nginx cached time (no syscall involved unlike Lua's os.date
(<http://www.lua.org/manual/5.1/manual.html#pdf-os.date>) function).
This is the UTC time. This is the UTC time.
@ -1182,21 +1251,36 @@ Nginx API for Lua
ngx.is_subrequest ngx.is_subrequest
context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** context: *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Returns true if the current request is an nginx subrequest, or false Returns "true" if the current request is an nginx subrequest, or "false"
otherwise. otherwise.
ndk.set_var.DIRECTIVE ndk.set_var.DIRECTIVE
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** syntax: *res = ndk.set_var.DIRECTIVE_NAME* context: *rewrite_by_lua*,
access_by_lua*, content_by_lua**
This mechanism allows calling other nginx C modules' directives that are This mechanism allows calling other nginx C modules' directives that are
implemented by Nginx Devel Kit (NDK)'s set_var submodule's implemented by Nginx Devel Kit
ndk_set_var_value. (<https://github.com/simpl/ngx_devel_kit>) (NDK)'s set_var submodule's
"ndk_set_var_value".
For example, ngx_set_misc module's "set_escape_uri", For example, [[NginxHttpSetMiscModule]]'s following directives can be
"set_quote_sql_str", and etc. invoked this way:
For instance, local res = ndk.set_var.set_escape_uri('a/b'); -- now res * set_quote_sql_str
== 'a%2fb' This feature requires the ngx_devel_kit module.
* set_quote_pgsql_str
* set_escape_uri
* set_unescape_uri
For instance,
local res = ndk.set_var.set_escape_uri('a/b');
-- now res == 'a%2fb'
This feature requires the ngx_devel_kit
(<https://github.com/simpl/ngx_devel_kit>) module.
HTTP 1.0 support HTTP 1.0 support
The HTTP 1.0 protocol does not support chunked outputs and always The HTTP 1.0 protocol does not support chunked outputs and always
@ -1224,8 +1308,10 @@ Data Sharing within an Nginx Worker
shared data through it. It works because required Lua modules are loaded shared data through it. It works because required Lua modules are loaded
only once, and all coroutines will share the same copy of the module. only once, and all coroutines will share the same copy of the module.
Here's a complete small example: -- mydata.lua module("mydata", Here's a complete small example:
package.seeall)
-- mydata.lua
module("mydata", package.seeall)
local data = { local data = {
dog = 3, dog = 3,
@ -1236,31 +1322,32 @@ Data Sharing within an Nginx Worker
function get_age(name) function get_age(name)
return data[name] return data[name]
end end
and then accessing it from your nginx.conf: and then accessing it from your nginx.conf:
location /lua { location /lua {
content_lua_by_lua ' content_lua_by_lua '
local mydata = require("mydata") local mydata = require("mydata")
ngx.say(mydata.get_age("dog")) ngx.say(mydata.get_age("dog"))
'; ';
} }
Your C<mydata> module in this example will only be loaded
and run on the first request to the location C</lua>, Your "mydata" module in this example will only be loaded and run on the
and all those subsequent requests to the same nginx first request to the location "/lua", and all those subsequent requests
worker process will use the reloaded instance of the to the same nginx worker process will use the reloaded instance of the
module as well as the same copy of the data in it, module as well as the same copy of the data in it, until you send a
until you send a C<HUP> signal to the nginx master "HUP" signal to the nginx master process to enforce a reload.
process to enforce a reload.
This data sharing technique is essential for high-performance Lua apps This data sharing technique is essential for high-performance Lua apps
built atop this module. It's common to cache reusable data globally. built atop this module. It's common to cache reusable data globally.
It's worth noting that this is *per-worker* sharing, not *per-server* It's worth noting that this is *per-worker* sharing, not *per-server*
sharing. That is, when you have multiple nginx worker processes under an sharing. That is, when you have multiple nginx worker processes under an
nginx master, this data sharing cannot pass process boundry. If you nginx master, this data sharing cannot pass process boundary. If you
indeed need server-wide data sharing, you can indeed need server-wide data sharing, you can
1. Use only a single nginx worker and a single server. This is not 1. Use only a single nginx worker and a single server. This is not
recommended when you have a mulit-core CPU or multiple CPUs in a recommended when you have a multi-core CPU or multiple CPUs in a
single machine. single machine.
2. Use some true backend storage like "memcached", "redis", or an RDBMS 2. Use some true backend storage like "memcached", "redis", or an RDBMS
@ -1460,22 +1547,19 @@ Future Plan
Known Issues Known Issues
* Because the standard Lua 5.1 interpreter's VM is not fully * Because the standard Lua 5.1 interpreter's VM is not fully
resumable, the ngx.location.capture and ngx.location.capture_multi resumable, the ngx.location.capture and ngx.location.capture_multi
methods cannot be used within the context of a Lua "pcall()" or methods cannot be used within the context of a Lua pcall()
"xpcall()". If you're heavy on Lua exception model based on Lua's (<http://www.lua.org/manual/5.1/manual.html#pdf-pcall>) or xpcall()
"error()" and "pcall()"/"xpcall()", use LuaJIT 2.0 instead because (<http://www.lua.org/manual/5.1/manual.html#pdf-xpcall>). If you're
LuaJIT 2.0 supports fully resumable VM. heavy on Lua exception model based on Lua's error()
(<http://www.lua.org/manual/5.1/manual.html#pdf-error>) and
"pcall()"/"xpcall()", use LuaJIT 2.0 instead because LuaJIT 2.0
supports fully resume-able VM.
* The ngx.location.capture and ngx.location.capture_multi Lua methods * The ngx.location.capture and ngx.location.capture_multi Lua methods
cannot capture cannot capture locations configured by [[NginxHttpEchoModule]]'s
echo_location, echo_location_async, echo_subrequest, or
locations configured by ngx_echo module's "echo_location", echo_subrequest_async directives. This won't be fixed in the future
"echo_location_async", "echo_subrequest", or "echo_subrequest_async" due to technical problems.
directives. This won't be fixed in the future due to technical problems
:)
* The ngx.location.capture and ngx.location.capture_multi Lua methods
cannot capture locations with internal redirections for now. But
this may get fixed in the future.
* WATCH OUT: Globals WON'T persist between requests, because of the * WATCH OUT: Globals WON'T persist between requests, because of the
one-coroutine-per-request isolation design. Especially watch one-coroutine-per-request isolation design. Especially watch

Просмотреть файл

@ -185,13 +185,13 @@ Description
This module embeds the Lua interpreter or LuaJIT into the nginx core and integrates the powerful Lua threads (aka Lua coroutines) into the nginx event model This module embeds the Lua interpreter or LuaJIT into the nginx core and integrates the powerful Lua threads (aka Lua coroutines) into the nginx event model
by means of nginx subrequests. by means of nginx subrequests.
Unlike Apache's mod_lua and Lighttpd's mod_magnet, Lua code written atop this module can be 100% non-blocking on network traffic Unlike [Apache's mod_lua](http://httpd.apache.org/docs/2.3/mod/mod_lua.html) and [Lighttpd's mod_magnet](http://redmine.lighttpd.net/wiki/1/Docs:ModMagnet), Lua code written atop this module can be *100% non-blocking* on network traffic
as long as you use the `ngx.location.capture` or as long as you use the `ngx.location.capture` or
`ngx.location.capture_multi` interfaces `ngx.location.capture_multi` interfaces
to let the nginx core do all your to let the nginx core do all your
requests to mysql, postgresql, memcached, redis, requests to mysql, postgresql, memcached, redis,
upstream http web services, and etc etc etc (see upstream http web services, and etc etc etc (see
[ngx_drizzle](http://github.com/chaoslawful/drizzle-nginx-module), [ngx_postgres](http://github.com/FRiCKLE/ngx_postgres/), [ngx_memc](http://wiki.nginx.org/NginxHttpMemcModule), [ngx_redis2](http://github.com/agentzh/redis2-nginx-module) and ngx_proxy modules for details). [ngx_drizzle](http://github.com/chaoslawful/drizzle-nginx-module), [ngx_postgres](http://github.com/FRiCKLE/ngx_postgres/), [ngx_memc](http://wiki.nginx.org/NginxHttpMemcModule), [ngx_redis2](http://github.com/agentzh/redis2-nginx-module) and `NginxHttpProxyModule` modules for details).
The Lua interpreter instance is shared across all The Lua interpreter instance is shared across all
the requests in a single nginx worker process. the requests in a single nginx worker process.
@ -302,7 +302,7 @@ for example,
echo "sum = $sum, diff = $diff"; echo "sum = $sum, diff = $diff";
} }
This directive requires the ngx_devel_kit module. This directive requires the [ngx_devel_kit](https://github.com/simpl/ngx_devel_kit) module.
set_by_lua_file set_by_lua_file
--------------- ---------------
@ -319,7 +319,7 @@ once at the first request and cached. Nginx config must be reloaded if you
modified the file and expected to see updated behavior. You can disable the modified the file and expected to see updated behavior. You can disable the
Lua code cache by setting `lua_code_cache off;` in your nginx.conf. Lua code cache by setting `lua_code_cache off;` in your nginx.conf.
This directive requires the ngx_devel_kit module. This directive requires the [ngx_devel_kit](https://github.com/simpl/ngx_devel_kit) module.
content_by_lua content_by_lua
-------------- --------------
@ -453,17 +453,12 @@ access_by_lua
**phase:** *access tail* **phase:** *access tail*
Act as an access phase handler and execute user code specified by `<lua-script-str>` Act as an access phase handler and execute user code specified by `<lua-script-str>` for every request. The user code may call predefined APIs to generate response content.
for every request. The user code may call predefined APIs to generate response
content.
This hook uses exactly the same mechamism as `content_by_lua` This hook uses exactly the same mechanism as `content_by_lua` so all the nginx APIs defined there are also available here.
so all the nginx APIs defined there
are also available here. Note that this handler always runs *after* the standard `NginxHttpAccessModule`. So the following will work as expected:
Note that this handler always runs *after* the standard nginx
access module ( <http://wiki.nginx.org/NginxHttpAccessModule> ).
So the following will work as expected:
location / { location / {
deny 192.168.1.1; deny 192.168.1.1;
@ -479,12 +474,11 @@ So the following will work as expected:
# proxy_pass/fastcgi_pass/... # proxy_pass/fastcgi_pass/...
} }
That is, if a client address appears in the blacklist, then
we don't have to bother sending a mysql query to do more
advanced authentication in `access_by_lua`.
It's worth mentioning that, the `ngx_auth_request` module can be That is, if a client address appears in the blacklist, then we don't have to bother sending a MySQL query to do more advanced authentication in `access_by_lua`.
approximately implemented by `access_by_lua`. For example,
It's worth mentioning that, the `ngx_auth_request` module can be approximately implemented by `access_by_lua`. For example,
location / { location / {
auth_request /auth; auth_request /auth;
@ -492,8 +486,10 @@ approximately implemented by `access_by_lua`. For example,
# proxy_pass/fastcgi_pass/postgres_pass/... # proxy_pass/fastcgi_pass/postgres_pass/...
} }
can be implemented in terms of `ngx_lua` like this can be implemented in terms of `ngx_lua` like this
location / { location / {
access_by_lua ' access_by_lua '
local res = ngx.location.capture("/auth") local res = ngx.location.capture("/auth")
@ -512,11 +508,10 @@ can be implemented in terms of `ngx_lua` like this
# proxy_pass/fastcgi_pass/postgres_pass/... # proxy_pass/fastcgi_pass/postgres_pass/...
} }
Just as any other access-phase handlers, `access_by_lua` will NOT run in subrequests.
Note that calling `ngx.exit(ngx.OK)` just returning from the current `access_by_lua` handler, and the nginx request processing Just as any other access phase handlers, `access_by_lua` will *not* run in subrequests.
control flow will still continue to the content handler. To terminate the current request from within the current `access_by_lua` handler,
calling `ngx.exit(status)` where status >= 200 (ngx.HTTP_OK) and status < 300 (ngx.HTTP_SPECIAL_RESPONSE) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` or its friends for failures. Note that calling `ngx.exit(ngx.OK)` just returning from the current `access_by_lua` handler, and the nginx request processing control flow will still continue to the content handler. To terminate the current request from within the current `access_by_lua` handler, calling `ngx.exit(status)` where status >= 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` or its friends for failures.
content_by_lua_file content_by_lua_file
------------------- -------------------
@ -534,10 +529,7 @@ Nginx variables can be used in `<path-to-lua-script>` string, in order to provid
greater flexibility in practice. But this feature must be used carefully, so is greater flexibility in practice. But this feature must be used carefully, so is
not recommend for beginners. not recommend for beginners.
When the Lua code cache is on (this is the default), the user code is loaded When the Lua code cache is on (this is the default), the user code is loaded once at the first request and cached. Nginx config must be reloaded if you modified the file and expected to see updated behavior. You can disable the Lua code cache by setting `lua_code_cache` `off` in your `nginx.conf` file.
once at the first request and cached. Nginx config must be reloaded if you
modified the file and expected to see updated behavior. You can disable the
Lua code cache by setting `lua_code_cache off;` in your nginx.conf.
rewrite_by_lua_file rewrite_by_lua_file
------------------- -------------------
@ -558,7 +550,7 @@ not recommend for beginners.
When the Lua code cache is on (this is the default), the user code is loaded When the Lua code cache is on (this is the default), the user code is loaded
once at the first request and cached. Nginx config must be reloaded if you once at the first request and cached. Nginx config must be reloaded if you
modified the file and expected to see updated behavior. You can disable the modified the file and expected to see updated behavior. You can disable the
Lua code cache by setting `lua_code_cache off;` in your nginx.conf. Lua code cache by setting `lua_code_cache` `off` in your `nginx.conf` file.
access_by_lua_file access_by_lua_file
------------------ ------------------
@ -579,7 +571,7 @@ not recommend for beginners.
When the Lua code cache is on (this is the default), the user code is loaded When the Lua code cache is on (this is the default), the user code is loaded
once at the first request and cached. Nginx config must be reloaded if you once at the first request and cached. Nginx config must be reloaded if you
modified the file and expected to see updated behavior. You can disable the modified the file and expected to see updated behavior. You can disable the
Lua code cache by setting `lua_code_cache off;` in your nginx.conf. Lua code cache by setting `lua_code_cache` `off` in your `nginx.conf` file.
lua_need_request_body lua_need_request_body
--------------------- ---------------------
@ -592,15 +584,10 @@ lua_need_request_body
**phase:** *depends on usage* **phase:** *depends on usage*
Force reading request body data or not. The client request body won't be read, Force reading request body data or not. The client request body won't be read, so you have to explicitly force reading the body if you need its content.
so you have to explicitly force reading the body if you need its content.
If you want to read the request body data from the `$request_body` variable, make sure that If you want to read the request body data from the `$request_body` variable, make sure that
your have configured `client_body_buffer_size` to have exactly the same value as `client_max_body_size`. See your have configured `client_body_buffer_size` to have exactly the same value as `client_max_body_size`.
<http://wiki.nginx.org/HttpCoreModule#client_body_buffer_size>
for more details.
If the current location defines `rewrite_by_lua` or `rewrite_by_lua_file`, If the current location defines `rewrite_by_lua` or `rewrite_by_lua_file`,
then the request body will be read just before the `rewrite_by_lua` or `rewrite_by_lua_file` code is run (and also at the then the request body will be read just before the `rewrite_by_lua` or `rewrite_by_lua_file` code is run (and also at the
@ -614,16 +601,20 @@ The same applies to `access_by_lua` and `access_by_lua_file`.
Nginx API for Lua Nginx API for Lua
================= =================
Input arguments ngx.arg
--------------- -------
**syntax:** *val = ngx.arg[index]*
**context:** *set_by_lua** **context:** *set_by_lua**
Index the input arguments to the set_by_lua* directives: Index the input arguments to the `set_by_lua` and `set_by_lua_file` directives:
value = ngx.arg[n] value = ngx.arg[n]
Here's an example Here's an example
location /foo { location /foo {
set $a 32; set $a 32;
set $b 56; set $b 56;
@ -635,7 +626,8 @@ Here's an example
echo $sum; echo $sum;
} }
that outputs 88, the sum of 32 and 56.
that outputs `88`, the sum of `32` and `56`.
ngx.var.VARIABLE ngx.var.VARIABLE
---------------- ----------------
@ -669,10 +661,10 @@ Core constants
-------------- --------------
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
ngx.OK ngx.OK (0)
ngx.DONE ngx.ERROR (-1)
ngx.AGAIN ngx.AGAIN (-2)
ngx.ERROR ngx.DONE (-4)
They take the same values of `NGX_OK`, `NGX_AGAIN`, `NGX_DONE`, `NGX_ERROR`, and etc. But now They take the same values of `NGX_OK`, `NGX_AGAIN`, `NGX_DONE`, `NGX_ERROR`, and etc. But now
only `ngx.exit` only take two of these values, i.e., `NGX_OK` and `NGX_ERROR`. only `ngx.exit` only take two of these values, i.e., `NGX_OK` and `NGX_ERROR`.
@ -681,11 +673,15 @@ HTTP method constants
--------------------- ---------------------
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
value = ngx.HTTP_GET
value = ngx.HTTP_HEAD ngx.HTTP_GET
value = ngx.HTTP_PUT ngx.HTTP_HEAD
value = ngx.HTTP_POST ngx.HTTP_PUT
value = ngx.HTTP_DELETE ngx.HTTP_POST
ngx.HTTP_DELETE
These constants are usually used in `ngx.location.catpure` and `ngx.location.capture_multi` method calls.
HTTP status constants HTTP status constants
--------------------- ---------------------
@ -711,15 +707,18 @@ Nginx log level constants
------------------------- -------------------------
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
log_level = ngx.STDERR ngx.STDERR
log_level = ngx.EMERG ngx.EMERG
log_level = ngx.ALERT ngx.ALERT
log_level = ngx.CRIT ngx.CRIT
log_level = ngx.ERR ngx.ERR
log_level = ngx.WARN ngx.WARN
log_level = ngx.NOTICE ngx.NOTICE
log_level = ngx.INFO ngx.INFO
log_level = ngx.DEBUG ngx.DEBUG
These constants are usually used by the `ngx.log` method.
print print
----- -----
@ -727,13 +726,13 @@ print
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Emit args concatenated to `error.log`, with log level `ngx.NOTICE` and prefix `lua print: `. Emit args concatenated to nginx's `error.log` file, with log level `ngx.NOTICE` and prefix `lua print: `.
It's equivalent to It's equivalent to
ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...) ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...)
Lua nil arguments are accepted and result in literal "nil", and Lua booleans result in "true" or "false". Lua `nil` arguments are accepted and result in literal `"nil"`, and Lua booleans result in `"true"` or `"false"`.
ngx.ctx ngx.ctx
------- -------
@ -819,26 +818,19 @@ Overriding `ngx.ctx` with a new Lua table is also supported, for example,
ngx.ctx = { foo = 32, bar = 54 } ngx.ctx = { foo = 32, bar = 54 }
ngx.location.capture ngx.location.capture
-------------------- --------------------
**syntax:** *res = ngx.location.capture(uri, options?)* **syntax:** *res = ngx.location.capture(uri, options?)*
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
Issue a synchronous but still non-blocking "nginx subrequest" using `uri`. Issue a synchronous but still non-blocking *Nginx Subrequest* using `uri`.
Nginx subrequests provide a powerful way to make Nginx subrequests provide a powerful way to make non-blocking internal requests to other locations configured with disk file directory or *any* other nginx C modules like `ngx_proxy`, `ngx_fastcgi`, `ngx_memc`,
non-blocking internal requests to other locations `ngx_postgres`, `ngx_drizzle`, and even `ngx_lua` itself and etc etc etc.
configured with disk file directory or *any*
other nginx C modules like
`ngx_proxy`, `ngx_fastcgi`, `ngx_memc`,
`ngx_postgres`,
`ngx_drizzle`, and even `ngx_lua` itself and etc etc etc.
Also note that subrequests just mimic the HTTP Also note that subrequests just mimic the HTTP interface but there's *no* extra HTTP/TCP traffic *nor* IPC involved. Everything works internally, efficiently, on the C level.
interface but there's *no*
extra HTTP/TCP traffic *nor* IPC involved. Everything
works internally, efficiently, on the C level.
Subrequests are completely different from HTTP 301/302 redirection (via `ngx.redirect`) and internal redirection (via `ngx.exec`). Subrequests are completely different from HTTP 301/302 redirection (via `ngx.redirect`) and internal redirection (via `ngx.exec`).
@ -901,7 +893,7 @@ is equivalent to
ngx.location.capture('/foo?a=1&b=3&c=%3a') ngx.location.capture('/foo?a=1&b=3&c=%3a')
that is, this method will autmotically escape argument keys and values according to URI rules and that is, this method will automatically escape argument keys and values according to URI rules and
concatenating them together into a complete query string. Because it's all done in hand-written C, concatenating them together into a complete query string. Because it's all done in hand-written C,
it should be faster than your own Lua code. it should be faster than your own Lua code.
@ -918,9 +910,7 @@ request headers of the current request. This may have unexpected side-effects on
subrequest responses. For example, when you're using the standard `ngx_proxy` module to serve subrequest responses. For example, when you're using the standard `ngx_proxy` module to serve
your subrequests, then an "Accept-Encoding: gzip" header in your main request may result your subrequests, then an "Accept-Encoding: gzip" header in your main request may result
in gzip'd responses that your Lua code is not able to handle properly. So always set in gzip'd responses that your Lua code is not able to handle properly. So always set
`proxy_pass_request_headers off` in your subrequest location to ignore the original request headers. `proxy_pass_request_headers` `off` in your subrequest location to ignore the original request headers.
See <http://wiki.nginx.org/NginxHttpProxyModule#proxy_pass_request_headers> for more
details.
ngx.location.capture_multi ngx.location.capture_multi
-------------------------- --------------------------
@ -975,6 +965,7 @@ of this function. Logically speaking, the `ngx.location.capture` can be implemen
return ngx.location.capture_multi({ {uri, args} }) return ngx.location.capture_multi({ {uri, args} })
end end
ngx.status ngx.status
---------- ----------
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
@ -985,13 +976,14 @@ before sending out the response headers.
ngx.status = ngx.HTTP_CREATED ngx.status = ngx.HTTP_CREATED
status = ngx.status status = ngx.status
ngx.header.HEADER ngx.header.HEADER
----------------- -----------------
**syntax:** *ngx.header.HEADER = VALUE* **syntax:** *ngx.header.HEADER = VALUE*
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
Set/add/clear the current request's response headers. Underscores (_) in the header names will be replaced by dashes (-) and the header names will be matched case-insentively. Set/add/clear the current request's response headers. Underscores (`_`) in the header names will be replaced by dashes (`-`) and the header names will be matched case-insentively.
-- equivalent to ngx.header["Content-Type"] = 'text/plain' -- equivalent to ngx.header["Content-Type"] = 'text/plain'
ngx.header.content_type = 'text/plain'; ngx.header.content_type = 'text/plain';
@ -1009,7 +1001,7 @@ will yield
in the response headers. Only array-like tables are accepted. in the response headers. Only array-like tables are accepted.
Note that, for those standard headers that only accepts a single value, like Content-Type, only the last element Note that, for those standard headers that only accepts a single value, like `Content-Type`, only the last element
in the (array) table will take effect. So in the (array) table will take effect. So
ngx.header.content_type = {'a', 'b'} ngx.header.content_type = {'a', 'b'}
@ -1018,7 +1010,7 @@ is equivalent to
ngx.header.content_type = 'b' ngx.header.content_type = 'b'
Setting a slot to nil effectively removes it from the response headers: Setting a slot to `nil` effectively removes it from the response headers:
ngx.header["X-My-Header"] = nil; ngx.header["X-My-Header"] = nil;
@ -1029,9 +1021,9 @@ same does assigning an empty table:
`ngx.header` is not a normal Lua table so you cannot `ngx.header` is not a normal Lua table so you cannot
iterate through it. iterate through it.
For reading request headers, use the `ngx.req.get_headers()` function instead. For reading request headers, use the `ngx.req.get_headers` function instead.
Reading values from ngx.header.HEADER is not implemented yet, Reading values from `ngx.header.HEADER` is not implemented yet,
and usually you shouldn't need it. and usually you shouldn't need it.
ngx.req.get_uri_args ngx.req.get_uri_args
@ -1177,9 +1169,7 @@ the value of `ngx.req.get_headers()["Foo"]` will be a Lua (array) table like thi
{"foo", "bar", "baz"} {"foo", "bar", "baz"}
Another way to read individual request headers is to use `ngx.var.http_HEADER`, that is, nginx's standard `$http_HEADER` variables: Another way to read individual request headers is to use `ngx.var.http_HEADER`, that is, nginx's standard `$http_HEADER` variables.
<http://wiki.nginx.org/NginxHttpCoreModule#.24http_HEADER>
ngx.req.set_header ngx.req.set_header
------------------ ------------------
@ -1214,6 +1204,7 @@ is equivalent to
ngx.req.clear_header("X-Foo") ngx.req.clear_header("X-Foo")
ngx.req.clear_header ngx.req.clear_header
-------------------- --------------------
**syntax:** *ngx.req.clear_header(header_name)* **syntax:** *ngx.req.clear_header(header_name)*
@ -1228,13 +1219,16 @@ ngx.exec
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
Does an internal redirect to uri with args. Does an internal redirect to `uri` with `args`.
ngx.exec('/some-location'); ngx.exec('/some-location');
ngx.exec('/some-location', 'a=3&b=5&c=6'); ngx.exec('/some-location', 'a=3&b=5&c=6');
ngx.exec('/some-location?a=3&b=5', 'c=6'); ngx.exec('/some-location?a=3&b=5', 'c=6');
Named locations are also supported, but query strings are ignored. For example
Named locations are also supported, but query strings are ignored. For example,
location /foo { location /foo {
content_by_lua ' content_by_lua '
@ -1246,16 +1240,16 @@ Named locations are also supported, but query strings are ignored. For example
... ...
} }
Note that this is very different from `ngx.redirect` in that Note that this is very different from `ngx.redirect` in that
it's just an internal redirect and no new HTTP traffic is involved. it's just an internal redirect and no new HTTP traffic is involved.
This method never returns. This method never returns.
This method MUST be called before `ngx.send_headers()` or explicit response body This method *must* be called before `ngx.send_headers` or explicit response body
outputs by either `ngx.print` or `ngx.say`. outputs by either `ngx.print` or `ngx.say`.
This method is very much like the `echo_exec` This method is very much like the `echo_exec` directive in `NginxHttpEchoModule`.
directive in the ngx_echo module.
ngx.redirect ngx.redirect
------------ ------------
@ -1263,43 +1257,54 @@ ngx.redirect
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
Issue an HTTP 301 or 302 redirection to `uri`. Issue an `HTTP 301` or <code>302` redirection to <code>uri`.
The optional `status` parameter specifies whether The optional `status` parameter specifies whether
301 or 302 to be used. It's 302 (ngx.HTTP_MOVED_TEMPORARILY) by default. `301` or `302` to be used. It's `302` (`ngx.HTTP_MOVED_TEMPORARILY`) by default.
Here's a small example: Here's a small example:
return ngx.redirect("/foo") return ngx.redirect("/foo")
which is equivalent to which is equivalent to
return ngx.redirect("http://localhost:1984/foo", ngx.HTTP_MOVED_TEMPORARILY) return ngx.redirect("http://localhost:1984/foo", ngx.HTTP_MOVED_TEMPORARILY)
assuming the current server name is `localhost` and it's listening on the `1984` port. assuming the current server name is `localhost` and it's listening on the `1984` port.
This method MUST be called before `ngx.send_headers()` or explicit response body This method *must* be called before `ngx.send_headers` or explicit response body outputs by either `ngx.print` or `ngx.say`.
outputs by either `ngx.print` or `ngx.say`.
This method never returns. This method never returns.
This method is very much like the `rewrite` directive with the `redirect` modifier in the standard This method is very much like the `rewrite` directive with the `redirect` modifier in the standard
`ngx_rewrite` module, for example, this `nginx.conf` snippet `NginxHttpRewriteModule`, for example, this `nginx.conf` snippet
rewrite ^ /foo redirect; # nginx config rewrite ^ /foo redirect; # nginx config
is equivalent to the following Lua code is equivalent to the following Lua code
return ngx.redirect('/foo'); -- lua code return ngx.redirect('/foo'); -- lua code
while while
rewrite ^ /foo permanent; # nginx config rewrite ^ /foo permanent; # nginx config
is equivalent to is equivalent to
return ngx.redirect('/foo', ngx.HTTP_MOVED_PERMANENTLY) -- Lua code return ngx.redirect('/foo', ngx.HTTP_MOVED_PERMANENTLY) -- Lua code
ngx.send_headers ngx.send_headers
---------------- ----------------
**syntax:** *ngx.send_headers()* **syntax:** *ngx.send_headers()*
@ -1308,8 +1313,7 @@ ngx.send_headers
Explicitly send out the response headers. Explicitly send out the response headers.
Usually you don't have to send headers yourself. ngx_lua Usually you don't have to send headers yourself. `ngx_lua` will automatically send out headers right before you
will automatically send out headers right before you
output contents via `ngx.say` or `ngx.print`. output contents via `ngx.say` or `ngx.print`.
Headers will also be sent automatically when `content_by_lua` exits normally. Headers will also be sent automatically when `content_by_lua` exits normally.
@ -1320,12 +1324,13 @@ ngx.print
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
Emit args concatenated to the HTTP client (as response body). Emit arguments concatenated to the HTTP client (as response body). If response headers have not been sent yet, this function will first send the headers out, and then output the body data.
Lua nil value will result in outputing "nil", and Lua boolean values will emit "true" or "false". Lua `nil` value will result in outputing `"nil"`, and Lua boolean values will emit literal `"true"` or `"false"`, accordingly.
Also, nested arrays of strings are also allowed. The elements in the arrays will be sent one by one. For example Also, nested arrays of strings are also allowed. The elements in the arrays will be sent one by one. For example
local table = { local table = {
"hello, ", "hello, ",
{"world: ", true, " or ", false, {"world: ", true, " or ", false,
@ -1333,10 +1338,13 @@ Also, nested arrays of strings are also allowed. The elements in the arrays will
} }
ngx.print(table) ngx.print(table)
will yield the output will yield the output
hello, world: true or false: nil hello, world: true or false: nil
Non-array table arguments will cause a Lua exception to be thrown. Non-array table arguments will cause a Lua exception to be thrown.
ngx.say ngx.say
@ -1353,9 +1361,11 @@ ngx.log
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Log args concatenated to error.log with the given logging level. Log arguments concatenated to error.log with the given logging level.
Lua nil arguments are accepted and result in literal "nil", and Lua booleans result in "true" or "false". Lua `nil` arguments are accepted and result in literal `"nil"`, and Lua booleans result in literal `"true"` or `"false"` outputs.
The `log_level` argument can take constants like `ngx.ERR` and `ngx.WARN`. Check out `Nginx log level constants` for details.
ngx.flush ngx.flush
--------- ---------
@ -1363,7 +1373,7 @@ ngx.flush
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
Force flushing the response outputs. Force flushing the response outputs. This operation has no effect in HTTP 1.0 buffering output mode. See `HTTP 1.0 support`.
ngx.exit ngx.exit
-------- --------
@ -1371,14 +1381,13 @@ ngx.exit
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
When status >= 200 (ngx.HTTP_OK), it will interrupt the execution of the current Lua thread and returns When `status >= 200` (`ngx.HTTP_OK`), it will interrupt the execution of the current Lua thread and returns
status code to nginx. status code to nginx.
When status == 0 (ngx.OK), it will quits the current phase handler (or content handler if content_by_lua* directives are used). When `status == 0` (`ngx.OK`), it will quits the current phase handler (or content handler if `content_by_lua` directives are used).
The `status` argument can be `ngx.OK`, `ngx.ERROR`, `ngx.HTTP_NOT_FOUND`, The `status` argument can be `ngx.OK`, `ngx.ERROR`, `ngx.HTTP_NOT_FOUND`,
`ngx.HTTP_MOVED_TEMPORARILY`, `ngx.HTTP_MOVED_TEMPORARILY`, or other `HTTP status constants`.
or other HTTP status numbers.
ngx.eof ngx.eof
------- -------
@ -1402,7 +1411,7 @@ ngx.unescape_uri
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Unescape `str` as a escaped URI component. Unescape `str` as an escaped URI component.
ngx.encode_base64 ngx.encode_base64
----------------- -----------------
@ -1427,7 +1436,6 @@ ngx.today
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Returns today's date (in the format `yyyy-mm-dd`) from nginx cached time (no syscall involved unlike Lua's date library). Returns today's date (in the format `yyyy-mm-dd`) from nginx cached time (no syscall involved unlike Lua's date library).
.
This is the local time. This is the local time.
@ -1445,7 +1453,7 @@ ngx.localtime
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Returns the current timestamp (in the format `yyyy-mm-dd hh:mm:ss`) of the nginx cached time (no syscall involved unlike Lua's date library). Returns the current timestamp (in the format `yyyy-mm-dd hh:mm:ss`) of the nginx cached time (no syscall involved unlike Lua's [os.date](http://www.lua.org/manual/5.1/manual.html#pdf-os.date) function).
This is the local time. This is the local time.
@ -1455,7 +1463,7 @@ ngx.utctime
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Returns the current timestamp (in the format `yyyy-mm-dd hh:mm:ss`) of the nginx cached time (no syscall involved unlike Lua's date library). Returns the current timestamp (in the format `yyyy-mm-dd hh:mm:ss`) of the nginx cached time (no syscall involved unlike Lua's [os.date](http://www.lua.org/manual/5.1/manual.html#pdf-os.date) function).
This is the UTC time. This is the UTC time.
@ -1498,23 +1506,30 @@ ngx.is_subrequest
----------------- -----------------
**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua**
Returns true if the current request is an nginx subrequest, or false otherwise. Returns `true` if the current request is an nginx subrequest, or `false` otherwise.
ndk.set_var.DIRECTIVE ndk.set_var.DIRECTIVE
--------------------- ---------------------
**syntax:** *res = ndk.set_var.DIRECTIVE_NAME*
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua** **context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
This mechanism allows calling other nginx C modules' directives that are This mechanism allows calling other nginx C modules' directives that are implemented by [Nginx Devel Kit](https://github.com/simpl/ngx_devel_kit) (NDK)'s set_var submodule's `ndk_set_var_value`.
implemented by Nginx Devel Kit (NDK)'s set_var submodule's ndk_set_var_value.
For example, ngx_set_misc module's `set_escape_uri`, `set_quote_sql_str`, and etc. For example, `NginxHttpSetMiscModule`'s following directives can be invoked this way:
* `set_quote_sql_str`
* `set_quote_pgsql_str`
* `set_escape_uri`
* `set_unescape_uri`
For instance, For instance,
local res = ndk.set_var.set_escape_uri('a/b'); local res = ndk.set_var.set_escape_uri('a/b');
-- now res == 'a%2fb' -- now res == 'a%2fb'
This feature requires the ngx_devel_kit module.
This feature requires the [ngx_devel_kit](https://github.com/simpl/ngx_devel_kit) module.
HTTP 1.0 support HTTP 1.0 support
================ ================
@ -1540,6 +1555,7 @@ If you want to globally share user data among all the requests handled by the sa
Here's a complete small example: Here's a complete small example:
-- mydata.lua -- mydata.lua
module("mydata", package.seeall) module("mydata", package.seeall)
@ -1553,8 +1569,10 @@ Here's a complete small example:
return data[name] return data[name]
end end
and then accessing it from your nginx.conf: and then accessing it from your nginx.conf:
location /lua { location /lua {
content_lua_by_lua ' content_lua_by_lua '
local mydata = require("mydata") local mydata = require("mydata")
@ -1562,6 +1580,7 @@ and then accessing it from your nginx.conf:
'; ';
} }
Your `mydata` module in this example will only be loaded Your `mydata` module in this example will only be loaded
and run on the first request to the location `/lua`, and run on the first request to the location `/lua`,
and all those subsequent requests to the same nginx and all those subsequent requests to the same nginx
@ -1572,9 +1591,9 @@ process to enforce a reload.
This data sharing technique is essential for high-performance Lua apps built atop this module. It's common to cache reusable data globally. This data sharing technique is essential for high-performance Lua apps built atop this module. It's common to cache reusable data globally.
It's worth noting that this is *per-worker* sharing, not *per-server* sharing. That is, when you have multiple nginx worker processes under an nginx master, this data sharing cannot pass process boundry. If you indeed need server-wide data sharing, you can It's worth noting that this is *per-worker* sharing, not *per-server* sharing. That is, when you have multiple nginx worker processes under an nginx master, this data sharing cannot pass process boundary. If you indeed need server-wide data sharing, you can
1. Use only a single nginx worker and a single server. This is not recommended when you have a mulit-core CPU or multiple CPUs in a single machine. 1. Use only a single nginx worker and a single server. This is not recommended when you have a multi-core CPU or multiple CPUs in a single machine.
1. Use some true backend storage like `memcached`, `redis`, or an RDBMS like `mysql`. 1. Use some true backend storage like `memcached`, `redis`, or an RDBMS like `mysql`.
Performance Performance
@ -1716,12 +1735,9 @@ Future Plan
Known Issues Known Issues
============ ============
* Because the standard Lua 5.1 interpreter's VM is not fully resumable, the `ngx.location.capture` and `ngx.location.capture_multi` methods cannot be used within the context of a Lua `pcall()` or `xpcall()`. If you're heavy on Lua exception model based on Lua's `error()` and `pcall()`/`xpcall()`, use LuaJIT 2.0 instead because LuaJIT 2.0 supports fully resumable VM. * Because the standard Lua 5.1 interpreter's VM is not fully resumable, the `ngx.location.capture` and `ngx.location.capture_multi` methods cannot be used within the context of a Lua [pcall()](http://www.lua.org/manual/5.1/manual.html#pdf-pcall) or [xpcall()](http://www.lua.org/manual/5.1/manual.html#pdf-xpcall). If you're heavy on Lua exception model based on Lua's [error()](http://www.lua.org/manual/5.1/manual.html#pdf-error) and `pcall()`/`xpcall()`, use LuaJIT 2.0 instead because LuaJIT 2.0 supports fully resume-able VM.
* The `ngx.location.capture` and `ngx.location.capture_multi` Lua methods cannot capture * The `ngx.location.capture` and `ngx.location.capture_multi` Lua methods cannot capture locations configured by `NginxHttpEchoModule`'s `echo_location`, `echo_location_async`, `echo_subrequest`, or `echo_subrequest_async` directives. This won't be fixed in the future due to technical problems.
locations configured by ngx_echo module's `echo_location`, `echo_location_async`, `echo_subrequest`, or `echo_subrequest_async` directives. This won't be fixed in the future due to technical problems :)
* The `ngx.location.capture` and `ngx.location.capture_multi` Lua methods cannot capture locations with internal redirections for now. But this may get fixed in the future.
* **WATCH OUT: Globals WON'T persist between requests**, because of the one-coroutine-per-request isolation design. Especially watch yourself when using `require()` to import modules, and use this form: * **WATCH OUT: Globals WON'T persist between requests**, because of the one-coroutine-per-request isolation design. Especially watch yourself when using `require()` to import modules, and use this form:

Просмотреть файл

@ -180,13 +180,13 @@ This document describes lua-nginx-module [https://github.com/chaoslawful/lua-ngi
This module embeds the Lua interpreter or LuaJIT into the nginx core and integrates the powerful Lua threads (aka Lua coroutines) into the nginx event model This module embeds the Lua interpreter or LuaJIT into the nginx core and integrates the powerful Lua threads (aka Lua coroutines) into the nginx event model
by means of nginx subrequests. by means of nginx subrequests.
Unlike Apache's mod_lua and Lighttpd's mod_magnet, Lua code written atop this module can be 100% non-blocking on network traffic Unlike [http://httpd.apache.org/docs/2.3/mod/mod_lua.html Apache's mod_lua] and [http://redmine.lighttpd.net/wiki/1/Docs:ModMagnet Lighttpd's mod_magnet], Lua code written atop this module can be ''100% non-blocking'' on network traffic
as long as you use the [[#ngx.location.capture|ngx.location.capture]] or as long as you use the [[#ngx.location.capture|ngx.location.capture]] or
[[#ngx.location.capture_multi|ngx.location.capture_multi]] interfaces [[#ngx.location.capture_multi|ngx.location.capture_multi]] interfaces
to let the nginx core do all your to let the nginx core do all your
requests to mysql, postgresql, memcached, redis, requests to mysql, postgresql, memcached, redis,
upstream http web services, and etc etc etc (see upstream http web services, and etc etc etc (see
[http://github.com/chaoslawful/drizzle-nginx-module ngx_drizzle], [http://github.com/FRiCKLE/ngx_postgres/ ngx_postgres], [http://wiki.nginx.org/NginxHttpMemcModule ngx_memc], [http://github.com/agentzh/redis2-nginx-module ngx_redis2] and ngx_proxy modules for details). [http://github.com/chaoslawful/drizzle-nginx-module ngx_drizzle], [http://github.com/FRiCKLE/ngx_postgres/ ngx_postgres], [http://wiki.nginx.org/NginxHttpMemcModule ngx_memc], [http://github.com/agentzh/redis2-nginx-module ngx_redis2] and [[NginxHttpProxyModule]] modules for details).
The Lua interpreter instance is shared across all The Lua interpreter instance is shared across all
the requests in a single nginx worker process. the requests in a single nginx worker process.
@ -292,7 +292,7 @@ for example,
echo "sum = $sum, diff = $diff"; echo "sum = $sum, diff = $diff";
} }
</geshi> </geshi>
This directive requires the ngx_devel_kit module. This directive requires the [https://github.com/simpl/ngx_devel_kit ngx_devel_kit] module.
== set_by_lua_file == == set_by_lua_file ==
@ -308,7 +308,7 @@ once at the first request and cached. Nginx config must be reloaded if you
modified the file and expected to see updated behavior. You can disable the modified the file and expected to see updated behavior. You can disable the
Lua code cache by setting <code>lua_code_cache off;</code> in your nginx.conf. Lua code cache by setting <code>lua_code_cache off;</code> in your nginx.conf.
This directive requires the ngx_devel_kit module. This directive requires the [https://github.com/simpl/ngx_devel_kit ngx_devel_kit] module.
== content_by_lua == == content_by_lua ==
@ -439,17 +439,12 @@ calling [[#ngx.exit|ngx.exit]] with status >= 200 (<code>ngx.HTTP_OK</code>) and
'''phase:''' ''access tail'' '''phase:''' ''access tail''
Act as an access phase handler and execute user code specified by <code><lua-script-str></code> Act as an access phase handler and execute user code specified by <code><lua-script-str></code> for every request. The user code may call predefined APIs to generate response content.
for every request. The user code may call predefined APIs to generate response
content.
This hook uses exactly the same mechamism as [[#content_by_lua|content_by_lua]] This hook uses exactly the same mechanism as [[#content_by_lua|content_by_lua]] so all the nginx APIs defined there are also available here.
so all the nginx APIs defined there
are also available here. Note that this handler always runs ''after'' the standard [[NginxHttpAccessModule]]. So the following will work as expected:
Note that this handler always runs ''after'' the standard nginx
access module ( http://wiki.nginx.org/NginxHttpAccessModule ).
So the following will work as expected:
<geshi lang="nginx"> <geshi lang="nginx">
location / { location / {
deny 192.168.1.1; deny 192.168.1.1;
@ -465,12 +460,11 @@ So the following will work as expected:
# proxy_pass/fastcgi_pass/... # proxy_pass/fastcgi_pass/...
} }
</geshi> </geshi>
That is, if a client address appears in the blacklist, then
we don't have to bother sending a mysql query to do more
advanced authentication in [[#access_by_lua|access_by_lua]].
It's worth mentioning that, the <code>ngx_auth_request</code> module can be That is, if a client address appears in the blacklist, then we don't have to bother sending a MySQL query to do more advanced authentication in [[#access_by_lua|access_by_lua]].
approximately implemented by [[#access_by_lua|access_by_lua]]. For example,
It's worth mentioning that, the <code>ngx_auth_request</code> module can be approximately implemented by [[#access_by_lua|access_by_lua]]. For example,
<geshi lang="nginx"> <geshi lang="nginx">
location / { location / {
auth_request /auth; auth_request /auth;
@ -478,7 +472,9 @@ approximately implemented by [[#access_by_lua|access_by_lua]]. For example,
# proxy_pass/fastcgi_pass/postgres_pass/... # proxy_pass/fastcgi_pass/postgres_pass/...
} }
</geshi> </geshi>
can be implemented in terms of <code>ngx_lua</code> like this can be implemented in terms of <code>ngx_lua</code> like this
<geshi lang="nginx"> <geshi lang="nginx">
location / { location / {
access_by_lua ' access_by_lua '
@ -498,11 +494,10 @@ can be implemented in terms of <code>ngx_lua</code> like this
# proxy_pass/fastcgi_pass/postgres_pass/... # proxy_pass/fastcgi_pass/postgres_pass/...
} }
</geshi> </geshi>
Just as any other access-phase handlers, [[#access_by_lua|access_by_lua]] will NOT run in subrequests.
Note that calling <code>ngx.exit(ngx.OK)</code> just returning from the current [[#access_by_lua|access_by_lua]] handler, and the nginx request processing Just as any other access phase handlers, [[#access_by_lua|access_by_lua]] will ''not'' run in subrequests.
control flow will still continue to the content handler. To terminate the current request from within the current [[#access_by_lua|access_by_lua]] handler,
calling <code>ngx.exit(status)</code> where status >= 200 (ngx.HTTP_OK) and status < 300 (ngx.HTTP_SPECIAL_RESPONSE) for successful quits and <code>ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)</code> or its friends for failures. Note that calling <code>ngx.exit(ngx.OK)</code> just returning from the current [[#access_by_lua|access_by_lua]] handler, and the nginx request processing control flow will still continue to the content handler. To terminate the current request from within the current [[#access_by_lua|access_by_lua]] handler, calling <code>ngx.exit(status)</code> where status >= 200 (<code>ngx.HTTP_OK</code>) and status < 300 (<code>ngx.HTTP_SPECIAL_RESPONSE</code>) for successful quits and <code>ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)</code> or its friends for failures.
== content_by_lua_file == == content_by_lua_file ==
@ -519,10 +514,7 @@ Nginx variables can be used in <code><path-to-lua-script></code> string, in orde
greater flexibility in practice. But this feature must be used carefully, so is greater flexibility in practice. But this feature must be used carefully, so is
not recommend for beginners. not recommend for beginners.
When the Lua code cache is on (this is the default), the user code is loaded When the Lua code cache is on (this is the default), the user code is loaded once at the first request and cached. Nginx config must be reloaded if you modified the file and expected to see updated behavior. You can disable the Lua code cache by setting [[#lua_code_cache|lua_code_cache]] <code>off</code> in your <code>nginx.conf</code> file.
once at the first request and cached. Nginx config must be reloaded if you
modified the file and expected to see updated behavior. You can disable the
Lua code cache by setting <code>lua_code_cache off;</code> in your nginx.conf.
== rewrite_by_lua_file == == rewrite_by_lua_file ==
@ -542,7 +534,7 @@ not recommend for beginners.
When the Lua code cache is on (this is the default), the user code is loaded When the Lua code cache is on (this is the default), the user code is loaded
once at the first request and cached. Nginx config must be reloaded if you once at the first request and cached. Nginx config must be reloaded if you
modified the file and expected to see updated behavior. You can disable the modified the file and expected to see updated behavior. You can disable the
Lua code cache by setting <code>lua_code_cache off;</code> in your nginx.conf. Lua code cache by setting [[#lua_code_cache|lua_code_cache]] <code>off</code> in your <code>nginx.conf</code> file.
== access_by_lua_file == == access_by_lua_file ==
@ -562,7 +554,7 @@ not recommend for beginners.
When the Lua code cache is on (this is the default), the user code is loaded When the Lua code cache is on (this is the default), the user code is loaded
once at the first request and cached. Nginx config must be reloaded if you once at the first request and cached. Nginx config must be reloaded if you
modified the file and expected to see updated behavior. You can disable the modified the file and expected to see updated behavior. You can disable the
Lua code cache by setting <code>lua_code_cache off;</code> in your nginx.conf. Lua code cache by setting [[#lua_code_cache|lua_code_cache]] <code>off</code> in your <code>nginx.conf</code> file.
== lua_need_request_body == == lua_need_request_body ==
@ -574,15 +566,10 @@ Lua code cache by setting <code>lua_code_cache off;</code> in your nginx.conf.
'''phase:''' ''depends on usage'' '''phase:''' ''depends on usage''
Force reading request body data or not. The client request body won't be read, Force reading request body data or not. The client request body won't be read, so you have to explicitly force reading the body if you need its content.
so you have to explicitly force reading the body if you need its content.
If you want to read the request body data from the <code>$request_body</code> variable, make sure that If you want to read the request body data from the [[NginxHttpCoreModule#$request_body|$request_body]] variable, make sure that
your have configured <code>client_body_buffer_size</code> to have exactly the same value as <code>client_max_body_size</code>. See your have configured [[NginxHttpCoreModule#client_body_buffer_size|client_body_buffer_size]] to have exactly the same value as [[NginxHttpCoreModule#client_max_body_size|client_max_body_size]].
http://wiki.nginx.org/HttpCoreModule#client_body_buffer_size
for more details.
If the current location defines [[#rewrite_by_lua|rewrite_by_lua]] or [[#rewrite_by_lua_file|rewrite_by_lua_file]], If the current location defines [[#rewrite_by_lua|rewrite_by_lua]] or [[#rewrite_by_lua_file|rewrite_by_lua_file]],
then the request body will be read just before the [[#rewrite_by_lua|rewrite_by_lua]] or [[#rewrite_by_lua_file|rewrite_by_lua_file]] code is run (and also at the then the request body will be read just before the [[#rewrite_by_lua|rewrite_by_lua]] or [[#rewrite_by_lua_file|rewrite_by_lua_file]] code is run (and also at the
@ -595,14 +582,18 @@ The same applies to [[#access_by_lua|access_by_lua]] and [[#access_by_lua_file|a
= Nginx API for Lua = = Nginx API for Lua =
== Input arguments == == ngx.arg ==
'''syntax:''' ''val = ngx.arg[index]''
'''context:''' ''set_by_lua*'' '''context:''' ''set_by_lua*''
Index the input arguments to the set_by_lua* directives: Index the input arguments to the [[#set_by_lua|set_by_lua]] and [[#set_by_lua_file|set_by_lua_file]] directives:
<geshi lang="nginx">
<geshi lang="lua">
value = ngx.arg[n] value = ngx.arg[n]
</geshi> </geshi>
Here's an example Here's an example
<geshi lang="nginx"> <geshi lang="nginx">
location /foo { location /foo {
set $a 32; set $a 32;
@ -615,7 +606,8 @@ Here's an example
echo $sum; echo $sum;
} }
</geshi> </geshi>
that outputs 88, the sum of 32 and 56.
that outputs <code>88</code>, the sum of <code>32</code> and <code>56</code>.
== ngx.var.VARIABLE == == ngx.var.VARIABLE ==
'''syntax:''' ''ngx.var.VAR_NAME'' '''syntax:''' ''ngx.var.VAR_NAME''
@ -646,24 +638,28 @@ interface as well, by writing <code>ngx.var[1]</code>, <code>ngx.var[2]</code>,
== Core constants == == Core constants ==
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
<geshi lang="nginx"> <geshi lang="lua">
ngx.OK ngx.OK (0)
ngx.DONE ngx.ERROR (-1)
ngx.AGAIN ngx.AGAIN (-2)
ngx.ERROR ngx.DONE (-4)
</geshi> </geshi>
They take the same values of <code>NGX_OK</code>, <code>NGX_AGAIN</code>, <code>NGX_DONE</code>, <code>NGX_ERROR</code>, and etc. But now They take the same values of <code>NGX_OK</code>, <code>NGX_AGAIN</code>, <code>NGX_DONE</code>, <code>NGX_ERROR</code>, and etc. But now
only [[#ngx.exit|ngx.exit]] only take two of these values, i.e., <code>NGX_OK</code> and <code>NGX_ERROR</code>. only [[#ngx.exit|ngx.exit]] only take two of these values, i.e., <code>NGX_OK</code> and <code>NGX_ERROR</code>.
== HTTP method constants == == HTTP method constants ==
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
<geshi lang="nginx">
value = ngx.HTTP_GET <geshi lang="lua">
value = ngx.HTTP_HEAD ngx.HTTP_GET
value = ngx.HTTP_PUT ngx.HTTP_HEAD
value = ngx.HTTP_POST ngx.HTTP_PUT
value = ngx.HTTP_DELETE ngx.HTTP_POST
ngx.HTTP_DELETE
</geshi> </geshi>
These constants are usually used in [[#ngx.location.capture|ngx.location.catpure]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]] method calls.
== HTTP status constants == == HTTP status constants ==
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
<geshi lang="nginx"> <geshi lang="nginx">
@ -685,29 +681,32 @@ only [[#ngx.exit|ngx.exit]] only take two of these values, i.e., <code>NGX_OK</c
</geshi> </geshi>
== Nginx log level constants == == Nginx log level constants ==
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*''
<geshi lang="nginx"> <geshi lang="lua">
log_level = ngx.STDERR ngx.STDERR
log_level = ngx.EMERG ngx.EMERG
log_level = ngx.ALERT ngx.ALERT
log_level = ngx.CRIT ngx.CRIT
log_level = ngx.ERR ngx.ERR
log_level = ngx.WARN ngx.WARN
log_level = ngx.NOTICE ngx.NOTICE
log_level = ngx.INFO ngx.INFO
log_level = ngx.DEBUG ngx.DEBUG
</geshi> </geshi>
These constants are usually used by the [[#ngx.log|ngx.log]] method.
== print == == print ==
'''syntax:''' ''print(...)'' '''syntax:''' ''print(...)''
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*''
Emit args concatenated to <code>error.log</code>, with log level <code>ngx.NOTICE</code> and prefix <code>lua print: </code>. Emit args concatenated to nginx's <code>error.log</code> file, with log level <code>ngx.NOTICE</code> and prefix <code>lua print: </code>.
It's equivalent to It's equivalent to
<geshi lang="nginx"> <geshi lang="lua">
ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...) ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...)
</geshi> </geshi>
Lua nil arguments are accepted and result in literal "nil", and Lua booleans result in "true" or "false". Lua <code>nil</code> arguments are accepted and result in literal <code>"nil"</code>, and Lua booleans result in <code>"true"</code> or <code>"false"</code>.
== ngx.ctx == == ngx.ctx ==
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
@ -730,7 +729,7 @@ This table has a liftime identical to the current request (just like Nginx varia
} }
</geshi> </geshi>
Then <code>GET /test</code> will yield the output Then <code>GET /test</code> will yield the output
<geshi lang="nginx"> <geshi lang="bash">
foo = nil foo = nil
79 79
</geshi> </geshi>
@ -757,7 +756,7 @@ Also, every request has its own copy, include subrequests, for example:
} }
</geshi> </geshi>
Then <code>GET /main</code> will give the output Then <code>GET /main</code> will give the output
<geshi lang="nginx"> <geshi lang="bash">
main pre: 73 main pre: 73
sub pre: nil sub pre: nil
sub post: 32 sub post: 32
@ -781,7 +780,7 @@ Internal redirection will destroy the original request's <code>ngx.ctx</code> da
} }
</geshi> </geshi>
Then <code>GET /orig</code> will give you Then <code>GET /orig</code> will give you
<geshi lang="nginx"> <geshi lang="bash">
nil nil
</geshi> </geshi>
rather than the original <code>"hello"</code> value. rather than the original <code>"hello"</code> value.
@ -789,33 +788,26 @@ rather than the original <code>"hello"</code> value.
Arbitrary data values can be inserted into this "matic" table, including Lua closures and nested tables. You can also register your own meta methods with it. Arbitrary data values can be inserted into this "matic" table, including Lua closures and nested tables. You can also register your own meta methods with it.
Overriding <code>ngx.ctx</code> with a new Lua table is also supported, for example, Overriding <code>ngx.ctx</code> with a new Lua table is also supported, for example,
<geshi lang="nginx"> <geshi lang="lua">
ngx.ctx = { foo = 32, bar = 54 } ngx.ctx = { foo = 32, bar = 54 }
</geshi> </geshi>
== ngx.location.capture == == ngx.location.capture ==
'''syntax:''' ''res = ngx.location.capture(uri, options?)'' '''syntax:''' ''res = ngx.location.capture(uri, options?)''
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
Issue a synchronous but still non-blocking "nginx subrequest" using <code>uri</code>. Issue a synchronous but still non-blocking ''Nginx Subrequest'' using <code>uri</code>.
Nginx subrequests provide a powerful way to make Nginx subrequests provide a powerful way to make non-blocking internal requests to other locations configured with disk file directory or ''any'' other nginx C modules like <code>ngx_proxy</code>, <code>ngx_fastcgi</code>, <code>ngx_memc</code>,
non-blocking internal requests to other locations <code>ngx_postgres</code>, <code>ngx_drizzle</code>, and even <code>ngx_lua</code> itself and etc etc etc.
configured with disk file directory or ''any''
other nginx C modules like
<code>ngx_proxy</code>, <code>ngx_fastcgi</code>, <code>ngx_memc</code>,
<code>ngx_postgres</code>,
<code>ngx_drizzle</code>, and even <code>ngx_lua</code> itself and etc etc etc.
Also note that subrequests just mimic the HTTP Also note that subrequests just mimic the HTTP interface but there's ''no'' extra HTTP/TCP traffic ''nor'' IPC involved. Everything works internally, efficiently, on the C level.
interface but there's ''no''
extra HTTP/TCP traffic ''nor'' IPC involved. Everything
works internally, efficiently, on the C level.
Subrequests are completely different from HTTP 301/302 redirection (via [[#ngx.redirect|ngx.redirect]]) and internal redirection (via [[#ngx.exec|ngx.exec]]). Subrequests are completely different from HTTP 301/302 redirection (via [[#ngx.redirect|ngx.redirect]]) and internal redirection (via [[#ngx.exec|ngx.exec]]).
Here's a basic example: Here's a basic example:
<geshi lang="nginx"> <geshi lang="lua">
res = ngx.location.capture(uri) res = ngx.location.capture(uri)
</geshi> </geshi>
Returns a Lua table with three slots (<code>res.status</code>, <code>res.header</code>, and <code>res.body</code>). Returns a Lua table with three slots (<code>res.status</code>, <code>res.header</code>, and <code>res.body</code>).
@ -825,7 +817,7 @@ subrequest and it is a normal Lua table. For multi-value response headers,
the value is a Lua (array) table that holds all the values in the order that the value is a Lua (array) table that holds all the values in the order that
they appear. For instance, if the subrequest response headers contains the following they appear. For instance, if the subrequest response headers contains the following
lines: lines:
<geshi lang="nginx"> <geshi lang="bash">
Set-Cookie: a=3 Set-Cookie: a=3
Set-Cookie: foo=bar Set-Cookie: foo=bar
Set-Cookie: baz=blah Set-Cookie: baz=blah
@ -834,7 +826,7 @@ Then <code>res.header["Set-Cookie"]</code> will be evaluted to the table value
<code>{"a=3", "foo=bar", "baz=blah"}</code>. <code>{"a=3", "foo=bar", "baz=blah"}</code>.
URI query strings can be concatenated to URI itself, for instance, URI query strings can be concatenated to URI itself, for instance,
<geshi lang="nginx"> <geshi lang="lua">
res = ngx.location.capture('/foo/bar?a=3&b=4') res = ngx.location.capture('/foo/bar?a=3&b=4')
</geshi> </geshi>
Named locations like <code>@foo</code> are not allowed due to a limitation in Named locations like <code>@foo</code> are not allowed due to a limitation in
@ -846,7 +838,7 @@ argument, which support various options like
<code>method</code>, <code>body</code>, <code>args</code>, and <code>share_all_vars</code>. <code>method</code>, <code>body</code>, <code>args</code>, and <code>share_all_vars</code>.
Issuing a POST subrequest, for example, Issuing a POST subrequest, for example,
can be done as follows can be done as follows
<geshi lang="nginx"> <geshi lang="lua">
res = ngx.location.capture( res = ngx.location.capture(
'/foo/bar', '/foo/bar',
{ method = ngx.HTTP_POST, body = 'hello, world' } { method = ngx.HTTP_POST, body = 'hello, world' }
@ -864,21 +856,21 @@ and lead to confusing issues, use it with special
care. So, by default, the option is set to <code>false</code>. care. So, by default, the option is set to <code>false</code>.
The <code>args</code> option can specify extra url arguments, for instance, The <code>args</code> option can specify extra url arguments, for instance,
<geshi lang="nginx"> <geshi lang="lua">
ngx.location.capture('/foo?a=1', ngx.location.capture('/foo?a=1',
{ args = { b = 3, c = ':' } } { args = { b = 3, c = ':' } }
) )
</geshi> </geshi>
is equivalent to is equivalent to
<geshi lang="nginx"> <geshi lang="lua">
ngx.location.capture('/foo?a=1&b=3&c=%3a') ngx.location.capture('/foo?a=1&b=3&c=%3a')
</geshi> </geshi>
that is, this method will autmotically escape argument keys and values according to URI rules and that is, this method will automatically escape argument keys and values according to URI rules and
concatenating them together into a complete query string. Because it's all done in hand-written C, concatenating them together into a complete query string. Because it's all done in hand-written C,
it should be faster than your own Lua code. it should be faster than your own Lua code.
The <code>args</code> option can also take plain query string: The <code>args</code> option can also take plain query string:
<geshi lang="nginx"> <geshi lang="lua">
ngx.location.capture('/foo?a=1', ngx.location.capture('/foo?a=1',
{ args = 'b=3&c=%3a' } } { args = 'b=3&c=%3a' } }
) )
@ -890,9 +882,7 @@ request headers of the current request. This may have unexpected side-effects on
subrequest responses. For example, when you're using the standard <code>ngx_proxy</code> module to serve subrequest responses. For example, when you're using the standard <code>ngx_proxy</code> module to serve
your subrequests, then an "Accept-Encoding: gzip" header in your main request may result your subrequests, then an "Accept-Encoding: gzip" header in your main request may result
in gzip'd responses that your Lua code is not able to handle properly. So always set in gzip'd responses that your Lua code is not able to handle properly. So always set
<code>proxy_pass_request_headers off</code> in your subrequest location to ignore the original request headers. [[NginxHttpProxyModule#proxy_pass_request_headers|proxy_pass_request_headers]] <code>off</code> in your subrequest location to ignore the original request headers.
See http://wiki.nginx.org/NginxHttpProxyModule#proxy_pass_request_headers for more
details.
== ngx.location.capture_multi == == ngx.location.capture_multi ==
'''syntax:''' ''res1, res2, ... = ngx.location.capture_multi({ {uri, options?}, {uri, options?}, ... })'' '''syntax:''' ''res1, res2, ... = ngx.location.capture_multi({ {uri, options?}, {uri, options?}, ... })''
@ -902,7 +892,7 @@ details.
Just like [[#ngx.location.capture|ngx.location.capture]], but supports multiple subrequests running in parallel. Just like [[#ngx.location.capture|ngx.location.capture]], but supports multiple subrequests running in parallel.
This function issue several parallel subrequests specified by the input table, and returns their results in the same order. For example, This function issue several parallel subrequests specified by the input table, and returns their results in the same order. For example,
<geshi lang="nginx"> <geshi lang="lua">
res1, res2, res3 = ngx.location.capture_multi{ res1, res2, res3 = ngx.location.capture_multi{
{ "/foo", { args = "a=3&b=4" } }, { "/foo", { args = "a=3&b=4" } },
{ "/bar" }, { "/bar" },
@ -922,7 +912,7 @@ The total latency is the longest latency of the subrequests, instead of their su
When you don't know inadvance how many subrequests you want to issue, When you don't know inadvance how many subrequests you want to issue,
you can use Lua tables for both requests and responses. For instance, you can use Lua tables for both requests and responses. For instance,
<geshi lang="nginx"> <geshi lang="lua">
-- construct the requests table -- construct the requests table
local reqs = {} local reqs = {}
table.insert(reqs, { "/mysql" }) table.insert(reqs, { "/mysql" })
@ -940,67 +930,69 @@ you can use Lua tables for both requests and responses. For instance,
</geshi> </geshi>
The [[#ngx.location.capture|ngx.location.capture]] function is just a special form The [[#ngx.location.capture|ngx.location.capture]] function is just a special form
of this function. Logically speaking, the [[#ngx.location.capture|ngx.location.capture]] can be implemented like this of this function. Logically speaking, the [[#ngx.location.capture|ngx.location.capture]] can be implemented like this
<geshi lang="nginx"> <geshi lang="lua">
ngx.location.capture = ngx.location.capture =
function (uri, args) function (uri, args)
return ngx.location.capture_multi({ {uri, args} }) return ngx.location.capture_multi({ {uri, args} })
end end
</geshi> </geshi>
== ngx.status == == ngx.status ==
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*''
Read and write the current request's response status. This should be called Read and write the current request's response status. This should be called
before sending out the response headers. before sending out the response headers.
<geshi lang="nginx"> <geshi lang="lua">
ngx.status = ngx.HTTP_CREATED ngx.status = ngx.HTTP_CREATED
status = ngx.status status = ngx.status
</geshi> </geshi>
== ngx.header.HEADER == == ngx.header.HEADER ==
'''syntax:''' ''ngx.header.HEADER = VALUE'' '''syntax:''' ''ngx.header.HEADER = VALUE''
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
Set/add/clear the current request's response headers. Underscores (_) in the header names will be replaced by dashes (-) and the header names will be matched case-insentively. Set/add/clear the current request's response headers. Underscores (<code>_</code>) in the header names will be replaced by dashes (<code>-</code>) and the header names will be matched case-insentively.
<geshi lang="nginx"> <geshi lang="lua">
-- equivalent to ngx.header["Content-Type"] = 'text/plain' -- equivalent to ngx.header["Content-Type"] = 'text/plain'
ngx.header.content_type = 'text/plain'; ngx.header.content_type = 'text/plain';
ngx.header["X-My-Header"] = 'blah blah'; ngx.header["X-My-Header"] = 'blah blah';
</geshi> </geshi>
Multi-value headers can be set this way: Multi-value headers can be set this way:
<geshi lang="nginx"> <geshi lang="lua">
ngx.header['Set-Cookie'] = {'a=32; path=/', 'b=4; path=/'} ngx.header['Set-Cookie'] = {'a=32; path=/', 'b=4; path=/'}
</geshi> </geshi>
will yield will yield
<geshi lang="nginx"> <geshi lang="bash">
Set-Cookie: a=32; path=/ Set-Cookie: a=32; path=/
Set-Cookie: b=4; path=/ Set-Cookie: b=4; path=/
</geshi> </geshi>
in the response headers. Only array-like tables are accepted. in the response headers. Only array-like tables are accepted.
Note that, for those standard headers that only accepts a single value, like Content-Type, only the last element Note that, for those standard headers that only accepts a single value, like <code>Content-Type</code>, only the last element
in the (array) table will take effect. So in the (array) table will take effect. So
<geshi lang="nginx"> <geshi lang="lua">
ngx.header.content_type = {'a', 'b'} ngx.header.content_type = {'a', 'b'}
</geshi> </geshi>
is equivalent to is equivalent to
<geshi lang="nginx"> <geshi lang="lua">
ngx.header.content_type = 'b' ngx.header.content_type = 'b'
</geshi> </geshi>
Setting a slot to nil effectively removes it from the response headers: Setting a slot to <code>nil</code> effectively removes it from the response headers:
<geshi lang="nginx"> <geshi lang="lua">
ngx.header["X-My-Header"] = nil; ngx.header["X-My-Header"] = nil;
</geshi> </geshi>
same does assigning an empty table: same does assigning an empty table:
<geshi lang="nginx"> <geshi lang="lua">
ngx.header["X-My-Header"] = {}; ngx.header["X-My-Header"] = {};
</geshi> </geshi>
<code>ngx.header</code> is not a normal Lua table so you cannot <code>ngx.header</code> is not a normal Lua table so you cannot
iterate through it. iterate through it.
For reading request headers, use the <code>ngx.req.get_headers()</code> function instead. For reading request headers, use the [[#ngx.req.get_headers|ngx.req.get_headers]] function instead.
Reading values from ngx.header.HEADER is not implemented yet, Reading values from <code>ngx.header.HEADER</code> is not implemented yet,
and usually you shouldn't need it. and usually you shouldn't need it.
== ngx.req.get_uri_args == == ngx.req.get_uri_args ==
@ -1026,35 +1018,35 @@ Here's an example,
} }
</geshi> </geshi>
Then <code>GET /test?foo=bar&bar=baz&bar=blah</code> will yield the response body Then <code>GET /test?foo=bar&bar=baz&bar=blah</code> will yield the response body
<geshi lang="nginx"> <geshi lang="bash">
foo: bar foo: bar
bar: baz, blah bar: baz, blah
</geshi> </geshi>
Multiple occurrences of an argument key will result in a table value holding all of the values for that key in order. Multiple occurrences of an argument key will result in a table value holding all of the values for that key in order.
Keys and values will be automatically unescaped according to URI escaping rules. For example, in the above settings, <code>GET /test?a%20b=1%61+2</code> will yield the output Keys and values will be automatically unescaped according to URI escaping rules. For example, in the above settings, <code>GET /test?a%20b=1%61+2</code> will yield the output
<geshi lang="nginx"> <geshi lang="bash">
a b: 1a 2 a b: 1a 2
</geshi> </geshi>
Arguments without the <code>=<value></code> parts are treated as boolean arguments. For example, <code>GET /test?foo&bar</code> will yield the outputs Arguments without the <code>=<value></code> parts are treated as boolean arguments. For example, <code>GET /test?foo&bar</code> will yield the outputs
<geshi lang="nginx"> <geshi lang="bash">
foo: true foo: true
bar: true bar: true
</geshi> </geshi>
That is, they will take Lua boolean values <code>true</code>. However, they're different from arguments taking empty string values. For example, <code>GET /test?foo=&bar=</code> will give something like That is, they will take Lua boolean values <code>true</code>. However, they're different from arguments taking empty string values. For example, <code>GET /test?foo=&bar=</code> will give something like
<geshi lang="nginx"> <geshi lang="bash">
foo: foo:
bar: bar:
</geshi> </geshi>
Empty key arguments are discarded, for instance, <code>GET /test?=hello&=world</code> will yield empty outputs. Empty key arguments are discarded, for instance, <code>GET /test?=hello&=world</code> will yield empty outputs.
Updating query arguments via the nginx variable <code>$args</code> (or <code>ngx.var.args</code> in Lua) at runtime are also supported: Updating query arguments via the nginx variable <code>$args</code> (or <code>ngx.var.args</code> in Lua) at runtime are also supported:
<geshi lang="nginx"> <geshi lang="lua">
ngx.var.args = "a=3&b=42" ngx.var.args = "a=3&b=42"
local args = ngx.req.get_uri_args() local args = ngx.req.get_uri_args()
</geshi> </geshi>
Here the <code>args</code> table will always look like Here the <code>args</code> table will always look like
<geshi lang="nginx"> <geshi lang="lua">
{a = 3, b = 42} {a = 3, b = 42}
</geshi> </geshi>
regardless of the actual request query string. regardless of the actual request query string.
@ -1083,33 +1075,33 @@ Here's an example,
} }
</geshi> </geshi>
Then Then
<geshi lang="nginx"> <geshi lang="bash">
# Post request with the body 'foo=bar&bar=baz&bar=blah' # Post request with the body 'foo=bar&bar=baz&bar=blah'
$ curl --data 'foo=bar&bar=baz&bar=blah' localhost/test $ curl --data 'foo=bar&bar=baz&bar=blah' localhost/test
</geshi> </geshi>
will yield the response body like will yield the response body like
<geshi lang="nginx"> <geshi lang="bash">
foo: bar foo: bar
bar: baz, blah bar: baz, blah
</geshi> </geshi>
Multiple occurrences of an argument key will result in a table value holding all of the values for that key in order. Multiple occurrences of an argument key will result in a table value holding all of the values for that key in order.
Keys and values will be automatically unescaped according to URI escaping rules. For example, in the above settings, Keys and values will be automatically unescaped according to URI escaping rules. For example, in the above settings,
<geshi lang="nginx"> <geshi lang="bash">
# POST request with body 'a%20b=1%61+2' # POST request with body 'a%20b=1%61+2'
$ curl -d 'a%20b=1%61+2' localhost/test $ curl -d 'a%20b=1%61+2' localhost/test
</geshi> </geshi>
will yield the output will yield the output
<geshi lang="nginx"> <geshi lang="bash">
a b: 1a 2 a b: 1a 2
</geshi> </geshi>
Arguments without the <code>=<value></code> parts are treated as boolean arguments. For example, <code>GET /test?foo&bar</code> will yield the outputs Arguments without the <code>=<value></code> parts are treated as boolean arguments. For example, <code>GET /test?foo&bar</code> will yield the outputs
<geshi lang="nginx"> <geshi lang="bash">
foo: true foo: true
bar: true bar: true
</geshi> </geshi>
That is, they will take Lua boolean values <code>true</code>. However, they're different from arguments taking empty string values. For example, <code>POST /test</code> with request body <code>foo=&bar=</code> will give something like That is, they will take Lua boolean values <code>true</code>. However, they're different from arguments taking empty string values. For example, <code>POST /test</code> with request body <code>foo=&bar=</code> will give something like
<geshi lang="nginx"> <geshi lang="bash">
foo: foo:
bar: bar:
</geshi> </geshi>
@ -1123,29 +1115,27 @@ Empty key arguments are discarded, for instance, <code>POST /test</code> with bo
Returns a Lua table holds all of the current request's request headers. Returns a Lua table holds all of the current request's request headers.
Here's an example, Here's an example,
<geshi lang="nginx"> <geshi lang="lua">
local h = ngx.req.get_headers() local h = ngx.req.get_headers()
for k, v in pairs(h) do for k, v in pairs(h) do
... ...
end end
</geshi> </geshi>
To read an individual header: To read an individual header:
<geshi lang="nginx"> <geshi lang="lua">
ngx.say("Host: ", ngx.req.get_headers()["Host"]) ngx.say("Host: ", ngx.req.get_headers()["Host"])
</geshi> </geshi>
For multiple instances of request headers like For multiple instances of request headers like
<geshi lang="nginx"> <geshi lang="bash">
Foo: foo Foo: foo
Foo: bar Foo: bar
Foo: baz Foo: baz
</geshi> </geshi>
the value of <code>ngx.req.get_headers()["Foo"]</code> will be a Lua (array) table like this: the value of <code>ngx.req.get_headers()["Foo"]</code> will be a Lua (array) table like this:
<geshi lang="nginx"> <geshi lang="lua">
{"foo", "bar", "baz"} {"foo", "bar", "baz"}
</geshi> </geshi>
Another way to read individual request headers is to use <code>ngx.var.http_HEADER</code>, that is, nginx's standard <code>$http_HEADER</code> variables: Another way to read individual request headers is to use <code>ngx.var.http_HEADER</code>, that is, nginx's standard [[NginxHttpCoreModule#$http_HEADER|$http_HEADER]] variables.
http://wiki.nginx.org/NginxHttpCoreModule#.24http_HEADER
== ngx.req.set_header == == ngx.req.set_header ==
'''syntax:''' ''ngx.req.set_header(header_name, header_value)'' '''syntax:''' ''ngx.req.set_header(header_name, header_value)''
@ -1156,29 +1146,30 @@ Set the current request's request header named <code>header_name</code> to value
None of the current request's subrequests will be affected. None of the current request's subrequests will be affected.
Here's an example of setting the <code>Content-Length</code> header: Here's an example of setting the <code>Content-Length</code> header:
<geshi lang="nginx"> <geshi lang="lua">
ngx.req.set_header("Content-Type", "text/css") ngx.req.set_header("Content-Type", "text/css")
</geshi> </geshi>
The <code>header_value</code> can take an array list of values, The <code>header_value</code> can take an array list of values,
for example, for example,
<geshi lang="nginx"> <geshi lang="lua">
ngx.req.set_header("Foo", {"a", "abc"}) ngx.req.set_header("Foo", {"a", "abc"})
</geshi> </geshi>
will produce two new request headers: will produce two new request headers:
<geshi lang="nginx"> <geshi lang="bash">
Foo: a Foo: a
Foo: abc Foo: abc
</geshi> </geshi>
and old <code>Foo</code> headers will be overridden if there's any. and old <code>Foo</code> headers will be overridden if there's any.
When the <code>header_value</code> argument is <code>nil</code>, the request header will be removed. So When the <code>header_value</code> argument is <code>nil</code>, the request header will be removed. So
<geshi lang="nginx"> <geshi lang="lua">
ngx.req.set_header("X-Foo", nil) ngx.req.set_header("X-Foo", nil)
</geshi> </geshi>
is equivalent to is equivalent to
<geshi lang="nginx"> <geshi lang="lua">
ngx.req.clear_header("X-Foo") ngx.req.clear_header("X-Foo")
</geshi> </geshi>
== ngx.req.clear_header == == ngx.req.clear_header ==
'''syntax:''' ''ngx.req.clear_header(header_name)'' '''syntax:''' ''ngx.req.clear_header(header_name)''
@ -1191,13 +1182,16 @@ Clear the current request's request header named <code>header_name</code>. None
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
Does an internal redirect to uri with args. Does an internal redirect to <code>uri</code> with <code>args</code>.
<geshi lang="nginx">
<geshi lang="lua">
ngx.exec('/some-location'); ngx.exec('/some-location');
ngx.exec('/some-location', 'a=3&b=5&c=6'); ngx.exec('/some-location', 'a=3&b=5&c=6');
ngx.exec('/some-location?a=3&b=5', 'c=6'); ngx.exec('/some-location?a=3&b=5', 'c=6');
</geshi> </geshi>
Named locations are also supported, but query strings are ignored. For example
Named locations are also supported, but query strings are ignored. For example,
<geshi lang="nginx"> <geshi lang="nginx">
location /foo { location /foo {
content_by_lua ' content_by_lua '
@ -1209,59 +1203,70 @@ Named locations are also supported, but query strings are ignored. For example
... ...
} }
</geshi> </geshi>
Note that this is very different from [[#ngx.redirect|ngx.redirect]] in that Note that this is very different from [[#ngx.redirect|ngx.redirect]] in that
it's just an internal redirect and no new HTTP traffic is involved. it's just an internal redirect and no new HTTP traffic is involved.
This method never returns. This method never returns.
This method MUST be called before <code>ngx.send_headers()</code> or explicit response body This method ''must'' be called before [[#ngx.send_headers|ngx.send_headers]] or explicit response body
outputs by either [[#ngx.print|ngx.print]] or [[#ngx.say|ngx.say]]. outputs by either [[#ngx.print|ngx.print]] or [[#ngx.say|ngx.say]].
This method is very much like the <code>echo_exec</code> This method is very much like the [[NginxHttpEchoModule#echo_exec|echo_exec]] directive in [[NginxHttpEchoModule]].
directive in the ngx_echo module.
== ngx.redirect == == ngx.redirect ==
'''syntax:''' ''ngx.redirect(uri, status?)'' '''syntax:''' ''ngx.redirect(uri, status?)''
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
Issue an HTTP 301 or 302 redirection to <code>uri</code>. Issue an <code>HTTP 301<code> or <code>302</code> redirection to <code>uri</code>.
The optional <code>status</code> parameter specifies whether The optional <code>status</code> parameter specifies whether
301 or 302 to be used. It's 302 (ngx.HTTP_MOVED_TEMPORARILY) by default. <code>301</code> or <code>302</code> to be used. It's <code>302</code> (<code>ngx.HTTP_MOVED_TEMPORARILY</code>) by default.
Here's a small example: Here's a small example:
<geshi lang="nginx">
<geshi lang="lua">
return ngx.redirect("/foo") return ngx.redirect("/foo")
</geshi> </geshi>
which is equivalent to which is equivalent to
<geshi lang="nginx">
<geshi lang="lua">
return ngx.redirect("http://localhost:1984/foo", ngx.HTTP_MOVED_TEMPORARILY) return ngx.redirect("http://localhost:1984/foo", ngx.HTTP_MOVED_TEMPORARILY)
</geshi> </geshi>
assuming the current server name is <code>localhost</code> and it's listening on the <code>1984</code> port. assuming the current server name is <code>localhost</code> and it's listening on the <code>1984</code> port.
This method MUST be called before <code>ngx.send_headers()</code> or explicit response body This method ''must'' be called before [[#ngx.send_headers|ngx.send_headers]] or explicit response body outputs by either [[#ngx.print|ngx.print]] or [[#ngx.say|ngx.say]].
outputs by either [[#ngx.print|ngx.print]] or [[#ngx.say|ngx.say]].
This method never returns. This method never returns.
This method is very much like the <code>rewrite</code> directive with the <code>redirect</code> modifier in the standard This method is very much like the [[NginxHttpRewriteModule#rewrite|rewrite]] directive with the <code>redirect</code> modifier in the standard
<code>ngx_rewrite</code> module, for example, this <code>nginx.conf</code> snippet [[NginxHttpRewriteModule]], for example, this <code>nginx.conf</code> snippet
<geshi lang="nginx"> <geshi lang="nginx">
rewrite ^ /foo redirect; # nginx config rewrite ^ /foo redirect; # nginx config
</geshi> </geshi>
is equivalent to the following Lua code is equivalent to the following Lua code
<geshi lang="nginx">
<geshi lang="lua">
return ngx.redirect('/foo'); -- lua code return ngx.redirect('/foo'); -- lua code
</geshi> </geshi>
while while
<geshi lang="nginx"> <geshi lang="nginx">
rewrite ^ /foo permanent; # nginx config rewrite ^ /foo permanent; # nginx config
</geshi> </geshi>
is equivalent to is equivalent to
<geshi lang="nginx">
<geshi lang="lua">
return ngx.redirect('/foo', ngx.HTTP_MOVED_PERMANENTLY) -- Lua code return ngx.redirect('/foo', ngx.HTTP_MOVED_PERMANENTLY) -- Lua code
</geshi> </geshi>
== ngx.send_headers == == ngx.send_headers ==
'''syntax:''' ''ngx.send_headers()'' '''syntax:''' ''ngx.send_headers()''
@ -1269,8 +1274,7 @@ is equivalent to
Explicitly send out the response headers. Explicitly send out the response headers.
Usually you don't have to send headers yourself. ngx_lua Usually you don't have to send headers yourself. <code>ngx_lua</code> will automatically send out headers right before you
will automatically send out headers right before you
output contents via [[#ngx.say|ngx.say]] or [[#ngx.print|ngx.print]]. output contents via [[#ngx.say|ngx.say]] or [[#ngx.print|ngx.print]].
Headers will also be sent automatically when [[#content_by_lua|content_by_lua]] exits normally. Headers will also be sent automatically when [[#content_by_lua|content_by_lua]] exits normally.
@ -1280,12 +1284,13 @@ Headers will also be sent automatically when [[#content_by_lua|content_by_lua]]
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
Emit args concatenated to the HTTP client (as response body). Emit arguments concatenated to the HTTP client (as response body). If response headers have not been sent yet, this function will first send the headers out, and then output the body data.
Lua nil value will result in outputing "nil", and Lua boolean values will emit "true" or "false". Lua <code>nil</code> value will result in outputing <code>"nil"</code>, and Lua boolean values will emit literal <code>"true"</code> or <code>"false"</code>, accordingly.
Also, nested arrays of strings are also allowed. The elements in the arrays will be sent one by one. For example Also, nested arrays of strings are also allowed. The elements in the arrays will be sent one by one. For example
<geshi lang="nginx">
<geshi lang="lua">
local table = { local table = {
"hello, ", "hello, ",
{"world: ", true, " or ", false, {"world: ", true, " or ", false,
@ -1293,10 +1298,13 @@ Also, nested arrays of strings are also allowed. The elements in the arrays will
} }
ngx.print(table) ngx.print(table)
</geshi> </geshi>
will yield the output will yield the output
<geshi lang="nginx">
<geshi lang="bash">
hello, world: true or false: nil hello, world: true or false: nil
</geshi> </geshi>
Non-array table arguments will cause a Lua exception to be thrown. Non-array table arguments will cause a Lua exception to be thrown.
== ngx.say == == ngx.say ==
@ -1311,30 +1319,31 @@ Just as [[#ngx.print|ngx.print]] but also emit a trailing newline.
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*''
Log args concatenated to error.log with the given logging level. Log arguments concatenated to error.log with the given logging level.
Lua nil arguments are accepted and result in literal "nil", and Lua booleans result in "true" or "false". Lua <code>nil</code> arguments are accepted and result in literal <code>"nil"</code>, and Lua booleans result in literal <code>"true"</code> or <code>"false"</code> outputs.
The <code>log_level</code> argument can take constants like <code>ngx.ERR</code> and <code>ngx.WARN</code>. Check out [[#Nginx log level constants|Nginx log level constants]] for details.
== ngx.flush == == ngx.flush ==
'''syntax:''' ''ngx.flush()'' '''syntax:''' ''ngx.flush()''
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
Force flushing the response outputs. Force flushing the response outputs. This operation has no effect in HTTP 1.0 buffering output mode. See [[#HTTP 1.0 support|HTTP 1.0 support]].
== ngx.exit == == ngx.exit ==
'''syntax:''' ''ngx.exit(status)'' '''syntax:''' ''ngx.exit(status)''
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
When status >= 200 (ngx.HTTP_OK), it will interrupt the execution of the current Lua thread and returns When <code>status >= 200</code> (<code>ngx.HTTP_OK</code>), it will interrupt the execution of the current Lua thread and returns
status code to nginx. status code to nginx.
When status == 0 (ngx.OK), it will quits the current phase handler (or content handler if content_by_lua* directives are used). When <code>status == 0</code> (<code>ngx.OK</code>), it will quits the current phase handler (or content handler if [[#content_by_lua|content_by_lua]] directives are used).
The <code>status</code> argument can be <code>ngx.OK</code>, <code>ngx.ERROR</code>, <code>ngx.HTTP_NOT_FOUND</code>, The <code>status</code> argument can be <code>ngx.OK</code>, <code>ngx.ERROR</code>, <code>ngx.HTTP_NOT_FOUND</code>,
<code>ngx.HTTP_MOVED_TEMPORARILY</code>, <code>ngx.HTTP_MOVED_TEMPORARILY</code>, or other [[#HTTP status constants|HTTP status constants]].
or other HTTP status numbers.
== ngx.eof == == ngx.eof ==
'''syntax:''' ''ngx.eof()'' '''syntax:''' ''ngx.eof()''
@ -1355,7 +1364,7 @@ Escape <code>str</code> as a URI component.
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*''
Unescape <code>str</code> as a escaped URI component. Unescape <code>str</code> as an escaped URI component.
== ngx.encode_base64 == == ngx.encode_base64 ==
'''syntax:''' ''newstr = ngx.encode_base64(str)'' '''syntax:''' ''newstr = ngx.encode_base64(str)''
@ -1377,7 +1386,6 @@ Decode <code>str</code> as a base64 digest to the raw form.
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*''
Returns today's date (in the format <code>yyyy-mm-dd</code>) from nginx cached time (no syscall involved unlike Lua's date library). Returns today's date (in the format <code>yyyy-mm-dd</code>) from nginx cached time (no syscall involved unlike Lua's date library).
.
This is the local time. This is the local time.
@ -1393,7 +1401,7 @@ Returns the elapsed seconds from the epoch for the current timestamp from the ng
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*''
Returns the current timestamp (in the format <code>yyyy-mm-dd hh:mm:ss</code>) of the nginx cached time (no syscall involved unlike Lua's date library). Returns the current timestamp (in the format <code>yyyy-mm-dd hh:mm:ss</code>) of the nginx cached time (no syscall involved unlike Lua's [http://www.lua.org/manual/5.1/manual.html#pdf-os.date os.date] function).
This is the local time. This is the local time.
@ -1402,7 +1410,7 @@ This is the local time.
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*''
Returns the current timestamp (in the format <code>yyyy-mm-dd hh:mm:ss</code>) of the nginx cached time (no syscall involved unlike Lua's date library). Returns the current timestamp (in the format <code>yyyy-mm-dd hh:mm:ss</code>) of the nginx cached time (no syscall involved unlike Lua's [http://www.lua.org/manual/5.1/manual.html#pdf-os.date os.date] function).
This is the UTC time. This is the UTC time.
@ -1441,22 +1449,29 @@ Parse the http time string (as returned by [[#ngx.http_time|ngx.http_time]]) int
== ngx.is_subrequest == == ngx.is_subrequest ==
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*''
Returns true if the current request is an nginx subrequest, or false otherwise. Returns <code>true</code> if the current request is an nginx subrequest, or <code>false</code> otherwise.
== ndk.set_var.DIRECTIVE == == ndk.set_var.DIRECTIVE ==
'''syntax:''' ''res = ndk.set_var.DIRECTIVE_NAME''
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*'' '''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
This mechanism allows calling other nginx C modules' directives that are This mechanism allows calling other nginx C modules' directives that are implemented by [https://github.com/simpl/ngx_devel_kit Nginx Devel Kit] (NDK)'s set_var submodule's <code>ndk_set_var_value</code>.
implemented by Nginx Devel Kit (NDK)'s set_var submodule's ndk_set_var_value.
For example, ngx_set_misc module's <code>set_escape_uri</code>, <code>set_quote_sql_str</code>, and etc. For example, [[NginxHttpSetMiscModule]]'s following directives can be invoked this way:
* [[NginxHttpSetMiscModule#set_quote_sql_str|set_quote_sql_str]]
* [[NginxHttpSetMiscModule#set_quote_pgsql_str|set_quote_pgsql_str]]
* [[NginxHttpSetMiscModule#set_escape_uri|set_escape_uri]]
* [[NginxHttpSetMiscModule#set_unescape_uri|set_unescape_uri]]
For instance, For instance,
<geshi lang="nginx">
<geshi lang="lua">
local res = ndk.set_var.set_escape_uri('a/b'); local res = ndk.set_var.set_escape_uri('a/b');
-- now res == 'a%2fb' -- now res == 'a%2fb'
</geshi> </geshi>
This feature requires the ngx_devel_kit module.
This feature requires the [https://github.com/simpl/ngx_devel_kit ngx_devel_kit] module.
= HTTP 1.0 support = = HTTP 1.0 support =
@ -1479,7 +1494,8 @@ the <code>-0</code> option.
If you want to globally share user data among all the requests handled by the same nginx worker process, you can encapsulate your shared data into a Lua module, require the module in your code, and manipulate shared data through it. It works because required Lua modules are loaded only once, and all coroutines will share the same copy of the module. If you want to globally share user data among all the requests handled by the same nginx worker process, you can encapsulate your shared data into a Lua module, require the module in your code, and manipulate shared data through it. It works because required Lua modules are loaded only once, and all coroutines will share the same copy of the module.
Here's a complete small example: Here's a complete small example:
<geshi lang="nginx">
<geshi lang="lua">
-- mydata.lua -- mydata.lua
module("mydata", package.seeall) module("mydata", package.seeall)
@ -1493,7 +1509,9 @@ Here's a complete small example:
return data[name] return data[name]
end end
</geshi> </geshi>
and then accessing it from your nginx.conf: and then accessing it from your nginx.conf:
<geshi lang="nginx"> <geshi lang="nginx">
location /lua { location /lua {
content_lua_by_lua ' content_lua_by_lua '
@ -1502,6 +1520,7 @@ and then accessing it from your nginx.conf:
'; ';
} }
</geshi> </geshi>
Your <code>mydata</code> module in this example will only be loaded Your <code>mydata</code> module in this example will only be loaded
and run on the first request to the location <code>/lua</code>, and run on the first request to the location <code>/lua</code>,
and all those subsequent requests to the same nginx and all those subsequent requests to the same nginx
@ -1512,9 +1531,9 @@ process to enforce a reload.
This data sharing technique is essential for high-performance Lua apps built atop this module. It's common to cache reusable data globally. This data sharing technique is essential for high-performance Lua apps built atop this module. It's common to cache reusable data globally.
It's worth noting that this is ''per-worker'' sharing, not ''per-server'' sharing. That is, when you have multiple nginx worker processes under an nginx master, this data sharing cannot pass process boundry. If you indeed need server-wide data sharing, you can It's worth noting that this is ''per-worker'' sharing, not ''per-server'' sharing. That is, when you have multiple nginx worker processes under an nginx master, this data sharing cannot pass process boundary. If you indeed need server-wide data sharing, you can
# Use only a single nginx worker and a single server. This is not recommended when you have a mulit-core CPU or multiple CPUs in a single machine. # Use only a single nginx worker and a single server. This is not recommended when you have a multi-core CPU or multiple CPUs in a single machine.
# Use some true backend storage like <code>memcached</code>, <code>redis</code>, or an RDBMS like <code>mysql</code>. # Use some true backend storage like <code>memcached</code>, <code>redis</code>, or an RDBMS like <code>mysql</code>.
= Performance = = Performance =
@ -1542,7 +1561,7 @@ Alternatively, you can compile this module with nginx core's source by hand:
# Download the latest version of the release tarball of the ngx_devel_kit (NDK) module from lua-nginx-module [http://github.com/simpl/ngx_devel_kit/downloads file list]. # Download the latest version of the release tarball of the ngx_devel_kit (NDK) module from lua-nginx-module [http://github.com/simpl/ngx_devel_kit/downloads file list].
# Download the latest version of the release tarball of this module from lua-nginx-module [http://github.com/chaoslawful/lua-nginx-module/downloads file list]. # Download the latest version of the release tarball of this module from lua-nginx-module [http://github.com/chaoslawful/lua-nginx-module/downloads file list].
# Grab the nginx source code from [http://nginx.org/ nginx.org], for example, the version 1.0.5 (see nginx compatibility), and then build the source with this module: # Grab the nginx source code from [http://nginx.org/ nginx.org], for example, the version 1.0.5 (see nginx compatibility), and then build the source with this module:
<geshi lang="nginx"> <geshi lang="bash">
$ wget 'http://sysoev.ru/nginx/nginx-1.0.5.tar.gz' $ wget 'http://sysoev.ru/nginx/nginx-1.0.5.tar.gz'
$ tar -xzvf nginx-1.0.5.tar.gz $ tar -xzvf nginx-1.0.5.tar.gz
$ cd nginx-1.0.5/ $ cd nginx-1.0.5/
@ -1647,12 +1666,9 @@ filtering chain affects a lot. The correct configure adding order is:
= Known Issues = = Known Issues =
* Because the standard Lua 5.1 interpreter's VM is not fully resumable, the [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]] methods cannot be used within the context of a Lua <code>pcall()</code> or <code>xpcall()</code>. If you're heavy on Lua exception model based on Lua's <code>error()</code> and <code>pcall()</code>/<code>xpcall()</code>, use LuaJIT 2.0 instead because LuaJIT 2.0 supports fully resumable VM. * Because the standard Lua 5.1 interpreter's VM is not fully resumable, the [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]] methods cannot be used within the context of a Lua [http://www.lua.org/manual/5.1/manual.html#pdf-pcall pcall()] or [http://www.lua.org/manual/5.1/manual.html#pdf-xpcall xpcall()]. If you're heavy on Lua exception model based on Lua's [http://www.lua.org/manual/5.1/manual.html#pdf-error error()] and <code>pcall()</code>/<code>xpcall()</code>, use LuaJIT 2.0 instead because LuaJIT 2.0 supports fully resume-able VM.
* The [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]] Lua methods cannot capture * The [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]] Lua methods cannot capture locations configured by [[NginxHttpEchoModule]]'s [[NginxHttpEchoModule#echo_location|echo_location]], [[NginxHttpEchoModule#echo_location_async|echo_location_async]], [[NginxHttpEchoModule#echo_subrequest|echo_subrequest]], or [[NginxHttpEchoModule#echo_subrequest_async|echo_subrequest_async]] directives. This won't be fixed in the future due to technical problems.
locations configured by ngx_echo module's <code>echo_location</code>, <code>echo_location_async</code>, <code>echo_subrequest</code>, or <code>echo_subrequest_async</code> directives. This won't be fixed in the future due to technical problems :)
* The [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]] Lua methods cannot capture locations with internal redirections for now. But this may get fixed in the future.
* '''WATCH OUT: Globals WON'T persist between requests''', because of the one-coroutine-per-request isolation design. Especially watch yourself when using <code>require()</code> to import modules, and use this form: * '''WATCH OUT: Globals WON'T persist between requests''', because of the one-coroutine-per-request isolation design. Especially watch yourself when using <code>require()</code> to import modules, and use this form:
<geshi lang="nginx"> <geshi lang="nginx">