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
event model 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 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
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
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/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).
(<http://github.com/agentzh/redis2-nginx-module>) and
[[NginxHttpProxyModule]] modules for details).
The Lua interpreter instance is shared across all the requests in a
single nginx worker process.
@ -285,7 +288,7 @@ Directives
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
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
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
syntax: *content_by_lua <lua-script-str>*
@ -414,13 +418,17 @@ Directives
"<lua-script-str>" 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 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.
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 / { deny 192.168.1.1; allow
192.168.1.0/24; allow 10.1.1.0/16; deny all;
Note that this handler always runs *after* the standard
[[NginxHttpAccessModule]]. So the following will work as expected:
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
deny all;
access_by_lua '
local res = ngx.location.capture("/mysql", { ... })
@ -429,17 +437,22 @@ Directives
# 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 L<access_by_lua|/"access_by_lua">.
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
approximately implemented by access_by_lua. For example, location / {
auth_request /auth;
approximately implemented by access_by_lua. For example,
location / {
auth_request /auth;
# 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 / {
access_by_lua '
local res = ngx.location.capture("/auth")
@ -457,14 +470,16 @@ Directives
# 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
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(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
@ -484,8 +499,8 @@ Directives
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.
You can disable the Lua code cache by setting lua_code_cache "off" in
your "nginx.conf" file.
rewrite_by_lua_file
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
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.
You can disable the Lua code cache by setting lua_code_cache "off" in
your "nginx.conf" file.
access_by_lua_file
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
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.
You can disable the Lua code cache by setting lua_code_cache "off" in
your "nginx.conf" file.
lua_need_request_body
syntax: *lua_need_request_body <on | off>*
@ -541,12 +556,8 @@ Directives
content.
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
http://wiki.nginx.org/HttpCoreModule#client_body_buffer_size
for more details.
variable, make sure that your have configured client_body_buffer_size to
have exactly the same value as client_max_body_size.
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
@ -558,11 +569,19 @@ Directives
The same applies to access_by_lua and access_by_lua_file.
Nginx API for Lua
Input arguments
context: *set_by_lua**
ngx.arg
syntax: *val = ngx.arg[index]* context: *set_by_lua**
Index the input arguments to the set_by_lua* directives: value =
ngx.arg[n] Here's an example location /foo { set $a 32; set $b 56;
Index the input arguments to the set_by_lua and set_by_lua_file
directives:
value = ngx.arg[n]
Here's an example
location /foo {
set $a 32;
set $b 56;
set_by_lua $res
'return tonumber(ngx.arg[1]) + tonumber(ngx.arg[2])'
@ -570,6 +589,7 @@ Nginx API for Lua
echo $sum;
}
that outputs 88, the sum of 32 and 56.
ngx.var.VARIABLE
@ -591,15 +611,22 @@ Nginx API for Lua
"ngx.var[3]", and etc.
Core constants
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** ngx.OK
ngx.DONE ngx.AGAIN ngx.ERROR 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".
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** ngx.OK (0)
ngx.ERROR (-1) ngx.AGAIN (-2) ngx.DONE (-4) 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".
HTTP method constants
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** value =
ngx.HTTP_GET value = ngx.HTTP_HEAD value = ngx.HTTP_PUT value =
ngx.HTTP_POST value = ngx.HTTP_DELETE
context: *rewrite_by_lua*, access_by_lua*, content_by_lua**
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
context: *rewrite_by_lua*, access_by_lua*, content_by_lua** value =
@ -614,21 +641,22 @@ Nginx API for Lua
Nginx log level constants
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
log_level = ngx.CRIT log_level = ngx.ERR log_level = ngx.WARN log_level
= ngx.NOTICE log_level = ngx.INFO log_level = ngx.DEBUG
ngx.STDERR ngx.EMERG ngx.ALERT ngx.CRIT ngx.ERR ngx.WARN ngx.NOTICE
ngx.INFO ngx.DEBUG
These constants are usually used by the ngx.log method.
print
syntax: *print(...)*
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 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".
It's equivalent to 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".
ngx.ctx
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**
Issue a synchronous but still non-blocking "nginx subrequest" using
Issue a synchronous but still non-blocking *Nginx Subrequest* using
"uri".
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,
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
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.
Because it's all done in hand-written C, it should be faster than your
own Lua code.
@ -757,10 +785,8 @@ Nginx API for Lua
you're using the standard "ngx_proxy" module to serve 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 "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.
So always set proxy_pass_request_headers "off" in your subrequest
location to ignore the original request headers.
ngx.location.capture_multi
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**
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
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' ngx.header.content_type =
'text/plain';
@ -833,17 +859,17 @@ Nginx API for Lua
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 in the (array) table will take
effect. So ngx.header.content_type = {'a', 'b'} is equivalent to
ngx.header.content_type = 'b' Setting a slot to nil effectively removes
it from the response headers: ngx.header["X-My-Header"] = nil; same does
assigning an empty table: ngx.header["X-My-Header"] = {}; "ngx.header"
is not a normal Lua table so you cannot iterate through it.
like "Content-Type", only the last element in the (array) table will
take effect. So ngx.header.content_type = {'a', 'b'} is equivalent to
ngx.header.content_type = 'b' Setting a slot to "nil" effectively
removes it from the response headers: ngx.header["X-My-Header"] = nil;
same does assigning an empty table: ngx.header["X-My-Header"] = {};
"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.
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.
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:
{"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:
http://wiki.nginx.org/NginxHttpCoreModule#.24http_HEADER
variables.
ngx.req.set_header
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**
Does an internal redirect to uri with args. ngx.exec('/some-location');
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 location /foo {
content_by_lua ' ngx.exec("@bar"); '; }
Does an internal redirect to "uri" with "args".
ngx.exec('/some-location');
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,
location /foo {
content_by_lua '
ngx.exec("@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 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.
This method is very much like the "echo_exec" directive in the ngx_echo
module.
This method is very much like the echo_exec directive in
[[NginxHttpEchoModule]].
ngx.redirect
syntax: *ngx.redirect(uri, status?)*
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.
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
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.
Here's a small example:
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.
This method never returns.
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 rewrite ^ /foo redirect; # nginx config 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
This method is very much like the rewrite directive with the "redirect"
modifier in the standard [[NginxHttpRewriteModule]], for example, this
"nginx.conf" snippet
rewrite ^ /foo redirect; # nginx config
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
syntax: *ngx.send_headers()*
@ -1012,7 +1063,7 @@ Nginx API for Lua
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
ngx.say or ngx.print.
@ -1024,16 +1075,28 @@ Nginx API for 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 local table = { "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.
arrays will be sent one by one. For example
local table = {
"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
syntax: *ngx.say(...)*
@ -1047,32 +1110,36 @@ Nginx API for 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
syntax: *ngx.flush()*
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
syntax: *ngx.exit(status)*
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 status code to nginx.
When "status >= 200" ("ngx.HTTP_OK"), it will interrupt the execution of
the current Lua thread and returns 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", "ngx.HTTP_MOVED_TEMPORARILY", or other HTTP status
numbers.
constants.
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**
Unescape "str" as a escaped URI component.
Unescape "str" as an escaped URI component.
ngx.encode_base64
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**
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.
@ -1134,7 +1201,8 @@ Nginx API for 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).
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.
@ -1144,7 +1212,8 @@ Nginx API for 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).
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.
@ -1182,21 +1251,36 @@ Nginx API for Lua
ngx.is_subrequest
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.
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
implemented by Nginx Devel Kit (NDK)'s set_var submodule's
ndk_set_var_value.
implemented by Nginx Devel Kit
(<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",
"set_quote_sql_str", and etc.
For example, [[NginxHttpSetMiscModule]]'s following directives can be
invoked this way:
For instance, local res = ndk.set_var.set_escape_uri('a/b'); -- now res
== 'a%2fb' This feature requires the ngx_devel_kit module.
* set_quote_sql_str
* 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
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
only once, and all coroutines will share the same copy of the module.
Here's a complete small example: -- mydata.lua module("mydata",
package.seeall)
Here's a complete small example:
-- mydata.lua
module("mydata", package.seeall)
local data = {
dog = 3,
@ -1236,31 +1322,32 @@ Data Sharing within an Nginx Worker
function get_age(name)
return data[name]
end
and then accessing it from your nginx.conf:
location /lua {
content_lua_by_lua '
local mydata = require("mydata")
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>,
and all those subsequent requests 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,
until you send a C<HUP> signal to the nginx master
process to enforce a reload.
Your "mydata" module in this example will only be loaded and run on the
first request to the location "/lua", and all those subsequent requests
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, until you send a
"HUP" signal to the nginx master 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.
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
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
recommended when you have a multi-core CPU or multiple CPUs in a
single machine.
2. Use some true backend storage like "memcached", "redis", or an RDBMS
@ -1460,22 +1547,19 @@ Future Plan
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.
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
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.
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.
* WATCH OUT: Globals WON'T persist between requests, because of the
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
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
`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/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 requests in a single nginx worker process.
@ -302,7 +302,7 @@ for example,
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
---------------
@ -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
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
--------------
@ -453,17 +453,12 @@ access_by_lua
**phase:** *access tail*
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.
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.
This hook uses exactly the same mechamism as `content_by_lua`
so all the nginx APIs defined there
are also available here.
This hook uses exactly the same mechanism as `content_by_lua` 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 / {
deny 192.168.1.1;
@ -479,12 +474,11 @@ So the following will work as expected:
# 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
approximately implemented by `access_by_lua`. For example,
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 approximately implemented by `access_by_lua`. For example,
location / {
auth_request /auth;
@ -492,8 +486,10 @@ approximately implemented by `access_by_lua`. For example,
# proxy_pass/fastcgi_pass/postgres_pass/...
}
can be implemented in terms of `ngx_lua` like this
location / {
access_by_lua '
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/...
}
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
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.
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 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
-------------------
@ -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
not recommend for beginners.
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.
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.
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
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.
Lua code cache by setting `lua_code_cache` `off` in your `nginx.conf` 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
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.
Lua code cache by setting `lua_code_cache` `off` in your `nginx.conf` file.
lua_need_request_body
---------------------
@ -592,15 +584,10 @@ lua_need_request_body
**phase:** *depends on usage*
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.
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.
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
<http://wiki.nginx.org/HttpCoreModule#client_body_buffer_size>
for more details.
your have configured `client_body_buffer_size` to have exactly the same value as `client_max_body_size`.
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
@ -614,16 +601,20 @@ The same applies to `access_by_lua` and `access_by_lua_file`.
Nginx API for Lua
=================
Input arguments
---------------
ngx.arg
-------
**syntax:** *val = ngx.arg[index]*
**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]
Here's an example
location /foo {
set $a 32;
set $b 56;
@ -635,7 +626,8 @@ Here's an example
echo $sum;
}
that outputs 88, the sum of 32 and 56.
that outputs `88`, the sum of `32` and `56`.
ngx.var.VARIABLE
----------------
@ -669,10 +661,10 @@ Core constants
--------------
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
ngx.OK
ngx.DONE
ngx.AGAIN
ngx.ERROR
ngx.OK (0)
ngx.ERROR (-1)
ngx.AGAIN (-2)
ngx.DONE (-4)
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`.
@ -681,11 +673,15 @@ HTTP method constants
---------------------
**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua**
value = 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
---------------------
@ -711,15 +707,18 @@ Nginx log level constants
-------------------------
**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
log_level = ngx.CRIT
log_level = ngx.ERR
log_level = ngx.WARN
log_level = ngx.NOTICE
log_level = ngx.INFO
log_level = ngx.DEBUG
ngx.STDERR
ngx.EMERG
ngx.ALERT
ngx.CRIT
ngx.ERR
ngx.WARN
ngx.NOTICE
ngx.INFO
ngx.DEBUG
These constants are usually used by the `ngx.log` method.
print
-----
@ -727,13 +726,13 @@ print
**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
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
-------
@ -819,26 +818,19 @@ Overriding `ngx.ctx` with a new Lua table is also supported, for example,
ngx.ctx = { foo = 32, bar = 54 }
ngx.location.capture
--------------------
**syntax:** *res = ngx.location.capture(uri, options?)*
**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
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`,
`ngx_postgres`,
`ngx_drizzle`, and even `ngx_lua` itself and etc etc etc.
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`,
`ngx_postgres`, `ngx_drizzle`, and even `ngx_lua` itself and etc etc etc.
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.
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.
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')
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,
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
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
`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.
`proxy_pass_request_headers` `off` in your subrequest location to ignore the original request headers.
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} })
end
ngx.status
----------
**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
status = ngx.status
ngx.header.HEADER
-----------------
**syntax:** *ngx.header.HEADER = VALUE*
**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'
ngx.header.content_type = 'text/plain';
@ -1009,7 +1001,7 @@ will yield
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
ngx.header.content_type = {'a', 'b'}
@ -1018,7 +1010,7 @@ is equivalent to
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;
@ -1029,9 +1021,9 @@ same does assigning an empty table:
`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 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.
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"}
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>
Another way to read individual request headers is to use `ngx.var.http_HEADER`, that is, nginx's standard `$http_HEADER` variables.
ngx.req.set_header
------------------
@ -1214,6 +1204,7 @@ is equivalent to
ngx.req.clear_header("X-Foo")
ngx.req.clear_header
--------------------
**syntax:** *ngx.req.clear_header(header_name)*
@ -1228,13 +1219,16 @@ ngx.exec
**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', '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 {
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
it's just an internal redirect and no new HTTP traffic is involved.
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`.
This method is very much like the `echo_exec`
directive in the ngx_echo module.
This method is very much like the `echo_exec` directive in `NginxHttpEchoModule`.
ngx.redirect
------------
@ -1263,43 +1257,54 @@ ngx.redirect
**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
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:
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`.
This method *must* be called before `ngx.send_headers` or explicit response body outputs by either `ngx.print` or `ngx.say`.
This method never returns.
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
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
----------------
**syntax:** *ngx.send_headers()*
@ -1308,8 +1313,7 @@ ngx.send_headers
Explicitly send out the response headers.
Usually you don't have to send headers yourself. ngx_lua
will automatically send out headers right before you
Usually you don't have to send headers yourself. `ngx_lua` will automatically send out headers right before you
output contents via `ngx.say` or `ngx.print`.
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**
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
local table = {
"hello, ",
{"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)
will yield the output
hello, world: true or false: nil
Non-array table arguments will cause a Lua exception to be thrown.
ngx.say
@ -1353,9 +1361,11 @@ ngx.log
**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
---------
@ -1363,7 +1373,7 @@ ngx.flush
**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
--------
@ -1371,14 +1381,13 @@ ngx.exit
**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.
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`,
`ngx.HTTP_MOVED_TEMPORARILY`,
or other HTTP status numbers.
`ngx.HTTP_MOVED_TEMPORARILY`, or other `HTTP status constants`.
ngx.eof
-------
@ -1402,7 +1411,7 @@ ngx.unescape_uri
**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
-----------------
@ -1427,7 +1436,6 @@ ngx.today
**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).
.
This is the local time.
@ -1445,7 +1453,7 @@ ngx.localtime
**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.
@ -1455,7 +1463,7 @@ ngx.utctime
**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.
@ -1498,23 +1506,30 @@ ngx.is_subrequest
-----------------
**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
---------------------
**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
implemented by Nginx Devel Kit (NDK)'s set_var submodule's ndk_set_var_value.
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`.
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,
local res = ndk.set_var.set_escape_uri('a/b');
-- 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
================
@ -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:
-- mydata.lua
module("mydata", package.seeall)
@ -1553,8 +1569,10 @@ Here's a complete small example:
return data[name]
end
and then accessing it from your nginx.conf:
location /lua {
content_lua_by_lua '
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
and run on the first request to the location `/lua`,
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.
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`.
Performance
@ -1716,12 +1735,9 @@ Future Plan
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
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.
* 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.
* **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
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
[[#ngx.location.capture_multi|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
[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 requests in a single nginx worker process.
@ -292,7 +292,7 @@ for example,
echo "sum = $sum, diff = $diff";
}
</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 ==
@ -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
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 ==
@ -439,17 +439,12 @@ calling [[#ngx.exit|ngx.exit]] with status >= 200 (<code>ngx.HTTP_OK</code>) and
'''phase:''' ''access tail''
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.
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.
This hook uses exactly the same mechamism as [[#content_by_lua|content_by_lua]]
so all the nginx APIs defined there
are also available here.
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.
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">
location / {
deny 192.168.1.1;
@ -465,12 +460,11 @@ So the following will work as expected:
# proxy_pass/fastcgi_pass/...
}
</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
approximately implemented by [[#access_by_lua|access_by_lua]]. For example,
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 approximately implemented by [[#access_by_lua|access_by_lua]]. For example,
<geshi lang="nginx">
location / {
auth_request /auth;
@ -478,7 +472,9 @@ approximately implemented by [[#access_by_lua|access_by_lua]]. For example,
# proxy_pass/fastcgi_pass/postgres_pass/...
}
</geshi>
can be implemented in terms of <code>ngx_lua</code> like this
<geshi lang="nginx">
location / {
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/...
}
</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
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.
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 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 ==
@ -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
not recommend for beginners.
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 <code>lua_code_cache off;</code> in your nginx.conf.
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.
== 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
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.
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 ==
@ -562,7 +554,7 @@ not recommend for beginners.
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 <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 ==
@ -574,15 +566,10 @@ Lua code cache by setting <code>lua_code_cache off;</code> in your nginx.conf.
'''phase:''' ''depends on usage''
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.
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.
If you want to read the request body data from the <code>$request_body</code> 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
http://wiki.nginx.org/HttpCoreModule#client_body_buffer_size
for more details.
If you want to read the request body data from the [[NginxHttpCoreModule#$request_body|$request_body]] variable, make sure that
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]].
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
@ -595,14 +582,18 @@ The same applies to [[#access_by_lua|access_by_lua]] and [[#access_by_lua_file|a
= Nginx API for Lua =
== Input arguments ==
== ngx.arg ==
'''syntax:''' ''val = ngx.arg[index]''
'''context:''' ''set_by_lua*''
Index the input arguments to the set_by_lua* directives:
<geshi lang="nginx">
Index the input arguments to the [[#set_by_lua|set_by_lua]] and [[#set_by_lua_file|set_by_lua_file]] directives:
<geshi lang="lua">
value = ngx.arg[n]
</geshi>
Here's an example
<geshi lang="nginx">
location /foo {
set $a 32;
@ -615,7 +606,8 @@ Here's an example
echo $sum;
}
</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 ==
'''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 ==
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
<geshi lang="nginx">
ngx.OK
ngx.DONE
ngx.AGAIN
ngx.ERROR
<geshi lang="lua">
ngx.OK (0)
ngx.ERROR (-1)
ngx.AGAIN (-2)
ngx.DONE (-4)
</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
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 ==
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
<geshi lang="nginx">
value = ngx.HTTP_GET
value = ngx.HTTP_HEAD
value = ngx.HTTP_PUT
value = ngx.HTTP_POST
value = ngx.HTTP_DELETE
<geshi lang="lua">
ngx.HTTP_GET
ngx.HTTP_HEAD
ngx.HTTP_PUT
ngx.HTTP_POST
ngx.HTTP_DELETE
</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 ==
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*''
<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>
== Nginx log level constants ==
'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*''
<geshi lang="nginx">
log_level = ngx.STDERR
log_level = ngx.EMERG
log_level = ngx.ALERT
log_level = ngx.CRIT
log_level = ngx.ERR
log_level = ngx.WARN
log_level = ngx.NOTICE
log_level = ngx.INFO
log_level = ngx.DEBUG
<geshi lang="lua">
ngx.STDERR
ngx.EMERG
ngx.ALERT
ngx.CRIT
ngx.ERR
ngx.WARN
ngx.NOTICE
ngx.INFO
ngx.DEBUG
</geshi>
These constants are usually used by the [[#ngx.log|ngx.log]] method.
== print ==
'''syntax:''' ''print(...)''
'''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
<geshi lang="nginx">
<geshi lang="lua">
ngx.log(ngx.NOTICE, 'lua print: ', a, b, ...)
</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 ==
'''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>
Then <code>GET /test</code> will yield the output
<geshi lang="nginx">
<geshi lang="bash">
foo = nil
79
</geshi>
@ -757,7 +756,7 @@ Also, every request has its own copy, include subrequests, for example:
}
</geshi>
Then <code>GET /main</code> will give the output
<geshi lang="nginx">
<geshi lang="bash">
main pre: 73
sub pre: nil
sub post: 32
@ -781,7 +780,7 @@ Internal redirection will destroy the original request's <code>ngx.ctx</code> da
}
</geshi>
Then <code>GET /orig</code> will give you
<geshi lang="nginx">
<geshi lang="bash">
nil
</geshi>
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.
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 }
</geshi>
== ngx.location.capture ==
'''syntax:''' ''res = ngx.location.capture(uri, options?)''
'''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
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>,
<code>ngx_postgres</code>,
<code>ngx_drizzle</code>, and even <code>ngx_lua</code> itself and etc etc etc.
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>,
<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
interface but there's ''no''
extra HTTP/TCP traffic ''nor'' IPC involved. Everything
works internally, efficiently, on the C level.
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.
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:
<geshi lang="nginx">
<geshi lang="lua">
res = ngx.location.capture(uri)
</geshi>
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
they appear. For instance, if the subrequest response headers contains the following
lines:
<geshi lang="nginx">
<geshi lang="bash">
Set-Cookie: a=3
Set-Cookie: foo=bar
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>.
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')
</geshi>
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>.
Issuing a POST subrequest, for example,
can be done as follows
<geshi lang="nginx">
<geshi lang="lua">
res = ngx.location.capture(
'/foo/bar',
{ 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>.
The <code>args</code> option can specify extra url arguments, for instance,
<geshi lang="nginx">
<geshi lang="lua">
ngx.location.capture('/foo?a=1',
{ args = { b = 3, c = ':' } }
)
</geshi>
is equivalent to
<geshi lang="nginx">
<geshi lang="lua">
ngx.location.capture('/foo?a=1&b=3&c=%3a')
</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,
it should be faster than your own Lua code.
The <code>args</code> option can also take plain query string:
<geshi lang="nginx">
<geshi lang="lua">
ngx.location.capture('/foo?a=1',
{ 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
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
<code>proxy_pass_request_headers 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.
[[NginxHttpProxyModule#proxy_pass_request_headers|proxy_pass_request_headers]] <code>off</code> in your subrequest location to ignore the original request headers.
== ngx.location.capture_multi ==
'''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.
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{
{ "/foo", { args = "a=3&b=4" } },
{ "/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,
you can use Lua tables for both requests and responses. For instance,
<geshi lang="nginx">
<geshi lang="lua">
-- construct the requests table
local reqs = {}
table.insert(reqs, { "/mysql" })
@ -940,67 +930,69 @@ you can use Lua tables for both requests and responses. For instance,
</geshi>
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
<geshi lang="nginx">
<geshi lang="lua">
ngx.location.capture =
function (uri, args)
return ngx.location.capture_multi({ {uri, args} })
end
</geshi>
== ngx.status ==
'''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
before sending out the response headers.
<geshi lang="nginx">
<geshi lang="lua">
ngx.status = ngx.HTTP_CREATED
status = ngx.status
</geshi>
== ngx.header.HEADER ==
'''syntax:''' ''ngx.header.HEADER = VALUE''
'''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.
<geshi lang="nginx">
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="lua">
-- equivalent to ngx.header["Content-Type"] = 'text/plain'
ngx.header.content_type = 'text/plain';
ngx.header["X-My-Header"] = 'blah blah';
</geshi>
Multi-value headers can be set this way:
<geshi lang="nginx">
<geshi lang="lua">
ngx.header['Set-Cookie'] = {'a=32; path=/', 'b=4; path=/'}
</geshi>
will yield
<geshi lang="nginx">
<geshi lang="bash">
Set-Cookie: a=32; path=/
Set-Cookie: b=4; path=/
</geshi>
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
<geshi lang="nginx">
<geshi lang="lua">
ngx.header.content_type = {'a', 'b'}
</geshi>
is equivalent to
<geshi lang="nginx">
<geshi lang="lua">
ngx.header.content_type = 'b'
</geshi>
Setting a slot to nil effectively removes it from the response headers:
<geshi lang="nginx">
Setting a slot to <code>nil</code> effectively removes it from the response headers:
<geshi lang="lua">
ngx.header["X-My-Header"] = nil;
</geshi>
same does assigning an empty table:
<geshi lang="nginx">
<geshi lang="lua">
ngx.header["X-My-Header"] = {};
</geshi>
<code>ngx.header</code> is not a normal Lua table so you cannot
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.
== ngx.req.get_uri_args ==
@ -1026,35 +1018,35 @@ Here's an example,
}
</geshi>
Then <code>GET /test?foo=bar&bar=baz&bar=blah</code> will yield the response body
<geshi lang="nginx">
<geshi lang="bash">
foo: bar
bar: baz, blah
</geshi>
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
<geshi lang="nginx">
<geshi lang="bash">
a b: 1a 2
</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
<geshi lang="nginx">
<geshi lang="bash">
foo: true
bar: true
</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
<geshi lang="nginx">
<geshi lang="bash">
foo:
bar:
</geshi>
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:
<geshi lang="nginx">
<geshi lang="lua">
ngx.var.args = "a=3&b=42"
local args = ngx.req.get_uri_args()
</geshi>
Here the <code>args</code> table will always look like
<geshi lang="nginx">
<geshi lang="lua">
{a = 3, b = 42}
</geshi>
regardless of the actual request query string.
@ -1083,33 +1075,33 @@ Here's an example,
}
</geshi>
Then
<geshi lang="nginx">
<geshi lang="bash">
# Post request with the body 'foo=bar&bar=baz&bar=blah'
$ curl --data 'foo=bar&bar=baz&bar=blah' localhost/test
</geshi>
will yield the response body like
<geshi lang="nginx">
<geshi lang="bash">
foo: bar
bar: baz, blah
</geshi>
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,
<geshi lang="nginx">
<geshi lang="bash">
# POST request with body 'a%20b=1%61+2'
$ curl -d 'a%20b=1%61+2' localhost/test
</geshi>
will yield the output
<geshi lang="nginx">
<geshi lang="bash">
a b: 1a 2
</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
<geshi lang="nginx">
<geshi lang="bash">
foo: true
bar: true
</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
<geshi lang="nginx">
<geshi lang="bash">
foo:
bar:
</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.
Here's an example,
<geshi lang="nginx">
<geshi lang="lua">
local h = ngx.req.get_headers()
for k, v in pairs(h) do
...
end
</geshi>
To read an individual header:
<geshi lang="nginx">
<geshi lang="lua">
ngx.say("Host: ", ngx.req.get_headers()["Host"])
</geshi>
For multiple instances of request headers like
<geshi lang="nginx">
<geshi lang="bash">
Foo: foo
Foo: bar
Foo: baz
</geshi>
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"}
</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:
http://wiki.nginx.org/NginxHttpCoreModule#.24http_HEADER
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.
== ngx.req.set_header ==
'''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.
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")
</geshi>
The <code>header_value</code> can take an array list of values,
for example,
<geshi lang="nginx">
<geshi lang="lua">
ngx.req.set_header("Foo", {"a", "abc"})
</geshi>
will produce two new request headers:
<geshi lang="nginx">
<geshi lang="bash">
Foo: a
Foo: abc
</geshi>
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
<geshi lang="nginx">
<geshi lang="lua">
ngx.req.set_header("X-Foo", nil)
</geshi>
is equivalent to
<geshi lang="nginx">
<geshi lang="lua">
ngx.req.clear_header("X-Foo")
</geshi>
== ngx.req.clear_header ==
'''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*''
Does an internal redirect to uri with args.
<geshi lang="nginx">
Does an internal redirect to <code>uri</code> with <code>args</code>.
<geshi lang="lua">
ngx.exec('/some-location');
ngx.exec('/some-location', 'a=3&b=5&c=6');
ngx.exec('/some-location?a=3&b=5', 'c=6');
</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">
location /foo {
content_by_lua '
@ -1209,59 +1203,70 @@ Named locations are also supported, but query strings are ignored. For example
...
}
</geshi>
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.
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]].
This method is very much like the <code>echo_exec</code>
directive in the ngx_echo module.
This method is very much like the [[NginxHttpEchoModule#echo_exec|echo_exec]] directive in [[NginxHttpEchoModule]].
== ngx.redirect ==
'''syntax:''' ''ngx.redirect(uri, status?)''
'''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
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:
<geshi lang="nginx">
<geshi lang="lua">
return ngx.redirect("/foo")
</geshi>
which is equivalent to
<geshi lang="nginx">
<geshi lang="lua">
return ngx.redirect("http://localhost:1984/foo", ngx.HTTP_MOVED_TEMPORARILY)
</geshi>
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
outputs by either [[#ngx.print|ngx.print]] or [[#ngx.say|ngx.say]].
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]].
This method never returns.
This method is very much like the <code>rewrite</code> directive with the <code>redirect</code> modifier in the standard
<code>ngx_rewrite</code> module, for example, this <code>nginx.conf</code> snippet
This method is very much like the [[NginxHttpRewriteModule#rewrite|rewrite]] directive with the <code>redirect</code> modifier in the standard
[[NginxHttpRewriteModule]], for example, this <code>nginx.conf</code> snippet
<geshi lang="nginx">
rewrite ^ /foo redirect; # nginx config
</geshi>
is equivalent to the following Lua code
<geshi lang="nginx">
<geshi lang="lua">
return ngx.redirect('/foo'); -- lua code
</geshi>
while
<geshi lang="nginx">
rewrite ^ /foo permanent; # nginx config
</geshi>
is equivalent to
<geshi lang="nginx">
<geshi lang="lua">
return ngx.redirect('/foo', ngx.HTTP_MOVED_PERMANENTLY) -- Lua code
</geshi>
== ngx.send_headers ==
'''syntax:''' ''ngx.send_headers()''
@ -1269,8 +1274,7 @@ is equivalent to
Explicitly send out the response headers.
Usually you don't have to send headers yourself. ngx_lua
will automatically send out headers right before you
Usually you don't have to send headers yourself. <code>ngx_lua</code> will automatically send out headers right before you
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.
@ -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*''
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
<geshi lang="nginx">
<geshi lang="lua">
local table = {
"hello, ",
{"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)
</geshi>
will yield the output
<geshi lang="nginx">
<geshi lang="bash">
hello, world: true or false: nil
</geshi>
Non-array table arguments will cause a Lua exception to be thrown.
== 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*''
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 ==
'''syntax:''' ''ngx.flush()''
'''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 ==
'''syntax:''' ''ngx.exit(status)''
'''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.
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>,
<code>ngx.HTTP_MOVED_TEMPORARILY</code>,
or other HTTP status numbers.
<code>ngx.HTTP_MOVED_TEMPORARILY</code>, or other [[#HTTP status constants|HTTP status constants]].
== 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*''
Unescape <code>str</code> as a escaped URI component.
Unescape <code>str</code> as an escaped URI component.
== ngx.encode_base64 ==
'''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*''
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.
@ -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*''
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.
@ -1402,7 +1410,7 @@ This is the local time.
'''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.
@ -1441,22 +1449,29 @@ Parse the http time string (as returned by [[#ngx.http_time|ngx.http_time]]) int
== ngx.is_subrequest ==
'''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 ==
'''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
implemented by Nginx Devel Kit (NDK)'s set_var submodule's ndk_set_var_value.
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>.
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,
<geshi lang="nginx">
<geshi lang="lua">
local res = ndk.set_var.set_escape_uri('a/b');
-- now res == 'a%2fb'
</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 =
@ -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.
Here's a complete small example:
<geshi lang="nginx">
<geshi lang="lua">
-- mydata.lua
module("mydata", package.seeall)
@ -1493,7 +1509,9 @@ Here's a complete small example:
return data[name]
end
</geshi>
and then accessing it from your nginx.conf:
<geshi lang="nginx">
location /lua {
content_lua_by_lua '
@ -1502,6 +1520,7 @@ and then accessing it from your nginx.conf:
';
}
</geshi>
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 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.
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>.
= 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 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:
<geshi lang="nginx">
<geshi lang="bash">
$ wget 'http://sysoev.ru/nginx/nginx-1.0.5.tar.gz'
$ tar -xzvf nginx-1.0.5.tar.gz
$ cd nginx-1.0.5/
@ -1647,12 +1666,9 @@ filtering chain affects a lot. The correct configure adding order is:
= 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
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.
* 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.
* '''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">