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