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